常见运算的x86反汇编分析(1)

来源:互联网 发布:老鼠仓 知乎 编辑:程序博客网 时间:2024/06/14 03:38

下面是C语言中常见的三目运算:b = (a>0)?c:d;

在vs2008的debug模式下观察下述语句的反汇编:
            b = (a>2)?100:200;

1. 00413095 33 C0                 xor         eax,eax
2. 00413097 83 7D F8 02      cmp         dword ptr [a],2
3. 0041309B 0F 9E C0           setle       al  
4. 0041309E 83 E8 01            sub         eax,1
5. 004130A1 83 E0 9C            and         eax,0FFFFFF9Ch
6. 004130A4 05 C8 00 00 00   add         eax,0C8h
7. 004130A9 89 45 EC              mov         dword ptr [b],eax  //典型的变量赋值;

上述的语句3简单猜下就可以猜出来:应该是根据cmp的结果,设置al中的数值;具体是a>2的时候设置,还是a<2的时候设置,我们完全可以通过调试来得知。
先猜测下:顾名思义setle,就是set when less的意思,如此,a=1的话应该会设置al;

 通过调试,我们发现当a = 1时,al被设置为1,证实了我们的猜测;
 
再看下面的语句,当al=1时,发生什么情况:
sub eax, 1 //对应的eax变为0;

add eax, 0FFFFFFF9Ch //eax还是0;

add eax, 0c8h //eax变为200;

 

那么我们再来看另外一种情况,当a中的值为3的时候,此时al=0,sub eax, 1后,eax=0xFFFFFFFFh,执行后面的and指令后,eax变为0xFFFFFF9Ch,就是值-100;

然后再进行加上0c8h(就是值200),最后刚好得到值100。

 
另外,这里要注意的一个问题,上述的代码是在vs2008的debug模式下获得的,如果考虑release模式下的代码,我们发现并没有上述的复杂过程,而是直接出现指令:
 push 0C8h(在a小于2的情况下)说明编译器帮我们完成中间过程的计算,具体可以采用IDA工具分析test-release版本。

0 0
原创粉丝点击