i386 assembler with Linux

Differences between Intel and AT&T syntax

There are the following differences between the "Intel" and the "AT&T" syntax.

Parameter ordersource,dest
(i.e. to put 23 in reg eax you write mov $23, %eax)
(i.e. put 23 in eax becomes mov eax,23)
Parameter sizeuses suffix b for byte, w for int16, l for int32, q for int64
Immediate valuesare prefixed with $automatically detected
Registersare prefixed with %automatically detected (do not use variables named like registers)
Effective addressesuse use square brackets

For people like me who also know assembler for other CPU's (e.g. Motorola 68k), the AT&T syntax feels more familiar, and fortunately the people who made the GNU assembler thought likewise. So I will use only AT&T syntax here.

Example 1 - Copy integer variable a to variable b

int b=0, a=12;
__asm__("movl %1, %%eax\n\t;"
	"movl %%eax, %0;"
	:"=r"(b)	/* output variable is b */
	:"r"(a)		/* input variable is a */
	:"%eax"		/* clobbered register - optional */
printf("a=%i, b=%i\n", a, b);

Example 2 - exit() syscall

asm("movl $1, %eax;"	/* SYS_exit is 1 */
	"xorl %ebx, %ebx;"	/* Argument is in ebx, it is 0 */
	"int $0x80"		/* enter kernel mode */

How to learn more

A possible way to learn more assembler (if you already are a good C programmer) is to look how C gets translated to assembler by the compiler:

gcc -O3 -S test.c

will produce test.s in gas-compatible format...