汇编指令 addl 使用字节而不是长
Posted
技术标签:
【中文标题】汇编指令 addl 使用字节而不是长【英文标题】:Assembly instruction addl using byte instead of long 【发布时间】:2016-08-27 20:37:11 【问题描述】:我目前正在研究使用 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似乎使用单个字节作为操作数,这是为什么呢?
【问题讨论】:
指令被编码为 ADD r/m32, imm8 。由于 5 适合一个字节,因此汇编程序选择以这种方式对其进行编码。值 5 将符号扩展为 32 位并存储在目标中。 已存储 = 添加了哎呀。 【参考方案1】:许多对立即数进行操作的指令可以具有 8 位立即数或 32 位立即数(mov r/m32,i32
尤其没有)。这种设计的目的可能是减少代码大小。但是,立即数隐式符号扩展为 32 位。对于add
,操作码83 /0
是add
,具有8 位立即数,操作码81 /0
是add
,具有32 位立即数。您的汇编程序应该自动选择最短的编码。你可以把这个小sn-p组装起来,然后拆开结果来观察区别:
.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
【讨论】:
@PeterCordes 我通常会查看this one。噪音更少,信息更紧凑。 如果您只关心编码,那就太好了。不过,我忘记了它有用于修改/未定义标志的列。这是查找说明的主要原因之一。但无论如何,我经常想仔细检查操作部分的详细信息(以获得更复杂的说明)。此外,英特尔手册中的 html 摘录非常适合链接到其他可能不熟悉英特尔手册的好/详细程度的人。以上是关于汇编指令 addl 使用字节而不是长的主要内容,如果未能解决你的问题,请参考以下文章