23

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.

21

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/.

  • I looked at the gas manual but I did not find the right section. Thanks a lot 0xC0000022L ! :-) – perror Aug 12 '13 at 19:53
  • How can you move a 32 bit number into al? – phuclv Sep 25 '13 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 '13 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 '14 at 10:31
8

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

6

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

  • 1
    good downloadable reference thanks igorsk for the link – blabb Aug 13 '13 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.

  • 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 '18 at 6:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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