You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

汇编代码中addr32前缀含义及双addr32出现原因

x86_64反汇编中addr32前缀的含义

先贴对应反汇编片段:

adcx   %r13,%r13                                #! PC = 0x55555557d9fb
adox   %rcx,%r10                                #! PC = 0x55555557da01
adcx   %r14,%r14                                #! PC = 0x55555557da07
addr32 mulx %rdx,%rcx,%rbp                      #! PC = 0x55555557da0d
mov    0x98(%rsi),%rdx                          #! EA = L0x7fffffffdc68; Value = 0x0000000000000000; PC = 0x55555557da13
adox   %rax,%r11                                #! PC = 0x55555557da1a
adcx   %r15,%r15                                #! PC = 0x55555557da20
adox   %rcx,%r12                                #! PC = 0x55555557da26
mov    $0x20,%rsi                               #! PC = 0x55555557da2c
adox   %rbp,%r13                                #! PC = 0x55555557da33
addr32 addr32 mulx %rdx,%rcx,%rax               #! PC = 0x55555557da39

单addr32的具体含义

addr32对应机器码字节0x67,是x86架构定义的地址长度覆盖前缀。64位长模式下默认内存寻址使用64位规则计算有效地址,当指令前携带0x67前缀时,会强制切换为32位寻址宽度计算内存操作数的有效地址。
你这段代码里的addr32和寻址宽度修改没有任何关系:此处mulx的操作数全是通用寄存器,不存在内存访问,自然没有切换寻址宽度的需求。这个前缀是编译器插入的冗余对齐填充字节,目的是把后续指令的起始地址凑到对齐边界(通常是16字节或缓存行起始位置),提升CPU取指和执行效率。GDB反汇编时没有把这个填充字节识别为对齐nop,就直接按前缀对应的助记符打印成了addr32。

连续两个addr32的成因

最后一行出现两个addr32,本质是编译器在这条mulx指令前连续插入了两个0x67字节凑对齐长度。
x86架构允许指令前存在不改变指令行为的冗余前缀,只要整条指令(含前缀)总长度不超过15字节的硬件限制,CPU执行时会直接忽略这些冗余前缀,不会抛出异常。反汇编工具只是逐字节解析机器码,遇到一个0x67就打印一个addr32,遇到两个就打印两个,不会主动做省略处理。
可以通过地址差直接验证:带单个addr32的mulx从0xda0d起始,到下一条指令0xda13总长度为6字节,比无冗余前缀的同形式mulx刚好多1字节,就是那个0x67填充字节;带双addr32的mulx从0xda39起始,两个0x67字节刚好把指令长度凑到对齐需要的数值。

这类冗余前缀的显示效果和反汇编工具版本有关,新版objdump、IDA等工具会把纯用于对齐的冗余前缀识别为填充数据,不会显示为addr32助记符。

内容的提问来源于stack exchange,提问作者Alex Lai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:48:45