Two Dialects: Intel vs AT&T Syntax
The same instructions can be written two ways. Learn to recognise both and understand why this course uses Intel syntax.
The Same Instructions, Two Spellings
There is one confusing surprise waiting for anyone who starts reading x86-64 assembly: the same machine instructions can be written in two different notations. They describe identical code, but they look quite different on the page.
The two notations are:
- Intel syntax, used by Microsoft's tools, the Intel manuals, many disassemblers, and this course.
- AT&T syntax, the default output of the GNU tools (
gcc,objdump) on Unix-like systems.
You will run into both, so the goal of this lesson is simple: be able to tell which one you are looking at, and translate between them in your head.
A Side-by-Side Example
Take our add function again:
int add(int a, int b)
{
return a + b;
}
Compiled at -O2, here it is in both notations:
; Intel syntax
add(int, int):
lea eax, [rdi+rsi]
ret
# AT&T syntax
add(int, int):
leal (%rdi, %rsi), %eax
ret
Same two instructions. Same machine code. Different spelling. Let us list exactly what changed.
The Four Differences That Matter
1. Operand order is reversed
This is the big one, and the easiest to get wrong.
- Intel:
destination, source - AT&T:
source, destination
In the Intel line, eax (the destination) comes first. In the AT&T line, %eax (the destination) comes last. The result is identical, but if you read them with the wrong convention, you will get everything backwards.
2. AT&T puts a % in front of every register
- Intel:
eax,rdi,rsi - AT&T:
%eax,%rdi,%rsi
If you see percent signs on the registers, you are reading AT&T.
3. AT&T puts a $ in front of immediate (literal) values
Consider returning the constant 42:
mov eax, 42 ; Intel
movl $42, %eax # AT&T
In AT&T, the literal 42 is written $42. In Intel it is just 42.
4. AT&T encodes operand size as a suffix letter
Look closely at the mnemonics: Intel wrote lea, AT&T wrote lea**l**. That trailing l means "long", a 4-byte operation. The size suffixes are:
| Suffix | Size | Typical C++ type |
|---|---|---|
b |
1 byte | char |
w |
2 bytes | short |
l |
4 bytes | int |
q |
8 bytes | long / pointer |
So movl, addl, popq are AT&T. Intel instead writes the size next to the operand only when it is ambiguous, using keywords like DWORD PTR (4 bytes) or QWORD PTR (8 bytes).
Memory Operands Look Different Too
The biggest visual difference is how memory addresses are written. Both express the same idea, "base register plus an offset", but the shape differs.
Reading the value at 4 bytes below rbp:
mov eax, DWORD PTR -4[rbp] ; Intel: displacement[base]
movl -4(%rbp), %eax # AT&T: displacement(base)
The general forms are:
- Intel:
displacement[base + index*scale] - AT&T:
displacement(base, index, scale)
These describe exactly the same address computation; they just arrange the pieces differently. You will study addressing modes in depth in Chapter 2. For now, just notice that square brackets mean Intel, and parentheses mean AT&T.
A Full Unoptimized Comparison
Here is add at -O0 in both notations so you can apply all four rules at once:
; Intel
add(int, int):
push rbp
mov rbp, rsp
mov DWORD PTR -4[rbp], edi
mov DWORD PTR -8[rbp], esi
mov edx, DWORD PTR -4[rbp]
mov eax, DWORD PTR -8[rbp]
add eax, edx
pop rbp
ret
# AT&T
add(int, int):
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -4(%rbp), %edx
movl -8(%rbp), %eax
addl %edx, %eax
popq %rbp
ret
Run your eyes down both. The percent signs, the size suffixes, the reversed operand order, and the parentheses for memory all jump out once you know to look for them.
Why This Course Uses Intel
Both notations are equally valid, but this course uses Intel syntax because it is generally easier to read when you are learning: no register or immediate prefixes to filter out, sizes stated only when needed, and the destination-first order that most people find natural. It is also the syntax used by the popular Compiler Explorer (godbolt.org) by default, so what you learn here will match the examples you find online.
When you view assembly in this course's editor, it will be in Intel syntax. Just remember that the GNU tools on your own machine default to AT&T, so if you ever run gcc -S yourself and the output looks different, add -masm=intel to switch.
Key Takeaways
- The same x86-64 instructions can be written in Intel or AT&T syntax.
- Operand order is reversed: Intel is
dest, src; AT&T issrc, dest. - AT&T prefixes registers with
%, immediates with$, and encodes operand size as a mnemonic suffix (b/w/l/q). - Intel uses no such prefixes and states size with keywords like
DWORD PTRonly when needed. - Memory operands: Intel uses
[ ... ], AT&T usesdisp(base, index, scale). - This course (and Compiler Explorer) use Intel syntax; GNU tools default to AT&T but accept
-masm=intel.
Create an account to track your progress and access interactive exercises. Already have one? Sign in.
Two Dialects: Intel vs AT&T Syntax - Quiz
Test your understanding of the lesson.
Lesson Discussion
Share your thoughts and questions
No comments yet. Be the first to share your thoughts!