负整数的默认存储格式



二进制值默认以 2 的补码形式存储吗?
我尝试了代码mov al, -1,发现EAX = 000000FF
这是默认的还是我们可以指定使用一个人的补码或其他格式

x86 硬件使用 2 的补码有符号整数,例如用于movsx符号扩展、imul/idiv有符号乘法/除法等指令,以及add等的 FLAGS 设置(特别是 OF),包括sub/cmp和分支条件,如jle小于或等于。 并且没有人的补码数学指令(除了not,一个人的补码否定,vs。neg二的补否定又名二元0 - x.)

另请参阅了解进位与溢出条件/标志,其中准确描述了 2 的补码溢出 (OF) 与进位 (CF) 如何用于加法。

汇编程序在将源代码中的负数编码为机器代码时,总是1使用 2 的补码。mov-立即在机器代码中只是将位模式复制到寄存器中;所有的"解释"在CPU看到它之前就已经完成了。 (mov reg, sign_extended_narrow_immediate的唯一情况是 x86-64mov r/m64, imm32仅在 64 位模式下。 另请注意,mov al, -1不会影响 EAX 的上部。 如果你看到0x000000FF,那是因为EAX的上限字节碰巧已经为零。

脚注1:你当然可以写一个x86汇编程序,它真的很奇怪,并做了其他事情。 但是,不太可能有人愿意使用它,因为这意味着add eax, -2不会将EAX的值减少2。现有的主流汇编程序使用与硬件相同的数字格式,硬件硬连线为2的补码,不可切换。

old_timer指出,一些汇编程序(例如简单微控制器的简单汇编程序)甚至可能根本不支持负常量的语法,在这种情况下,您始终必须手动将常量编码为十六进制或其他内容。 诸如0xFF$FF或任何语法之类的东西。


如果要使用 1 的补码位模式,请手动将它们编码为十六进制。 例如mov al, 0FDh(~2)而不是mov al, 0FEh-2

当然,你必须使用多个指令实现1的补码数学。add执行二进制加法,这与 2 的补码符号加法是相同的操作,但与1 的补码不是相同的操作。 (这是计算机使用 2 补码的主要原因: +/- 与无符号运算相同,乘法的低半部分也是如此。

请注意,x86 机器代码具有某些形式的指令,例如add r/m32, sign_extended_imm8它涉及解码中的 2 补码符号扩展。 即,上面的 24 位是位 #7 的副本,复制即时的顶部位以填充寄存器。 许多 1 的补码值与此兼容,例如add eax, 0FFFFFFFDh可以编码为 imm8,汇编程序将为您完成此操作。