使用 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