能力值:
( LV12,RANK:210 )
|
-
-
26 楼
鄙人声明:非抬杠也,交流尔。
|
能力值:
( 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后面的语句是永远不会被执行的,所以产生了不可达分支,因此编译器会将这个多余的分支剪掉。
竹君兄可能是没仔细看小弟的文章,因此才有这些疑问,相信您仔细看完后就不会有这些疑问了。
最后,非常感谢竹君的反馈与交流,笔者期望竹君能继续关注此系列教程,并大胆的反馈问题。
|
能力值:
( LV2,RANK:10 )
|
-
-
28 楼
写得太好了。。。通俗易懂...继续学习~!
|
能力值:
( LV4,RANK:50 )
|
-
-
29 楼
看后,看到作者的调查,回复一下。
这一章还没看出不清楚的地方,建议楼主继续。
|
能力值:
( LV9,RANK:280 )
|
-
-
30 楼
本想等到6月4日继续的。
如果没什么问题,下一节与6月1日放出,敬请期待。
|
能力值:
( LV2,RANK:10 )
|
-
-
31 楼
嗯,六一快乐,感谢楼主还记得
|
能力值:
( 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
应该不用解释了吧。
|
能力值:
( LV9,RANK:280 )
|
-
-
33 楼
[QUOTE=zzycqok;817089]支持楼主,也感谢楼主分享。
个人感觉这节还可以,我看的时候倒是感觉没有什么不理解的,可以不用重写了。
ps:感叹楼主那句话,写编译器的人才是真的NB,后来用了这个三目运算符号,更感觉NB,贴一下代码
int _tmain(int argc, _TCHAR* argv[])
{
retur...[/QUOTE]
恩,不错,其实三目运算是有很多模式的,其中有些模式也是有规律可循的,有时间的话我会补上更多的。
|
能力值:
( 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;
|
能力值:
( LV2,RANK:10 )
|
-
-
35 楼
原来里面有这么多玄机
|
能力值:
( LV9,RANK:280 )
|
-
-
36 楼
补充了三目运算符的相关知识……
|
能力值:
( LV2,RANK:10 )
|
-
-
37 楼
不错!三目运算总结的很有心得,领教了!
顶楼主!
~~~~~~~~~~~~~
时间太晚了,剩下的几篇有时间看
|
能力值:
( LV2,RANK:10 )
|
-
-
38 楼
一直塙不懂这些关系
看了以后有比较清晰的概念了
感谢
|
能力值:
( LV2,RANK:10 )
|
-
-
39 楼
此贴必火 顶起
|
能力值:
( LV2,RANK:10 )
|
-
-
40 楼
这节感觉量很大 要慢慢看。。
|
能力值:
( LV2,RANK:10 )
|
-
-
41 楼
太经典了,向您学习
|
能力值:
( LV2,RANK:10 )
|
-
-
42 楼
真滴不错,学习学习
|
能力值:
( LV3,RANK:20 )
|
-
-
43 楼
楼主分析的很详细
看了之后,收获不少……
|
能力值:
( LV2,RANK:10 )
|
-
-
44 楼
谢谢,很精彩·~
|
能力值:
( LV4,RANK:50 )
|
-
-
45 楼
今天看完这一章了,谢谢楼主。
|
能力值:
( LV2,RANK:10 )
|
-
-
46 楼
"真正的牛人与前辈其实是在幕后默默的写编译器的那帮家伙……"
|
能力值:
( LV2,RANK:10 )
|
-
-
47 楼
18年的我
|
能力值:
( LV3,RANK:30 )
|
-
-
48 楼
还有19年的我啊
|
|
|