有没有一种方法可以在32位寄存器指令中保持字大小的立即数



假设以下x86-32指令:

add ebx,1

(至少)有两种方法可以组装此操作码:

81 c3 01 00 00 00

83 c3 01

第一个保留1作为4字节的双字第二个保持1作为字节

是否有将1保持为2字节的指令?如果没有,为什么?

您偶然发现了x86指令集的一个怪癖。英特尔在干83下包含了一组指令,其第一个操作数为Ev类型,第二个操作数是立即数字节,被解释为与Ev操作数大小相同。因此,对于83 c3 0101被解释为32位值;对于66 83 c3 01,01被解释为16位值(并且目的地是16位ax寄存器)。在词干6A下编码的push助记符在其单个操作数的大小方面以相同的方式表现。

你的问题的更广泛的答案是否定的,没有将16位常数解释为32位常数的编码。

来源:我写了一个反汇编程序。

66 81 C3 01 00(在32位模式下为"add bx,01")可能被认为是一个例子

没有这样的例子不需要重写,因为不需要重写。第一个例子需要四个字节的原因是它可以跨越整个4Gb范围。第二个只使用一个字节,因为它被限制为+/-128(总共256个值)。通过使用覆盖,我们可以将第一个示例限制为64kb,但实际上它不是两个字节中的一个,它仍然是两个字节。

无论目标大小,在编程中使用小整数是非常常见的。好处是减少了指令编码。许多指令支持这一点:IMUL、ADD、ADC、SUB、SBB、AND、CMP等。此外,寻址模式支持字节大小符号扩展偏移,以帮助减少代码大小。

至于为什么不:我认为与字节编码的节省相比,增加的节省是最小的。ENTER指令确实使用16位立即数,但它是无符号的,并且固定为更新寄存器RSP/ESP/SP。

最新更新