Sto cercando di familiarizzare con l'assembly x86 utilizzando l'assemblatore inline di GCC. Sto cercando di aggiungere due numeri (a
e b
) e memorizzare il risultato in c
. Ho quattro tentativi leggermente diversi, tre dei quali funzionano; l'ultimo non produce il risultato atteso.Aggiunta di due numeri
I primi due esempi utilizzano un registro intermedio e entrambi funzionano correttamente. Il terzo e il quarto esempio cercano di aggiungere i due valori direttamente senza il registro intermedio, ma i risultati variano a seconda del livello di ottimizzazione e dell'ordine in cui aggiungo i valori di input. Cosa sto sbagliando?
Ambiente è:
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
In primo luogo, le variabili sono dichiarate come segue:
int a = 4;
int b = 7;
int c;
Esempio 1:
asm(" movl %1,%%eax;"
" addl %2,%%eax;"
" movl %%eax,%0;"
: "=r" (c)
: "r" (a), "r" (b)
: "%eax"
);
printf("a=%d, b=%d, c=%d\n", a, b, c);
// output: a=4, b=7, c=11
Esempio 2:
asm(" movl %2,%%eax;"
" addl %1,%%eax;"
" movl %%eax,%0;"
: "=r" (c)
: "r" (a), "r" (b)
: "%eax"
);
printf("a=%d, b=%d, c=%d\n", a, b, c);
// output: a=4, b=7, c=11
Esempio 3:
asm(" movl %2,%0;"
" addl %1,%0;"
: "=r" (c)
: "r" (a), "r" (b)
);
printf("a=%d, b=%d, c=%d\n", a, b, c);
// output with -O0: a=4, b=7, c=11
// output with -O3: a=4, b=7, c=14
Esempio 4:
// this one appears to calculate a+a instead of a+b
asm(" movl %1,%0;"
" addl %2,%0;"
: "=r" (c)
: "r" (a), "r" (b)
);
printf("a=%d, b=%d, c=%d\n", a, b, c);
// output with -O0: a=4, b=7, c=8
// output with -O3: a=4, b=7, c=11
risolto.Matthew Slattery's answer è corretto. Prima, stava cercando di riutilizzare eax
sia per b
e c
:
movl -4(%rbp), %edx
movl -8(%rbp), %eax
movl %edx, %eax
addl %eax, %eax
Con correzione suggerito di Matteo in luogo, esso utilizza ora ecx
per tenere c
separatamente.
movl -4(%rbp), %edx
movl -8(%rbp), %eax
movl %edx, %ecx
addl %eax, %ecx
Funziona bene per me, con o senza ottimizzazione abilitata. Prova a compilare con -S, per ottenere un elenco di linguaggio assembly. Quindi puoi vedere quali registri vengono utilizzati. – TonyK
Ho appena notato che ottengo risultati diversi a seconda del livello di ottimizzazione. Campioni di codice aggiornati con nuovo output. –
Allora, cosa ti dice la lista di montaggio? – TonyK