Da C ad ASM AXO Matteo Guarnerio
1
Da C ad ASM
Glossario istruzioni e conversione
C ASM Descrizione Spazio
occupato in bit int main(){
… }
ORG ${addrnum} Inizio del programma. 0
#define lbl var lbl: EQ/EQU {var/num} Equal è un define.
lbl è l’etichetta. 0
void dato =
valore; dato: DC{.B/.W/.L} valore Dichiarazione variabile per
valore. {8/16/32}
void
dato[num]; dato: DS{.B/.W/.L} num Dichiarazione variabile per
spazio occupato. {8/16/32}*num
void * punt; punt: DS.L 1 Dichiaro un puntatore e lo etichetto.
Qualsiasi tipo di puntatore è equiparato all’intero.
32
struct{
char c;
int a;
} s;
s: DS.B 5 s.c: EQU 0 s.a EQU 1
5 è dato dalla somma delle dimensioni dei dati della struttura, c+a.
0 lo spiazzamento di c rispetto ad s.
1 lo spiazzamento di a rispetto a c.
8*5 = 40
Richiamo il nome di una variabile sopra definita.
#etichettavar{.B/.W/.L} Utilizzo il valore della variabile in un tipo di dato, long o word.
{8/16/32}
Utilizzo un numero in un’operazione.
#numero{.B/.W/.L} Immediato, è un numero
definito nel codice. {8/16/32}
… *addr; (AX) Utilizzo il valore del dato al
quale punta l’indirizzo. 0 op2dest = op1
+ op2dest; ADD{A/I} {op1} {op2dest} Somma due elementi e il
risultato lo pone in op2dest. 16+SIZE(op1)+S IZE(op2dest) op2dest =
op2dest – op1; SUB{A/I} {op1} {op2dest} Sottrae due elementi e il
risultato lo pone in op2dest. 16+SIZE(op1)+S IZE(op2dest) op2dest = op1
* op2dest; MULS{A/I} {op1} {op2dest} Moltiplica due elementi e il
risultato lo pone in op2dest. 16+SIZE(op1)+S IZE(op2dest) dest = src; MOVE{A/I} {src} {dest} Sposta contenuti. Con A si
utilizza quando si copia un indirizzo in un registro diverso da A7 (Stack).
MOVE è ortogonale, quindi
16+SIZE(src)+SI ZE(dest)
Da C ad ASM AXO Matteo Guarnerio
2
può lavorare direttamente in memoria.
MOVEM {D1-‐D3/A0}, -‐(SP) Salvo i registri da D1 a D3 compreso A0 nello stack.
16 MOVEM +(SP), {D1-‐D3/A0-‐A6} Salvo dallo stack ai registri.
Utilizzando la convenzione del chiamato salvo i registri prima della chiamata.
16
if(…) CMP{A/I} {op1} {op2} Confronto tra elementi.
op2 >= op1 16+SIZE(op1)+S
IZE(op2)
goto dest; JMP {dest} Salto incondizionato. 16+SIZE(dest)
dest(); JSR {dest} Salto a Sub Routine. 16+SIZE(dest)
if(…) then…
B{T/F/NE/EQ/GT/LT/VC/VS/RA}
{dest}
Brench è un salto condizionato.
T = True; F = False; Not Equal;
EQ = Equal; GT = Greater, maggiore; LT = Less, minore;
VC = Overflow clear; VS = Overflow set; RA = Salta sempre, uguale ad utilizzare JMP.
16+SIZE(dest)
op = -‐op; NEG{.L/.W} {op} Nega complementando a 2.
{op} -‐> -‐1*{op} 16+SIZE(op)
op = ~op; NOT{.L/.W} {op} Inversione bitwise. 16+SIZE(op)
int *funz(int a, int b){
… }
LINK FP, #-‐{spazioritorno} Dichiarazione della funzione.
Alloco spazio per l’area di attivazione della funzione.
Lo spazio di ritorno è dato dalla dimensione del dato da ritornare.
spazioritorno = SIZE(int *)
16+spazioritorn o
… return;
}
UNLINK FP Libero l’area di attivazione
della funzione. 16
return;
}
RTS Return Sub Routine. E’ il
return della funzione (non il main).
16
{ } = Parametro da sostituire
Dimensioni:
Byte = 8 bit
Word = 16 bit = 2 Byte Long = 32 bit = 4 Byte
L’ASM di default utilizza la Word per le istruzioni che consentono di specificare il tipo di dato.
Gli indirizzi solitamente occupano 16bit (è specificato all’inizio del testo
nell’architettura della macchina).
Da C ad ASM AXO Matteo Guarnerio
3
Spazio occupato dai tipi di dato:
char = 1 Byte short int = 2 Byte int = 4 Byte
long int = 8 Byte (Non c’è in ASM 68000)
Registri ASM:
A0-‐A7; D0-‐D7
A6 = FP = Frame Pointer A7 = SP = Stack Pointer Non occupano spazio in bit.
I registri A sono utilizzati per gli indirizzi e i D per i dati (scalari).
SR = State Registry. E’ composto da 11 bit per il dato e 4 bit di esito: C = riporto, V = Carry; Z = zero; N = negativo; X = estensione.
PC = Program Counter. Memorizza l’indirizzo dell’istruzione corrente del programma.
Suffissi istruzioni ASM:
.B = Byte .W = Word .L = Long
I = Immediato (Numero definito direttamente nel sorgente) A = Address (Indirizzo)
Da C ad ASM AXO Matteo Guarnerio
4
Inizializzazione Sub Routine
Il valore in uscita dal return della sub routine va sovrascritto sull’ultimo elemento passato come argomento alla funzione.
Per allocare lo spazio nell’area di attivazione, sommare lo spazio degli argomenti della funzione e delle variabili locali.
Quando utilizzo variabili locali della funzione, quindi sia presenti nel prototipo che all’interno della funzione, devo utilizzarle con lo spiazzamento relativo a FP (Esempio:
p(FP) )
Esempio:
Si ipotizzano indirizzi da 32 bit, interi da 16 bit e parametri passati alla funzione sulla pila in ordine inverso di elencazione del prototipo.
int f (int p, int q){
int a;
int b;
… }
f: LINK FP, #-‐4 q: EQU 8 p: EQU 10 a: EQU -‐2 b: EQU -‐4 … // elabora
… // sovrascrive il valore di ritorno in q UNLINK FP
RTS Allocazione nello stack:
Byte/Indirizzo Dato Descrizione
-‐4 B
Spiazzamento: -‐4(FP) Variabili locali.
Nella posizione -‐4 punta l’attuale Stack Pointer,
utilizzato nel LINK.
-‐3
-‐2 A
Spiazzamento: -‐2(FP) -‐1
0
FP Frame Pointer
1 2 3 4
Indirizzo di ritorno
Spiazzamento: +4(FP)
5 6 7
8 q
Spiazzamento: +8(FP) Parametri passati ad argomento della funzione, nell’ordine specificato dalla
traccia 9
10 p
Spiazzamento: +10(FP) 11