vuoi
o PayPal
tutte le volte che vuoi
Bit di stato:
• CF (bit 0): 1 quando il risultato ha determinato riporto (carry)
• PF (bit 2): 1 quando il risultato ha un numero pari di 1
• AF (bit 4): 1 quando il risultato ha determinato riporto intermedio sul bit 3
• ZF (bit 6): 1 quando il risultato è zero
• SF (bit 7): bit segno, 1 quando il risultato è negativo
• OF (bit 11): 1 quando il risultato ha causato overflow con operazioni in aritmetica intera con
segno (complemento a 2)
Modalità di indirizzamento:
movl $0x10,%eax # immediato (eAx = 0x10)
movl 0x100,%eax # diretto o assoluto (eAx = mem[0x10])
movl %ebx,%eax # di un registro (eAx = eBx)
movl (%ebx),%eax # indiretto ( eAx = mem[eBx])
movl -2(%ecx),%eax # indiretto con indice (eAx = mem[ecx-2])
Lo stack – struttura dati sequenziale
- i dati vengono aggiunti (per memorizzarli) e rimossi (per leggerli).
- le operazioni sullo stack sono Push (aggiungi in “testa”), Pop (rimuovi dalla “testa”).
- eSP è detto stack pointer ed indica l'indirizzo in “testa”.
- eBP è detto base pointer ed indica l'indirizzo base di una procedura.
Schema:
ordine Dati → top dello stack
.
/|\ 1° 11EC
| 2° 01CC
| 3° 01CC
| 4° 0CF0 → “testa” della pila
%eSP
Esercizi 6502– Spiegati
Considerazioni generali:
Si inizia sempre con:
.Text
.Global _NomeFunzione
_NomeFunzione:
PUSH %eBP
MOVL %eSP, %eBP
Si finisce sempre con:
MOVL %eBP, %eSP
POPL %eBP
RET
ES: 1)
int f (int x, int y) {
return g (X+2, Y-4);
}
.Text
.Global _f
_f:
PUSHL %eBP Y
MOVL %eSP, %eBP X
Indicano entrambi la 1*
SUBL $8, %eSP RET eBP
eSP indica la 3* Y – 4 1*
MOVL 8(%eBP), %eAx X + 2 2* eSP
eBP + 8 = X → eAx
PUSHL %eAx 3*
mette il valore di X in cima allo stack (3*)
MOVL $2, %eAx eAx = 2
POPL %eBx mette il valore in cima allo stack in eBx
ADDL %eBx, %eAx eAx = eAx + eBx = (X+2)
MOVL %eAx, 4(%eSP) metto in 2* il valore di eAx
MOVL 12(%eBP), %eAx eBP + 12 = Y → eAx
PUSHL %eAx mette il valore di Y in cima allo stack (3*)
MOVL $4, %eAx eAx = 4
MOVL %eAx, %eBx eBx = 4
POPL %eAx eAx = 3* = Y
SUBL %eBx, %eAx eAx = eAx – eBx = (Y – 4)
MOVL %eAx, 8(%eSP) metto in 1* il valore di eAx
CALL _g
ADDL $4, %eSP eSP punta a 2* (non ne capisco il senso)
MOVL %eSP, %eBP eSP e eBP puntano entrambi a 1*
POPL %eBP
RET
MOVL $0, %eAx EAx = 0
MOVL %eBP, %eSP
POPL %eBP
RET
ES: 2)
int fatt (int n) {
if (n <= 1)
return 1;
return h*fatt (n-1); }
.Text
.Global _fatt
_fatt: PUSHL %eBP
MOVL %eSP, %eBP n
Indicano entrambi la 1* RET eBP, eSP
MOVL 8(%eSP), %eAx 1*
eAx = n
PUSHL %eAx 2*
1* = n, eSP punta a 2*
MOVL $1, $eAx 3*
eAx = 1
MOVL %eBx 4*
CMPL %eAx, %eBx 5*
Salta se eBx = eAx
JLE T1 6*
MOVL $0, %eBx eBx=0
JMP U1 Salto incondizionato
T1 MOPL $1, %eAx
U1 CMPL $0, %eAx Salta se 0 = eAx
JE E1
MOVL $1, %eAx eAx = 1
MOVL %eBP, %eSP
POPL %eBP
RET
E1 MOVL 8(%eBP), %eAx eAx = n
PUSHL %eAx Metto n in cima allo stack
MOVL 8(%eBP), %(eAx) eAx = n
PUSHL %eAx Metto n in cima allo stack
MOVL $1, %eAx eAx = 1
MOVL %eAx, %eBx eBx = 1
POPL %eAx eAx = Val in cima allo stack
SUBL %eBx, %eAx eAx = eAx – eBx = n – 1
PUSHL %eAx Metto “n - 1” in cima allo stack
CALL _FATT
POPL %eAx eAx = val in cima allo stack
POPL %eBx eBx = val in cima allo stack
IMULL %eBx, %eAx eAx = eAx * eBx
MOVL %eBP, %eSP
POPL %eBP
RET
MOVL $0, %eAx
MOVL %eBP, %eSP
POPL %eBP