在编译器VC6中,执行结果也相同。先看看分别给p和q赋值的汇编代码及其单步执行顺序:
我们发现:第一,逻辑相同的情况下,两者的汇编代码不同;第二,两者的执行顺序不同;第三,也是最关键的一点,两者使用寄存器的方式不同。
在给p赋值的过程中,分别用到了32位寄存器eax,ecx,edx,和16位寄存器a1,c1,d1.求第一个逻辑因子的时候,在jne处发生跳转,说明test处执行结果不为0.为什么会不为0呢?根据执行顺序:首先,eax=0x0000 0000,接着,a1=0x00ff,(我猜测)在执行not的时候,a1进行数据扩充,于是eax = 0x0000 00ff,not以后,变成0xffff ff00,而执行test以后,结果为(真真为真)1.所以不为0.
而在给q赋值的过程中,只有32位寄存器,开始时,edx = 0x0000 0000,在and后,edx = 0x0000 0000(0FF也要扩充),test时,结果为0(有假则假),当然也不存在jne跳转。
为了验证这个猜测,我把 unsigned char k,m,o 变成 unsigned int k,m,o后,结果k = m = o = -255,p = q = 1.
|