x86-64下MOV EAX, moffs32指令反汇编异常原因咨询
问题
在学习x86-64架构时,我发现了MOV EAX, moffs32指令。根据理解,当moffs32为0x12345678时,该指令的编码应为A1 78 56 34 12。但使用objdump和ndisasm以64位模式反汇编时,得到错误的指令解析:
objdump -D -b binary -mi386 -Mx86-64 -Mintel file.bin
00000000 <.data>: 0: a1 .byte 0xa1 1: 78 56 js 0x59 3: 34 12 xor al,0x12
ndisasm -b 64 file.bin
00000000 A1 db 0xa1 00000001 7856 js 0x59 00000003 3412 xor al,0x12
只有以32位模式(ndisasm -b 32)反汇编时,才能得到正确结果:
00000000 A178563412 mov eax,[0x12345678]
指令表显示该指令支持64位模式,为何会出现这种情况?我似乎遗漏了某些关键知识点,希望得到解答。
解答
在x86-64长模式下,MOV EAX, moffs系列指令的编码规则和32位模式存在差异,这是反汇编出错的核心原因:
- 32位模式中,
A1opcode直接对应MOV EAX, moffs32,指令总长度为5字节(opcode + 4字节偏移),因此ndisasm用32位模式能正确识别。 - 64位模式下,默认地址大小为64位,此时
A1opcode对应的是MOV EAX, moffs64,需要8字节的偏移量。你提供的二进制只有5字节(A1+ 4字节),反汇编器无法识别为完整指令,于是将A1标记为无效字节,后续字节被拆分成独立的短指令(js 0x59和xor al,0x12)。 - 若要在64位模式下使用32位宽度的moffs偏移,需要添加地址大小前缀
67,正确编码应为67 A1 78 56 34 12。此时反汇编器会将其解析为mov eax, dword ptr [0x12345678],地址大小前缀会强制使用32位偏移(并自动零扩展为64位地址)。
指令表标注该指令支持64位模式,指的是存在适配长模式的版本,而非直接兼容32位模式的编码格式。
内容的提问来源于stack exchange,提问作者NyxCode
相关产品推荐
相关产品推荐

