Esercitazione del 22 Dicembre 2010
Es 1
INT i = 0 INT j = 0 CHAR S[256];
INT OUT;
WHILE (1) {
i = (i+1)&0xFF j = j + S[i]&FF
S[i]=S[i]^S[j] // ^ = XOR S[j]=S[j]^S[i]
S[i]=S[i]^S[j]
OUT=S[(S[i]+S[j])&0xFF]
}
Traduzione
Code EQ 0 Code EQ 1 SECTION DATA ORG $ 1000
I DC.L 0 //4
J DC.L 0 //4
S DS.B 256 //100
OUT DS.L 1 //4. Totale 10 C SECTION CODE
ORG $ 110C
CICLO MOVE.L 1, D0 //Assegnamento i = (i+1)&0xFF ADD 1.L #1,D0
ANDI.L #255,D0 MOVE.L D0,1
MOVEA.L #S,A0//Assegnamento j = j + S[i]&FF MOVE.L J,D1
MOVE.B (A0, D0),D2 // Caricamento di S[i]
ADD.L D2,D1 ANDI.L #255,D1 MOVE.L D1,J
MOVE.B (A0,D1),D3 // Caricamento di S[j]
XOR.B D3,D2 XOR.B D2,D3 XOR.B D3,D2
MOVE.B D2, (A0,D0) //Calcolo dell’indice della OUT MOVE.B D3, (A0,D1)
MOVE.B D2, D4 ADD.L D3, D4 ANDI.L #255, D4 MOVE.B (A0, D4), D5 MOVE.B D5, OUT BRA CICLO MOVEI.B #9, D0 TRAP #15
END CICLO
Allocazione pila
BRA 0X2B2B .
. . . . .
RFS // Torna al program counter che ha salvato in fondo allo Stack Pointer
0x000 CODE
PC 0XFF
I parametri vanno sullo stack.
INT f(INT P)
MOVE.L D0, -(A7) //questo è l’equivalente della push MOVE.L (A7)+, D0 //questo è l’equivalente della pop CODE
D0 PC
MOVEM.L D0-D4/A0-A1, -(A7) //salva tutti i registri tra D0 e D4 e A0, A1 sullo stack
MOVEM.L (A7)+, D0-D4/A0-A1 //inversa Ricordarsi che lo stack cresce al contrario.
Attenzione alle chiamate ricorsive. Lo stack completo sarà così TEMP n-CALL
REG SALVATI
FP (punta al FP sotto) RET P
PARAM TEMP (n-1) REG (n-2)
FP (punta FP della n-2esima chiamata) RET P
PARAM (n-1)
Convenzione per ordinamento parametri
Es INT f(INT p, INT q) nello stack carico prima q e poi p, ovvero leggendo dall’alto verso il basso trovo prima p poi q
Es 2
INT G(VOID);
INT F(INT P, INT Q, INT R) { IF(P >= Q) {
RETURN F(Q, P-Q, G())+R } ELSE {
RETURN – 1 }
}
Scrivere la code section di questo oggetto
Traduzione
F: LINK A6,#0 //A6 = FP (frame pointer) P: EQU +8 //P
Q: EQU +12 //Q R: EQU +16 //R
MOVEM DO-D7, (-A7) MOVE.L P(A6),D0 MOVE.L Q(A6),D1 CMD D1, D0 BLT ELSE
/* Inizio a calcolare la prima Return, prima di chiamare G, siccome c’è un Int che va restituito e non ho lo spazio per metterlo, creo lo spazio */
SUBA.L #1 //Spazio per G() BSR G
MOVE.L P(A6),D2 MOVE.L Q(A6),D3 SUB.L D2,D3
MOVE.L D3, -(A7) //Carico P-q MOVE.L D1, -(A7) //Spazio per Q
BSR F //NB, dopo il return avrò lo SP sopra due parametri non usati ADDA.L #2, A7 //Pop del valore di F
MOVE.L (A7)+, D4
MOVE.L R(A6), D5 //R è lo spiazzamento
ADD.L D4, D5 /* Devo mettere il risultato della somma nel primo parametro impilato */
MOVE.L D5, R(A6) MOVEM (A7)+, D0-D7 UNLINK
RFS
ELSE MOVE.L #-1, R(A6) MOVEM (A7)+, D0-D7 UNLINK
RFS
Es 3: Albero sintattico
E’ il modo di rappresentare le precedenze.
F ( q, p-q, g() ) + R
I nodi sono i registri temporanei che uso nell’assembly