How to copy the value at a certain address in memory to a register in gcc AT&T style
To copy the value at a certain address in memory to a register in 32-bit mode we use
mov edi, [0xdeadbeef] ; Intel
movl 0xdeadbeef, %edi ; AT&T
In AT&T any literal that is not prefixed by $
is an address
But in x86_64 64-bit absolute addressing is not allowed, so you can't use movq 0xdeadbeef, %rdi
like above. The only instruction that has 64-bit immediate is mov
(movabs
in gas), which can assign a 64-bit constant to any registers, or move value at a 64-bit absolute address to Areg
mov rax, [0xdeadbeef] ; Intel
movabs 0xdeadbeef, %rax ; AT&T
If you really need to move the value from a 64-bit absolute address to a register different from Areg you must use indirect addressing instead
mov rdi, 0xdeadbeef ; Intel
mov rdi, [rdi]
movq $0xdeadbeef, %rdi ; AT&T
movq (%rdi), %rdi
or if you want the value to be copied to both rax and rdi then
mov rax, [0xdeadbeef] ; Intel
mov rdi, rax
movabs 0xdeadbeef, %rax ; AT&T
movq %rax, %rdi
Here the q
suffix means quadword (64-bit) registers
In AT&T syntax the size of memory operands is determined from the last character of the instruction mnemonic. Mnemonic suffixes of
b
,w
,l
andq
specify byte (8-bit), word (16-bit), long (32-bit) and quadruple word (64-bit) memory references. Intel syntax accomplishes this by prefixing memory operands (not the instruction mnemonics) withbyte ptr
,word ptr
,dword ptr
andqword ptr
. Thus, Intelmov al, byte ptr foo
ismovb foo, %al
in AT&T syntax.In 64-bit code,
movabs
can be used to encode themov
instruction with the 64-bit displacement or immediate operand.https://sourceware.org/binutils/docs/as/i386_002dVariations.html
More information about 64-bit mov
instruction here: Difference between movq and movabsq in x86-64. As you can see there's no version for moving from a 32-bit absolute address to a 64-bit register, so even in rare cases when the address fits in 32 bits like 0xdeadbeef, you still have to use movabs Areg, moffs64
Gnijuohz
I use Python primarily nowadays. I've previously worked with Django on several small projects and now trying out Flask. I have some experience with front end web development as well. Been using Mongodb for the past few months and am quite happy with it so far. I also developed an iOS app with Swift and node.js named GeeksforGeeks Reader, which has good reviews in the U.S. App Store. I'm interested in working with Swift, node.js more in the future.
Updated on June 04, 2022Comments
-
Gnijuohz almost 2 years
I want to copy the value at a certain address in memory to a register using AT&T style assembly. I know this shouldn't be hard, and I think in Intel style it's something like:
mov rdi, [0xdeadbeef]
But I don't know much about the AT&T style (or assembly in general). I searched about it but all the examples about
mov
that I got didn't include this one.So can anyone tell me how that instruction looks like?
Also, where can I find a complete list of x86_64 assembly instructions in AT&T style?
-
Gnijuohz over 10 yearsShould it be mov 0xdeadbeef, %rdi? Because in AT&T the destination should be the second one. So $0xdeadbeef copies the value and 0xdeadbeef copies the address?
-
phuclv over 10 yearsno, Intel style
mov [0xdeadbeef], rdi
would be reversed in AT&T syntax, which is like the one I wrote above -
Gnijuohz over 10 yearsok, my intel style instruction was wrong... Based on what I asked for, which is 'move value from memory to register' it should be the way I commented.
-
phuclv over 10 yearsAhhh, your Intel style example is wrong. To copy the value from an address to a register the instruction should be
mov rdi, [0xdeadbeef]
, which ismovq 0xdeadbeef, %rdi
in AT&T -
Gnijuohz over 10 yearsNow I'm confused... Could you explain the following three instructions? 1.
mov $5, %rdi
2.mov $0xdeadbeef, %rdi
3.mov 0xdeadbeef, %rdi
.The first one is moving the value 5 to rdi, the second one and the third one which is moving the value at the address, which one is moving the address 0xdeadbeef??? I thought the second one was moving the value because of the$
sign... -
phuclv over 10 yearsI've said that any number that is not prefixed by $ is and address. So the first 2 instructions will move the value (5 and 0xdeadbeef) to rdi. Only the last one move data from the address 0xdeadbeef to rdi. Look at the answer here
-
Gnijuohz over 10 yearsI see! Thanks so much for the clarification!
-
Gnijuohz over 10 yearsSorry but actually your answer gives an error
suffix or operands invalid for 'mov'
so I have to unchoose it as the answer... -
phuclv over 10 yearsThat's because you're compiling in the wrong mode. You must specify "-m64" or "-mx32" to use 64-bit registers and "q" suffix. Look at Differences between NASM, MASM, and GAS here, it also states that to move contents of address 10 into register ecx, use
mov ecx, [10]
ormovl 10, %ecx
-
phuclv over 10 yearsI understand why. 32-bit absolute address is not supported on x86_64. Edited my answer
-
Peter Cordes almost 6 yearsI think you read the question title backwards. It is asking for mem -> reg, like its Intel-syntax instruction is doing.
-
phuclv almost 6 years@PeterCordes originally the OP had written
mov [0xdeadbeef], rdi
which was reg -> mem -
Peter Cordes almost 6 yearsOk, but your AT&T syntax
mov %rdi, 0xdeadbeef
is a store. -
phuclv almost 6 years@PeterCordes that was the answer to the old question. I've updated to make it clearer
-
Peter Cordes almost 6 yearsThe title was always mem to reg. Preserving that historical detail as the very first thing in your current answer to the fixed question really brings it down, IMO. At least move it to a PS section or something.
-
Peter Cordes about 2 yearsBTW, 32-bit absolute addressing is allowed for any instruction: NASM
a32 mov rdi, [abs 0xdeadbeef]
is encodeable because the address-size prefix truncates to 32-bit with zero-extension back to 64, unlike normal ModRM[abs disp32]
encoding which sign-extends. That's the problem here with0xdeadbeef
, which is outside the low 2G but still in the low 4G. Objdump disassembly is67 48 8b 3c 25 ef be ad de mov 0xdeadbeef(,%eiz,1),%rdi
(because 32-bit absolute uses a SIB with no index I guess) -
Peter Cordes about 2 yearsIn AT&T syntax,
addr32 mov 0xdeadbeef, %rdi
. -
Peter Cordes about 2 years
mov rax, [0xdeadbeef]
isn't correct NASM syntax for movabs. Unfortunately you needmov rax, [qword 0xdeadbeef]
, otherwise it just warns aboutdword data exceeds bounds
and encodes a disp32 load from0xffffffffdeadbeef