负整数的默认存储格式

二进制值是否默认以 2 的补码形式存储?
我试验了代码 mov al,-1 并看到 EAX = 000000FF
这是默认的还是我们可以指定使用补码或其他格式

wszh453978896 回答:负整数的默认存储格式

x86 硬件使用 2 的补码有符号整数,例如有关 movsx 符号扩展、imul/idiv 带符号乘法/除法和 add 等的 FLAGS 设置(特别是 OF)等指令,包括 sub/ cmp 和分支条件,如 jle 小于等于。并且没有任何补码数学指令(除了 not,一个补码否定与 neg 二进制补码否定,也就是二进制 0 - x。)

另请参见 Understanding Carry vs. Overflow conditions/flags,它准确描述了 2 的补码溢出 (OF) 与进位 (CF) 对加法的作用。

在将源代码中的负数编码为机器代码时,汇编器总是1使用 2 的补码。 机器代码中的 mov-immediate 只是将位模式复制到登记册;在 CPU 看到之前,所有“解释”都已经完成。 (mov reg,sign_extended_narrow_immediate 的唯一情况是 x86-64 mov 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,汇编程序会为您完成。

本文链接:https://www.f2er.com/283511.html

大家都在问