有没有办法在32位寄存器指令中立即保持字大小

时间:2013-06-29 11:00:10

标签: assembly x86 reverse-engineering nasm

假设以下x86-32指令:

add ebx,1

有(至少)两种方法来组装这个操作码:

81 c3 01 00 00 00

83 c3 01

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

是否有一个指令将1保持为2个字节? 如果没有原因?

3 个答案:

答案 0 :(得分:12)

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

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

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

答案 1 :(得分:0)

66 81 C3 01 00(在32位模式下“添加bx,01”)可能被视为它的一个例子。

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

答案 2 :(得分:0)

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

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