11

在 x64 上,从 64 位绝对地址加载(即,取消引用 64 位立即数)可以通过

movabs addr64, %rax

但是,当目标寄存器不是rax汇编器时,会给出一条错误消息,说operand size mismatch for movabs. 我错过了什么?

4

2 回答 2

9

MOV 指令文档中,您可以看到您可以将 64 位立即数移动到任何寄存器,但涉及 64 位立即数绝对地址的加载/存储只能使用 Areg

操作码 操作说明 描述
A0 MOV AL, moffs8 * 将 ( seg:offset )处的字节移动到 AL。
雷克斯.W + A0 MOV AL, moffs8 * 将(偏移)处的字节移动到 AL。
A1 MOV AX,moffs16 * 将 ( seg:offset )处的单词移动到 AX。
A1 MOV EAX,moffs32 * 将 ( seg:offset ) 处的双字移动到 EAX。
雷克斯.W + A1 MOV RAX,moffs64 * 将 ( offset )处的四字移动到 RAX。
A2 MOV moffs8 ,AL 将 AL 移动到 ( seg:offset )。
雷克斯.W + A2 MOV moffs8 ***,AL 将 AL 移动到(偏移)。
A3 MOV moffs16 *,AX 将 AX 移动到 ( seg:offset )。
A3 MOV moffs32 *,EAX 将 EAX 移动到 ( seg:offset )。
雷克斯.W + A3 MOV moffs64 *,RAX 将 RAX 移动到(偏移)。

如您所见,没有 ModR/M 字节来编码寄存器编号。由于这比将 64 位立即数移动到寄存器更不常用,因此不会有问题。如果真的需要,可以在 2 条指令中完成

MOVABS是操作MOV码形式的 GAS 操作码名称,MOV Areg, [Offs64]并且MOV [Offs64], Areg. 在 Yasm 的 NASM 语法模式下,你可以通过MOV AX, [qword xxx]. Yasm 的 GAS 语法模式接受MOVABS(为了 GAS 兼容性)。请注意,此表格仅对 Areg (AL/AX/EAX/RAX) 作为源/目标寄存器有效。

http://cvs.tortall.net/pipermail/yasm-devel/2006-March/000579.html

于 2013-10-17T00:37:10.890 回答
3

对于除一个以外的任何寄存器%rax都可以用两条指令替换它:

48 bb f0 de bc 9a 78 56 34 12   mov    $0x123456789abcdef0,%rbx
48 8b 1b                        mov    (%rbx),%rbx

这个比一个长,

48 a1 f0 de bc 9a 78 56 34 12   mov    0x123456789abcdef0,%rax

因此,如果您可以使用它,您很可能更喜欢movabs(后者)。

于 2013-10-17T09:52:20.937 回答