x86-64 assembly order of operands
Asked Answered
R

1

5

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!

Rochellerochemont answered 19/1, 2019 at 7:48 Comment(4)
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."Mccurry
For AT&T for instance it is cmd source, dest while with Intel it is cmd dest, source so it is assembler dependent.Inconsonant
@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. 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.Seethrough
there's another major syntax for x86: Plan9 syntax uses in golangBattleplane
O
6

It depends on the syntax of an assembler. Mostly we have two choices: and AT&T syntaxes. See their respective tag wikis, intel-syntax and att.

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 the Intel syntax tag wiki for details on the differences and telling them apart.

Intel syntax example (from objdump -drwC -Mintel 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. GCC has -masm=intel which affects how inline asm("" :::) statements are assembled, as well as the asm the compiler feeds to the assembler.

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

Related:

Own answered 19/1, 2019 at 8:0 Comment(2)
Compilers have options too, if you're getting asm output instead of machine code (How to remove "noise" from GCC/clang assembly output?). gcc/clang/icc -masm=intel.Seethrough
Also, unix assemblers such as GNU assembler can switch syntax on the fly, see e.g. this question about "how" and this post with actual usage.Boracite

© 2022 - 2024 — McMap. All rights reserved.