2016-03-08 100 views
0

我读过有关部分寄存器 的解释,想明白为什么这个代码:如果EAX持有非签约正数 大会部分寄存器

XOR EAX,EAX 
MOV AX, BX 

只会工作,但如果有一个签名的负在eax的号码 你需要确保你添加的新位是111 ..,我明白它与二进制补码 但我仍然不明白它。

编辑:

我明白上面的代码将工作无论哪种方式 我想知道你为什么会需要垫这些额外1的(当我这样做不是零EAX)

+6

因为它被归零,所以'EAX'中的内容并不重要。重要的是'BX'中的内容。大概你在谈论的是将'BX'扩展到'EAX'的符号,但是这段代码没有扩展名。对于非负数,当然相当于符号扩展,因为符号位是“0”。 – Jester

+1

实际上你应该在这里做的是'movzx eax,bx'或者'movsx eax,bx',用于零或符号扩展。或者,这是您推理什么序列等同于哪条指令的参考点。 –

+0

实际上,我试图了解movzx的用法,我的意思是为什么你甚至需要填补那些额外的1s – Yarden

回答

2

更多的时候不是,您在手写汇编时使用无符号数字。当然,情况并非总是如此,C的int促销活动应该以某种方式实施,对吧?

让我们从解释比特级的二进制补码开始。首先,最高位在设置时表示负数,当清除时,表示非负数。如果清楚的话,这些东西就像你期望的一样。即,0被写入0x00000000,并且2147483647被写入0x7FFFFFFF。但是,对于任何负数N,为了获得其绝对值,您必须执行~N-1以及所有相应的绕回。这借给写0xFF-1和写为0x80-2147483648。这有一些很好的副作用,所以-0 == 0和加法/减法对于所有数字都是相同的操作。

现在,你的代码....

XOR EAX,EAX 

作为数学规则,异或运算对本身的东西总是会产生零结果。所以,你可以把它想象成一个优化的`MOV EAX,0'。顺便说一句,你可能想读why XOR is better for this。然后......

MOV AX, BX 

MOV是,字面意思是“对位原样复制”的指令。也就是说,源中的所有清零位在目标中分别被清零,并且源中的所有设置位分别设置在目标中。在这种情况下,AX现在将包含BX的内容的精确副本。在x86架构中,EAXEBXECX,和EDX都划分这样...

________________ ________ ____ ____ 
|  ERX  | RX | RH | RL | 
|________________|________|____|____| 
\_________________________________/ 
      |  \________________/ 
     32 bits    | \__/ 
         16 bits || 
           8 bits 

这意味着对于每一个寄存器RERX表示它的所有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。这是(还)补码的另一个优点。您可以根据需要多次复制最上面的位来签名扩展。

+0

[这解释了为什么'xor'-zeroing比'mov reg,0'更好](http://stackoverflow.com/questions/33666617/which-is-best-way-to-set-a-register-to -Zero-在86装配-XOR-MOV或 - 和)。您可能希望将该链接纳入您的答案。此外,x86标记wiki还有一些链接,用于注册图表,如您为单个寄存器创建的ASCII图表。 –

+0

@PeterCordes:编辑。谢谢! – 3442

+0

为什么在主持人把它拿出来之后,我希望这会给你带来一丝亮光!这甚至不是一个有意义的英语句子。你可以说“我希望这能够解决你的问题”,即阐明/澄清了以前不清楚/难以理解的内容。但这听起来不太酷。我无法想出一个很好的方式来描述我认为你想说的话。无论如何,我认为这是多余的;每个帖子的答案都是为了帮助人们。无论是问题的提问者,还是更经常地帮助未来阅读它的其他人。 –