使用 byte 而不是 long 的汇编指令 addl
Assembly instruction addl using byte instead of long
我目前正在研究使用 objdump 从简单的 c 程序编译的汇编代码,但这让我感到困惑:
4004f1: c7 45 fc 02 00 00 00 movl [=10=]x2,-0x4(%rbp)
4004f8: 83 45 fc 05 addl [=10=]x5,-0x4(%rbp)
指令中的'l'前缀不是代表long吗,movl看起来还好,addl操作数好像是单字节,这是为什么呢?
许多对立即数进行操作的指令可以具有 8 位立即数或 32 位立即数(mov r/m32,i32
尤其没有)。这种设计的目的很可能是减少代码大小。但是,立即数被隐式符号扩展为 32 位。在 add
的情况下,操作码 83 /0
是带有 8 位立即数的 add
,操作码 81 /0
是带有 32 位立即数的 add
。您的 assembler 应该会自动选择最短的编码。您可以 assemble 这个小片段,然后 disassemble 结果以观察差异:
.byte 0x83,0xc0,0x00 # addl [=10=],%eax with an 8 bit immediate
.byte 0x81,0xc0,0x00,0x00,0x00,0x00 # addl [=10=],%eax with a 32 bit immediate
我目前正在研究使用 objdump 从简单的 c 程序编译的汇编代码,但这让我感到困惑:
4004f1: c7 45 fc 02 00 00 00 movl [=10=]x2,-0x4(%rbp)
4004f8: 83 45 fc 05 addl [=10=]x5,-0x4(%rbp)
指令中的'l'前缀不是代表long吗,movl看起来还好,addl操作数好像是单字节,这是为什么呢?
许多对立即数进行操作的指令可以具有 8 位立即数或 32 位立即数(mov r/m32,i32
尤其没有)。这种设计的目的很可能是减少代码大小。但是,立即数被隐式符号扩展为 32 位。在 add
的情况下,操作码 83 /0
是带有 8 位立即数的 add
,操作码 81 /0
是带有 32 位立即数的 add
。您的 assembler 应该会自动选择最短的编码。您可以 assemble 这个小片段,然后 disassemble 结果以观察差异:
.byte 0x83,0xc0,0x00 # addl [=10=],%eax with an 8 bit immediate
.byte 0x81,0xc0,0x00,0x00,0x00,0x00 # addl [=10=],%eax with a 32 bit immediate