用汇编的眼光看C++(之判断流程)(二)

2014-11-24 12:47:57 · 作者: · 浏览: 1
"&&!\n");

004017C2 push offset string "&&!\n" (0046f020)

004017C7 call printf (004214e0)

004017CC add esp,4

27: }

28:

29: if(m == 10 || n == 0)

004017CF cmp dword ptr [ebp-4],0Ah

004017D3 je process+4Bh (004017db)

004017D5 cmp dword ptr [ebp-8],0

004017D9 jne process+58h (004017e8)

30: {

31: printf("||");

004017DB push offset string "||" (0046f01c)

004017E0 call printf (004214e0)

004017E5 add esp,4

32: }

&&在C语言中是与的意思,而||是或的意思。与就是说,两者均为真;而或的意思是两方中一方为真即可。这在对应的汇编的语句上面也体现得淋漓尽致。首先我们看与的情形。从地址0x4017B6处地指令,我们发现首先比较的是m数据,然后比较的是n数据,这可以从他们在堆栈中的偏移值可以看出来。如果m和10比较,那么下面才有n和0比较的机会,一旦比较失败,就会跳转到地址0x4017cf处执行,跳出当前的判断模块。n和0比较也一样,只有两者都比较成功,才有机会进入地址0x4017C2处执行,打印&&。和与对应的是或,我们发现地址0x4017cf处开始比较的也是数据m,其次才是数据n。和与不同,m数据和n数据只要由一方成功,就会跳转到地址0x4017db处执行。只有两者都为假,才会跳出当前的模块。所以说,两个jne构成了与的基础,一个je和一个jne构成了或的基石。大家可以自己试试看如果&&的选项和||的选项不断进行叠加的时候会出现怎样的情形?试试看。

总结:

if-else这种二分判断结构其实在现在的编程中特别重要,也特别基础。有一个关于二分法最显著的代码就是在顺序数据中进行二分查找。如果有兴趣的话,自己可以动笔试试?在这里,我有几个建议:

(1)确保函数输入的索引范围有序 (start < end)

(2)在计算中间点的时候注意不要范围溢出 (middle = start + (end - start) >> 1)

(3)考虑把你的函数修改成通用的二分法查找函数(可以考虑用const void*和函数指针)