首页
社区
课程
招聘
[原创]第一章:1.3、if-else分支的识别技巧
发表于: 2010-5-29 07:43 22027

[原创]第一章:1.3、if-else分支的识别技巧

2010-5-29 07:43
22027
收藏
免费 7
支持
分享
最新回复 (47)
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
26
鄙人声明:非抬杠也,交流尔。
2010-5-30 11:52
0
雪    币: 883
活跃值: (314)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
27
[QUOTE=竹君;815857]00401000  CMP DWORD PTR SS:[ESP+4], 0              ; 我们可以发现Release版是直接使用ESP寻址
00401005  JLE SHORT Test_0.00401018
00401007  PUSH Test_0.004020F4    ...[/QUOTE]

00401000  CMP DWORD PTR SS:[ESP+4], 0              ; 我们可以发现Release版是直接使用ESP寻址
00401005  JLE SHORT Test_0.00401018
00401007  PUSH Test_0.004020F4                     ; /format = "Hello world!
0040100C  CALL DWORD PTR DS:[<&MSVCR90.printf>]    ; \printf
00401012  ADD ESP, 4
00401015  XOR EAX, EAX
00401017  RETN
00401018  PUSH Test_0.00402104                     ; /format = "Hello everybody!
0040101D  CALL DWORD PTR DS:[<&MSVCR90.printf>]    ; \printf
00401023  ADD ESP, 4
00401026  XOR EAX, EAX
00401028  RETN

     对于这种从函数外部接受参数的情况,你、我与斯特劳斯特鲁普都不可能知道下面的if-else分支究竟会走哪一条,也就是说以上代码中没有绝对的不可达分支,因为其判定条件采用的是一个变量,这种情况编译器肯定不会做什么大的动作。但是如果其判定条件采用常量的的话,那么对于if-else语句来说肯定就有一个分支是不可达的了,编译器在检测到后就会将其剪掉。

    希望我的解释足够详细,为此我给出一个例子的伪代码:

int a = 接受用户输入的信息;
if(如果a大于0)
{
    显示"输入大于0";
}
else
{
    显示"输入小于等于0";
}

     现这种情况是没有不可达分支,因为我们不知道用户会输入什么,这是程序运行之后的才能知道的事,所以这个if-else的每个分支对于我们来说都是有用的,下面我们再看看另一个例子:

int a = 99;
if(如果a大于0)
{
    显示"输入大于0";
}
else
{
    显示"输入小于等于0";
}

    很明显这种情况下else后面的语句是永远不会被执行的,所以产生了不可达分支,因此编译器会将这个多余的分支剪掉。

    竹君兄可能是没仔细看小弟的文章,因此才有这些疑问,相信您仔细看完后就不会有这些疑问了。

    最后,非常感谢竹君的反馈与交流,笔者期望竹君能继续关注此系列教程,并大胆的反馈问题。
2010-5-30 13:58
0
雪    币: 291
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
28
写得太好了。。。通俗易懂...继续学习~!
2010-5-31 13:42
0
雪    币: 244
活跃值: (39)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
29
看后,看到作者的调查,回复一下。

这一章还没看出不清楚的地方,建议楼主继续。
2010-5-31 14:50
0
雪    币: 883
活跃值: (314)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
30
本想等到6月4日继续的。

如果没什么问题,下一节与6月1日放出,敬请期待。
2010-5-31 15:12
0
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
31
嗯,六一快乐,感谢楼主还记得
2010-5-31 19:54
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
32
支持楼主,也感谢楼主分享。
个人感觉这节还可以,我看的时候倒是感觉没有什么不理解的,可以不用重写了。
ps:感叹楼主那句话,写编译器的人才是真的NB,后来用了这个三目运算符号,更感觉NB,贴一下代码
int _tmain(int argc, _TCHAR* argv[])
{
        return argc==1 ? 6:18;
}

release下的汇编如下
00401000    8B4424 04       mov     eax, dword ptr [esp+4]
00401004    48              dec     eax
00401005    F7D8            neg     eax
00401007    1BC0            sbb     eax, eax
00401009    83E0 0C         and     eax, 0C
0040100C    83C0 06         add     eax, 6
0040100F    C3              retn
应该不用解释了吧。
2010-6-1 17:12
0
雪    币: 883
活跃值: (314)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
33
[QUOTE=zzycqok;817089]支持楼主,也感谢楼主分享。
个人感觉这节还可以,我看的时候倒是感觉没有什么不理解的,可以不用重写了。
ps:感叹楼主那句话,写编译器的人才是真的NB,后来用了这个三目运算符号,更感觉NB,贴一下代码
int _tmain(int argc, _TCHAR* argv[])
{
        retur...[/QUOTE]

恩,不错,其实三目运算是有很多模式的,其中有些模式也是有规律可循的,有时间的话我会补上更多的。
2010-6-3 11:09
0
雪    币: 161
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
34
[QUOTE=zzycqok;817089]支持楼主,也感谢楼主分享。
个人感觉这节还可以,我看的时候倒是感觉没有什么不理解的,可以不用重写了。
ps:感叹楼主那句话,写编译器的人才是真的NB,后来用了这个三目运算符号,更感觉NB,贴一下代码
int _tmain(int argc, _TCHAR* argv[])
{
        retur...[/QUOTE]

这个就是编译器具有的特殊优化技术无分支逻辑的神奇之处。
送一段有意思的代码,实现和三目类似。

call   SomeFunc
sub  eax,4
neg  eax
sbb  eax,eax
and  al,-4
add  eax,10
ret

实现:
if(SomeFunc()==4)
      return 10;
else
      return 6;
2010-6-3 11:32
0
雪    币: 780
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
35
原来里面有这么多玄机
2010-6-3 11:38
0
雪    币: 883
活跃值: (314)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
36
补充了三目运算符的相关知识……
2010-6-4 04:26
0
雪    币: 20
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
37
不错!三目运算总结的很有心得,领教了!

顶楼主!
~~~~~~~~~~~~~
时间太晚了,剩下的几篇有时间看
2010-6-8 01:40
0
雪    币: 257
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
38
一直塙不懂这些关系
看了以后有比较清晰的概念了
感谢
2010-6-8 10:35
0
雪    币: 237
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
39
此贴必火 顶起
2010-7-7 17:31
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
40
这节感觉量很大  要慢慢看。。
2010-8-9 14:55
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
41
太经典了,向您学习
2010-8-9 17:40
0
雪    币: 237
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
42
真滴不错,学习学习
2010-8-30 14:56
0
雪    币: 57
活跃值: (55)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
43
楼主分析的很详细
看了之后,收获不少……
2010-9-18 01:09
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
44
谢谢,很精彩·~
2011-2-27 21:17
0
雪    币: 102
活跃值: (1935)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
45
今天看完这一章了,谢谢楼主。
2011-3-3 09:41
0
雪    币: 955
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
46
"真正的牛人与前辈其实是在幕后默默的写编译器的那帮家伙……"
2011-3-10 03:17
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
47
18年的我
2018-9-17 19:49
0
雪    币: 1852
活跃值: (848)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
48
还有19年的我啊
2019-3-4 20:36
0
游客
登录 | 注册 方可回帖
返回
//