C 使用字节而不是长字节的汇编指令addl
我目前正在研究使用objdump从简单c程序编译的汇编代码,但这让我感到困惑:C 使用字节而不是长字节的汇编指令addl,c,gcc,assembly,objdump,C,Gcc,Assembly,Objdump,我目前正在研究使用objdump从简单c程序编译的汇编代码,但这让我感到困惑: 4004f1: c7 45 fc 02 00 00 00 movl $0x2,-0x4(%rbp) 4004f8: 83 45 fc 05 addl $0x5,-0x4(%rbp) 指令中的“l”前缀不是很长吗?对于movl来说,它看起来不错,但addl似乎使用单字节作为操作数,这是为什么呢?许多对立即数进行操作的指令可以具有8位立即数或32位立即数
4004f1: c7 45 fc 02 00 00 00 movl $0x2,-0x4(%rbp)
4004f8: 83 45 fc 05 addl $0x5,-0x4(%rbp)
指令中的“l”前缀不是很长吗?对于movl来说,它看起来不错,但addl似乎使用单字节作为操作数,这是为什么呢?许多对立即数进行操作的指令可以具有8位立即数或32位立即数(
mov r/m32,i32
显然没有)。此设计的目的可能是减少代码大小。但是,立即数隐式符号扩展为32位。在add
的情况下,操作码83/0
是带有8位立即数的add
,操作码81/0
是带有32位立即数的add
。汇编程序应该自动选择最短的编码。您可以组装这个小片段,然后反汇编结果以观察差异:
.byte 0x83,0xc0,0x00 # addl $0,%eax with an 8 bit immediate
.byte 0x81,0xc0,0x00,0x00,0x00,0x00 # addl $0,%eax with a 32 bit immediate
该指令被编码为一个。由于5适合一个字节,汇编程序选择这样编码。值5将符号扩展为32位并存储在目标中。存储=添加了oops。@我通常查看PeterCordes。噪音越小,信息越紧凑。如果你只关心编码,那就越好。不过,我忘了它有用于修改/未定义标志的列。这是查找说明的一个主要原因。但无论如何,我经常想仔细检查操作部分的细节(以获得更复杂的说明)。此外,《英特尔手册》中的HTML摘录有助于链接到其他人,这些人可能不熟悉《英特尔手册》的好坏/详细程度。