将内存中某个地址的值复制到寄存器在 32 位模式下我们使用
mov edi, [0xdeadbeef] ; Intel
movl 0xdeadbeef, %edi ; AT&T
在 AT&T any literal that is not prefixed by $ is an address
但是在 x86_64 64-bit absolute addressing is not allowed,所以你不能像上面那样使用movq 0xdeadbeef, %rdi。唯一具有 64 位立即数的指令是 mov(气体中的 movabs),它可以将 64 位常量分配给任何寄存器,或 move value at a 64-bit absolute address to Areg
mov rax, [0xdeadbeef] ; Intel
movabs 0xdeadbeef, %rax ; AT&T
如果您确实需要将值从 64 位绝对地址移动到不同于 Areg 的寄存器中,您必须 use indirect addressing instead
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 语法中,内存操作数的大小由指令助记符的最后一个字符确定。 b、w、l 和 q 的助记符后缀指定字节(8 位)、字(16 位)、长(32 位)和四字(64 位)内存引用。英特尔语法通过在内存操作数(不是指令助记符)前加上 byte ptr、word ptr、dword ptr 和 qword ptr 来实现这一点。因此,Intel mov al, byte ptr foo 在 AT&T 语法中是 movb foo, %al。
在 64 位代码中,movabs 可用于使用 64 位位移或立即操作数对 mov 指令进行编码。
https://sourceware.org/binutils/docs/as/i386_002dVariations.html
更多关于 64 位 mov 指令的信息在这里:Difference between movq and movabsq in x86-64。如您所见,没有从 32 位绝对地址移动到 64 位寄存器的版本,因此即使在极少数情况下,当地址适合 0xdeadbeef 等 32 位时,您仍然必须使用movabs Areg, moffs64