Difference Between AT&T and Intel Assembly Syntax
-------------------------------------------------
Shok (Matt Conover), shok@dataforce.net
The difference
--------------
This document is more related to coding than hacking, although
assembly is a very useful programming language, as its machine level and
provides direct access to the CPU, hardware, etc. Now in all Unix-derived
systems, the compilers like gcc use att syntax assembly and not intel. For
example: movl %esp, %ebp
Now this is unfortunate for DOS assembly programmers who recently
switched to Unix-derived systems. They are used to Intel syntax, whereas
Linux (and others) uses AT&T syntax. Where in the example above you
would use: mov ebp, esp.
I wrote this because I have only seen one document that
explained the differences between AT&T and Intel syntax. That document was
the GAS (GNU assembler) reference manual.
You can get the GAS reference manual at:
http://www.cs.utah.edu/csinfo/texinfo under "gas"
First let me give a few examples.
Intel: push 4
AT&T: pushl $4
All the immediate operands have a $ in front of them, in intel syntax, you
don't have prefix.
The register operands, have a % in front of them, intel has none.
Intel: mov eax, 4
att: movl $4, %eax
You notice there is a diff in intel/att's src/dst...
Intel: you do dst, src like mov ax, 2
att: it's the opposite, src, dst like movl $2, %ax
You can use 'b' for byte, 'w' for word, 'l' for long, etc...as the memory
suffix:
movl, movb, movw, etc.
in intel you wold do this like mov ax, byte ptr foo...
The far instruction for att is lret $stack-adjust, in intel it's
ret far stack-adjust.
The l in front of mov, is the byte/memory operand..... this is actually
more convient if you ask me.
In Intel you have:
section:[base + index*scale + disp]
disp = displcement
scale = 1 if not given
In AT&T, however, you would have:
section:disp(base, index, scale)
So "es:[ebp-5]" in Intel would be "%es:-4(%ebp)" in AT&T syntax.
Intel: [foo] AT&T: foo(,1) the ,1 means an index of one...
Inte: [foor + eax*4] AT&T: foor(, %eax, 4)
I hope this helps
How to Get some assembly examples in unix:
-----------------------------------------
Now how to get a few examples on how to get some assembly code for Unix.
Use this (assuming you called it test.c):
void main()
{
printf("hin");
}
now to compile it, do gcc -S test.c, this will make a file test.s in
assembly......look at it it contains great info....and some examples of
the macros and what not defined/shown in gas' (GNU assembler) manual.
(Which can be found at http://www.cs.utah.edu/csinfo/texinfo, under gas.
here is what test.s will look like:
.file "test.c"
.version "01.01"
gcc2_compiled.:
.section .rodata
.LC0:
.string "testn"
.text
.align 4
.globl main
.type main,@function
main:
pushl %ebp
movl %esp,%ebp
pushl $.LC0
call printf
addl $4,%esp
.L1:
leave
ret
.Lfe1:
.size main,.Lfe1-main
.ident "GCC: (GNU) 2.7.2.1"
As you know, the l's in front of push, mov, add, etc....that means it's
type long. and the % goes in front of all register operands, whereas in
intel syntax, it is undelimited. Likewise, the immediate operands, have a
'$' in front of them, whereas once again, intel is undelimited.
movl $3, %eax
is equal to:
mov eax, 3
in intel
The other way to get asm code is with gdb......you compile your program
with gcc -g .......and for even more......gcc -g -a...
here is our test.c ......in gdb,
we do 'disassemble main':
(gdb) disassemble main
Dump of assembler code for function main:
0x8048474 : pushl %ebp
0×8048475 : movl %esp,%ebp
0×8048477 : pushl $0×80484c8
0×804847c : call 0×8048378
0×8048481 : addl $0×4,%esp
0×8048484 : leave
0×8048485 : ret
End of assembler dump.
That is with just -g…….with -a as well you can see the difference
(more instructions show up that usually wouldn’t):
(gdb) disassemble main
Dump of assembler code for function main:
0×80485d8 : pushl %ebp
0×80485d9 : movl %esp,%ebp
0×80485db : cmpl $0×0,0×8049a6c
0×80485e2 : jne 0×80485f1
0×80485e4 : pushl $0×8049a6c
0×80485e9 : call 0×80488fc <__bb_init_func>
0×80485ee : addl $0×4,%esp
0×80485f1 : incl 0×8049b78
0×80485f7 : pushl $0×8048978
0×80485fc : call 0×8048468
0×8048601 : addl $0×4,%esp
0×8048604 : incl 0×8049b7c
0×804860a : leave
0×804860b : ret
End of assembler dump.
I of course need to give credit of this to the gas manual, as parts were
taken from there.
Shok (Matt Conover)
Email: shok@dataforce.net
Web: http://www.w00w00.org
—————-