我已经阅读了关于部分寄存器的解释 并想了解为什么这段代码:
XOR EAX,EAX
MOV AX, BX
只有当eax持有非签名正数时,才会起作用 但是如果eax中有一个带符号的负数 你需要确保你添加的新位是111 ..我知道它与二进制补码有关 但我仍然不明白。
修改
我理解上面的代码可以正常工作 我想知道为什么你需要填补额外的1(当我没有零eax时)
答案 0 :(得分:2)
通常,在手写汇编时使用无符号数字。当然,情况并非总是如此,C的int
促销应该以某种方式实施,对吗?
让我们首先解释位级别的二进制补码。首先,最高位在设置时表示负数,在清除时表示非负数。如果清楚的话,这些东西就像你期望的那样。也就是说,0
写为0x00000000
,2147483647
写为0x7FFFFFFF
。但是,对于任何负数N
,为了获得其绝对值,您必须执行~N-1
,并使用所有相应的环绕。这有助于-1
正在撰写0xFF
,-2147483648
正在撰写0x80
。这有一些很好的副作用,因此-0 == 0
和加法/减法对所有数字都是相同的操作。
现在,你的代码......
XOR EAX,EAX
作为一种数学规则,对某些东西进行异或运算总会产生零结果。所以,你可以把它想象成一个优化的`MOV EAX,0'。顺便说一下,您可能想阅读why XOR is better for this。然后...
MOV AX, BX
MOV
是一条字面意思是“按原样复制位”的指令。也就是说,源中的所有清零位分别在目的地中被清除,并且源中的所有设置位分别被设置在目的地中。在这种情况下,AX
现在将包含BX
内容的精确副本。在x86架构中,EAX
,EBX
,ECX
和EDX
都是这样划分的......
________________ ________ ____ ____
| ERX | RX | RH | RL |
|________________|________|____|____|
\_________________________________/
| \________________/
32 bits | \__/
16 bits ||
8 bits
这意味着对于每个寄存器R
,ERX
表示其所有32位,RX
表示其低16位,RH
表示其低位的较高字节16位,RL
表示其低16位的低字节。因此,返回到您的代码,并假设BX
包含0xFFFF
(两个补码中的-1
),这就是...
______________ __________________________________ __________________________________
| Instruction | EAX | EBX |
|______________|__________________________________|__________________________________|
| XOR EAX, EAX | 00000000000000000000000000000000 | 00000000000000001111111111111111 |
|______________|__________________________________|__________________________________|
| MOV AX, BX | 00000000000000001111111111111111 | 00000000000000001111111111111111 |
|______________|__________________________________|__________________________________|
然后,如果我们将AX
解释为二进制补码,我们会得到正确的答案,即-1
。但是,如果我们将EAX
解释为二的补码,我们会得到一个错误的答案,65535
。为了正确地做到这一点,我们必须进行符号扩展移动。这意味着该指令将考虑这个值是二进制补码形式的事实,因此将正确地操纵它。例如,见......
_______________ __________________________________ __________________________________
| Instruction | EAX | EBX |
|_______________|__________________________________|__________________________________|
| MOVSX EAX, BX | 11111111111111111111111111111111 | 00000000000000001111111111111111 |
|_______________|__________________________________|__________________________________|
现在,将EAX
解释为32位二进制补码数将得出正确答案-1
。这是(两个)补充的另一个优点。您可以根据需要多次复制最顶部位来进行符号扩展。