4

我想将内存中某个地址的值复制到使用 AT&T 样式程序集的寄存器中。我知道这应该不难,而且我认为在英特尔风格中它是这样的:

mov rdi, [0xdeadbeef]

但我对 AT&T 风格(或一般的装配)知之甚少。我搜索了它,但mov我得到的所有例子都不包括这个。

那么谁能告诉我该指令的外观?

另外,我在哪里可以找到 AT&T 风格的 x86_64 汇编指令的完整列表?

4

1 回答 1

4

要将内存中某个地址的值复制到32 位模式的寄存器中,我们使用

mov edi, [0xdeadbeef] ; Intel
movl 0xdeadbeef, %edi ; AT&T

在 AT&T中,任何没有前缀的文字都是$地址

但是在 x86_64 64 位绝对寻址中是不允许的,所以你不能movq 0xdeadbeef, %rdi像上面那样使用。唯一具有 64 位立即数的指令是mov( movabsin gas),它可以将64 位常量分配给任何寄存器,或者64 位绝对地址的值移动到Areg

mov rax, [0xdeadbeef]   ; Intel
movabs 0xdeadbeef, %rax ; AT&T

如果您确实需要将值从 64 位绝对地址移动到不同于 Areg 的寄存器,则必须改用间接寻址

mov rdi, 0xdeadbeef     ; Intel
mov rdi, [rdi]

movq $0xdeadbeef, %rdi  ; AT&T
movq (%rdi), %rdi

或者如果您希望将值复制到 rax 和 rdi 然后

mov rax, [0xdeadbeef]   ; Intel
mov rdi, rax

movabs 0xdeadbeef, %rax ; AT&T
movq %rax, %rdi

这里q后缀表示四字(64 位)寄存器

在 AT&T 语法中,内存操作数的大小由指令助记符的最后一个字符确定。bw和的助记符后缀l指定q字节(8 位)、字(16 位)、长字(32 位)和四字(64 位)内存引用。英特尔语法通过在内存操作数(不是指令助记符)前加上byte ptrword ptr和. 因此,英特尔采用AT&T 语法。dword ptrqword ptrmov al, byte ptr foomovb foo, %al

在 64 位代码中,movabs可用于对mov64 位位移或立即操作数的指令进行编码。

https://sourceware.org/binutils/docs/as/i386_002dVariations.html

此处有关 64 位mov指令的更多信息:x86-64 中 movq 和 movabsq 之间的区别。如您所见,没有从 32 位绝对地址移动到 64 位寄存器的版本,因此即使在极少数情况下,当地址适合 0xdeadbeef 等 32 位时,您仍然必须使用movabs Areg, moffs64

于 2013-10-21T03:44:17.317 回答