被 x86 MOV 指令迷惑
Posted
技术标签:
【中文标题】被 x86 MOV 指令迷惑【英文标题】:Puzzled by x86 MOV instruction 【发布时间】:2014-07-22 12:58:33 【问题描述】:从 Intel64 & IA-32 manual vol 2a,指令mov
有许多可能的用法。如:
mov r64, m64 # move m64 to r64
mov rax, moffs64 # move quadword at (offset) to RAX
我写了代码来测试(gas,intel 语法):
movabs rax, label
movabs rax, offset label
...
label:
.quad 0x112233445566
经过组装,链接和objdump,我得到了相关的组装:
mov rax, qword ptr ds:0xffff80000000008e
mov rax, 0xffff80000000008e
显然,我写的第二条指令不是预期的手册指令。手册中的格式说明是什么?
【问题讨论】:
汇编器会自动在这两个版本之间进行选择,汇编是一样的。您的movabs rax, offset label
不是两者之一,而是mov r64, imm64
。如果您想查看第一个版本,即mov r64, m64
,请使用rax
以外的其他寄存器,例如mov rdx, label
。
【参考方案1】:
moffs
表示内存操作数。以下是英特尔手册中的描述:
moffs8, moffs16, moffs32, moffs64
— 字节、字或MOV
指令的某些变体使用的双字。实际地址由一个简单的偏移量给出 相对于段基数。指令中没有使用ModR/M
字节。以moffs
显示的数字 表示它的大小,由指令的address-size属性决定。
MASM 和 TASM 等汇编程序使用的 offset
运算符为您提供“[操作数] 相关段的偏移量” (source)。所以你用offset label
得到的是label
的偏移量,它是一个立即值。所以你在看两个不同的东西:获取存储在特定地址的值,而不是获取地址本身。
我不知道获得moffs64
变体的GAS 语法是什么,但是使用NASM 你可以写mov rax,[qword label]
(请注意,这种编码会比你简单写mov rax,[label]
更长 - 即mov r64, r/m64
)。
【讨论】:
GAS 语法就是movabs label, %rax
。这汇编为操作码48 a1
,这是唯一支持moffs64
的mov
指令。以上是关于被 x86 MOV 指令迷惑的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向x86 汇编 ( call 子函数调用指令 | jmp 跳转指令 | lea 加载指令 | mov 数据传送指令 )
Android 逆向x86 汇编 ( call 子函数调用指令 | jmp 跳转指令 | lea 加载指令 | mov 数据传送指令 )