Da C ad ASM - Polinformatici

Transcript

Da C ad ASM - Polinformatici
Da C ad ASM AXO Matteo Guarnerio Da C ad ASM Glossario istruzioni e conversione C ASM int main(){ ORG ${addrnum} … } #define lbl var lbl: EQ/EQU {var/num} void dato = valore; void dato[num]; void * punt; dato: DC{.B/.W/.L} valore struct{ char c; int a; } s; s: DS.B 5 s.c: EQU 0 s.a EQU 1 dato: DS{.B/.W/.L} num punt: DS.L 1 Richiamo il #etichettavar{.B/.W/.L} nome di una variabile sopra definita. Utilizzo un #numero{.B/.W/.L} numero in un’operazione. … *addr; (AX) op2dest = op1 + op2dest; op2dest = op2dest – op1; op2dest = op1 * op2dest; dest = src; ADD{A/I} {op1} {op2dest} SUB{A/I} {op1} {op2dest} MULS{A/I} {op1} {op2dest} MOVE{A/I} {src} {dest} Descrizione Inizio del programma. Spazio occupato in bit 0 Equal è un define. lbl è l’etichetta. Dichiarazione variabile per valore. Dichiarazione variabile per spazio occupato. Dichiaro un puntatore e lo etichetto. Qualsiasi tipo di puntatore è equiparato all’intero. 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. Utilizzo il valore della variabile in un tipo di dato, long o word. 0 Immediato, è un numero definito nel codice. {8/16/32} Utilizzo il valore del dato al quale punta l’indirizzo. Somma due elementi e il risultato lo pone in op2dest. Sottrae due elementi e il risultato lo pone in op2dest. Moltiplica due elementi e il risultato lo pone in op2dest. Sposta contenuti. Con A si utilizza quando si copia un indirizzo in un registro diverso da A7 (Stack). MOVE è ortogonale, quindi 0 {8/16/32} {8/16/32}*num 32 8*5 = 40 {8/16/32} 16+SIZE(op1)+S
IZE(op2dest) 16+SIZE(op1)+S
IZE(op2dest) 16+SIZE(op1)+S
IZE(op2dest) 16+SIZE(src)+SI
ZE(dest) 1 Da C ad ASM AXO Matteo Guarnerio può lavorare direttamente in memoria. MOVEM {D1-­‐D3/A0}, -­‐(SP) Salvo i registri da D1 a D3 16 compreso A0 nello stack. MOVEM +(SP), {D1-­‐D3/A0-­‐A6} Salvo dallo stack ai registri. 16 Utilizzando la convenzione del chiamato salvo i registri prima della chiamata. if(…) CMP{A/I} {op1} {op2} Confronto tra elementi. 16+SIZE(op1)+S
op2 >= op1 IZE(op2) goto dest; JMP {dest} Salto incondizionato. 16+SIZE(dest) dest(); JSR {dest} Salto a Sub Routine. 16+SIZE(dest) if(…) B{T/F/NE/EQ/GT/LT/VC/VS/RA} Brench è un salto 16+SIZE(dest) then… {dest} 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. op = -­‐op; NEG{.L/.W} {op} Nega complementando a 2. 16+SIZE(op) {op} -­‐> -­‐1*{op} op = ~op; NOT{.L/.W} {op} Inversione bitwise. 16+SIZE(op) int *funz(int a, LINK FP, #-­‐{spazioritorno} Dichiarazione della funzione. 16+spazioritorn
int b){ Alloco spazio per l’area di o … attivazione della funzione. } Lo spazio di ritorno è dato dalla dimensione del dato da ritornare. spazioritorno = SIZE(int *) … UNLINK FP Libero l’area di attivazione 16 return; della funzione. } return; RTS Return Sub Routine. E’ il 16 } return della funzione (non il main). { } = 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). 2 Da C ad ASM AXO Matteo Guarnerio 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) 3 Da C ad ASM AXO Matteo Guarnerio 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){ f: LINK FP, #-­‐4 int a; q: EQU 8 int b; 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 Variabili locali. Spiazzamento: -­‐
4(FP) -­‐3 Nella posizione -­‐4 punta l’attuale Stack Pointer, -­‐2 A utilizzato nel LINK. Spiazzamento: -­‐2(FP) -­‐1 0 1 FP Frame Pointer 2 3 4 5 Indirizzo di ritorno Spiazzamento: +4(FP) 6 7 8 q Parametri passati ad Spiazzamento: +8(FP) 9 argomento della funzione, nell’ordine specificato dalla 10 p traccia 11 Spiazzamento: +10(FP) 4