Solitamente, nel mondo MS-DOS e Windows si usa la sintassi Intel per la scrittura di programmi assembly, e tipicamente è anche quella che viene insegnata nelle scuole tecniche (almeno nel mio caso).
Chi però entra nel mondo *nix, si ritrova a dover usare la sintassi AT&T. Anche se questo non è del tutto vero (quasi tutti i tool moderni permettono di specificare l’una o l’altra sintassi), conoscere anche questa sintassi non fa male 😉

Le differenze con la sintassi Intel non sono molte, ma importanti:

  • L’operando sorgente e la destinazione sono invertite, cioè per scrivere “ax ← bx”:
    Intel AT&T
    mov ax, bx mov %bx, %ax
  • Davanti ai nomi dei registri bisogna porre un %, davanti ai dati immediati (costanti) un $, e i valori esadecimali sono preceduti da “0x” (come in C)
    Intel AT&T
    ax %ax
    ebx %ebx
    23 $23
    147h $0x147
  • Se un’istruzione indicizza un’operando in memoria, bisogna specificare la dimensione del dato su cui si sta lavorando aggiungendo alla fine dell’opcode, “b”, “w”, “l”, rispettivamente per dati da 8, 16 o 32 bit. (es. movb, addw, xorl)
  • Per indicare le modalità di indirizzamento, la sintassi Intel usa questa struttura: [base + index*scale + disp] , mentre la AT&T usa disp(base, index, scale).

Ecco un po’ di esempi per chiarire le idee:

Intel AT&T
mov eax,1 movl $1,%eax
mov ebx,0ffh movl $0xff,%ebx
int 80h int $0x80
mov ebx, eax movl %eax, %ebx
mov eax,[ecx] movl (%ecx),%eax
mov eax,[ebx+3] movl 3(%ebx),%eax
mov eax,[ebx+20h] movl 0x20(%ebx),%eax
add eax,[ebx+ecx*2h] addl (%ebx,%ecx,0x2),%eax
lea eax,[ebx+ecx] leal (%ebx,%ecx),%eax
sub eax,[ebx+ecx*4h-20h] subl -0x20(%ebx,%ecx,0x4),%eax