4

What is the order of operands in x86-64 assembly?: instruction destination, source Or: instruction source, destination

I have three books and two different approaches!

Peter Cordes
  • 286,368
  • 41
  • 520
  • 731
Josiah
  • 43
  • 7
  • 2
    Actually, it can vary depending on what assembler you use. There are two common standards *Intel* and *AT&T*. There are frequent debates over which one is "better." – David Wohlferd Jan 19 '19 at 07:55
  • For *AT&T* for instance it is `cmd source, dest` while with *Intel* it is `cmd dest, source` so it is assembler dependent. – David C. Rankin Jan 19 '19 at 08:01
  • @DavidWohlferd: I think the main debate is usually whether AT&T syntax is usable / bearable *at all*. I've seen very few claims that it's better. The most that people usually claim is that it's not worse and you can get used to it, at least compared to a nice consistent assembler like NASM. It's pretty hard to defend a syntax that literally has design bugs (with `fsubr` vs. `fsub` being reversed for some register-register operands. https://sourceware.org/binutils/docs/as/i386_002dBugs.html). Other than for x87, I don't have a problem with it after getting my brain into AT&T mode. – Peter Cordes Jan 19 '19 at 08:11

1 Answers1

6

It depends on the syntax of an assembler. Mostly we have two choices: Intel and AT&T syntaxes.

There are multiple flavours of Intel syntax, the major ones being NASM (mov dword [symbol_name], 1) and MASM (including GAS's .intel_syntax noprefix mode which many GNU and Unix tools can use.) See https://stackoverflow.com/tags/intel-syntax/info for details on the differences and telling them apart.

Intel syntax example (from objdump disassembly, so this is GNU .intel_syntax, with a couple examples added in):

push   rbp         # comment character can be # (GAS) or ; MASM/NASM
mov    rbp,rsp
mov    DWORD PTR [rbp-0x4],edi
mov    DWORD PTR [rbp-0x8],esi
mov    edx,DWORD PTR [rbp-0x4]
mov    eax,DWORD PTR [rbp-0x8]
add    eax,edx
pop    rbp
ret

add    dword ptr [rdi], 1    # size specifier mandatory if neither operand is a reg
imul   ecx, [rdi + rax*4 + 20], 12345

There's only one flavour of AT&T syntax (https://stackoverflow.com/tags/att/info):

push   %rbp                 # comment character is always #
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    -0x4(%rbp),%edx
mov    -0x8(%rbp),%eax
add    %edx,%eax
pop    %rbp
retq

addl  $1, (%rdi)      # size suffix b/w/l/q used to indicate operand-size if neither operand is a register

# with more than 2 operands, reverse the whole list
imul   $12345, 20(%rdi, %rax, 4), %ecx 

AT&T syntax is native to Unix systems. Usually, decompilers have flags to control a type of output syntax. For example objdump has -Mintel flag, gdb has set disassembly-flavor intel option.

Also, take a look at this useful site on which you can quickly see assembler output without noise Compiler Explorer


Beware that AT&T syntax has a design bug for x87 non-commutative FP instructions like fsub and fsubr with register operands: see the manual: https://sourceware.org/binutils/docs/as/i386_002dBugs.html

Peter Cordes
  • 286,368
  • 41
  • 520
  • 731
funnydman
  • 4,408
  • 3
  • 22
  • 42
  • 1
    Compilers have options too, if you're getting asm output instead of machine code ([How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116)). gcc/clang/icc `-masm=intel`. – Peter Cordes Jan 19 '19 at 08:05
  • Also, unix assemblers such as GNU assembler can switch syntax on the fly, see e.g. [this question](https://stackoverflow.com/q/9347909/673852) about "how" and [this post](https://stackoverflow.com/q/5397677/673852) with actual usage. – Ruslan Jan 19 '19 at 08:18