32

I just found a strange instruction by assembling (with gas) and disassembling (with objdump) on a amd64 architecture.

The original amd64 assembly code is:

mov 0x89abcdef, %al

And, after gas compiled it (I am using the following command line: gcc -m64 -march=i686 -c -o myobjectfile myassemblycode.s), objdump gives the following code:

a0 df ce ab 89 00 00    movabs 0x89abcdef, %al

My problem is that I cannot find any movabs, nor movab in the Intel assembly manual (not even a mova instruction).

So, I am dreaming ? What is the meaning of this instruction ? My guess is that it is a quirks from the GNU binutils, but I am not sure of it.

PS: I checked precisely the spelling of this instruction, so it is NOT a movaps instruction for sure.

3

4 Answers 4

29

Here's the official documentation for gas, quoting the relevant section:

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 and q 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) with byte ptr, word ptr, dword ptr and qword ptr. Thus, Intel mov al, byte ptr foo is movb foo, %al in AT&T syntax.

In 64-bit code, movabs can be used to encode the mov instruction with the 64-bit displacement or immediate operand.

Particularly read the last sentence.

Note: Found via Google operator inurl, searching for movabs inurl:sourceware.org/binutils/.

4
  • I looked at the gas manual but I did not find the right section. Thanks a lot 0xC0000022L ! :-)
    – perror
    Aug 12, 2013 at 19:53
  • How can you move a 32 bit number into al?
    – phuclv
    Sep 25, 2013 at 6:24
  • @LưuVĩnhPhúc: well you can only with losses, but this has nothing to do with my answer or the question, so you better ask it as a new question.
    – 0xC0000022L
    Sep 25, 2013 at 7:17
  • What's interesting, gdb gives me 48 b8 <imm64> bytes as movabs rax, <imm64> even in disassembly-flavor=intel.
    – Ruslan
    Oct 30, 2014 at 10:31
9

movabs is used for absolute data moves, to either load an arbitrary 64-bit constant into a register or to load data in a register from a 64-bit address.

Source: http://www.ucw.cz/~hubicka/papers/amd64/node1.html

8

If you find yourself often deciphering AT&T syntax x86/x64 assembler, Solaris manuals may be of help: x86 Assembly Language Reference Manual .

1
  • 1
    good downloadable reference thanks igorsk for the link
    – blabb
    Aug 13, 2013 at 9:00
3

I noticed that GAS translates

movq $0x80000000, %rax

into

movabs 0x80000000, %rax

But values smaller than 0x80000000 movement is not translated into movabs. That is, movq $0x7fffffff, $rbx is NOT translated into movabs $0x7fffffff, %rbx. You can verify with disas disassemble command within GDB.

Maybe the reason is that $0x80000000 is over the signed positive number range of 32 bit and needs to be translated into 64-bit integer. For the reason, GAS translates such larger number into 64-bit long integer and therefore uses movabsq instruction instead of movq instruction whose immediate source is limited to 32 bit constant.

1
  • this is incorrect movq $0x80000000, %rax moves the immediate 0x80000000 into rax whereas movabs 0x80000000, %rax loads the quadword at address 0x80000000 to rax
    – phuclv
    Aug 8, 2018 at 6:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.