Istruzioni di controllo del flusso

Documenti analoghi
Istruzioni di trasferimento dati

Il set istruzioni di MIPS Modalità di indirizzamento. Proff. A. Borghese, F. Pedersini

Il set istruzioni di MIPS Modalità di indirizzamento. Proff. A. Borghese, F. Pedersini

Istruzioni assembler Istruzione N Registri

Le etichette nei programmi. Istruzioni di branch: beq. Istruzioni di branch: bne. Istruzioni di jump: j

Architettura degli Elaboratori

Linguaggio assembler e linguaggio macchina (caso di studio: processore MIPS)

Riassunto. Riassunto. Ciclo fetch&execute. Concetto di programma memorizzato. Istruzioni aritmetiche add, sub, mult, div

Calcolatori Elettronici Prof. Fabio Roli. Linguaggio Assembly. Capitolo 5. Corso di Laurea di Ingegneria Elettronica

Linguaggio macchina. Architettura degli Elaboratori e delle Reti. Il linguaggio macchina. Lezione 16. Proff. A. Borghese, F.

Calcolatori Elettronici

Il linguaggio macchina

Esercitazione di Calcolatori Elettronici Ing. Battista Biggio. Corso di Laurea in Ingegneria Elettronica. Capitolo 5 Linguaggio Assembly

Lezione 20. Assembly MIPS: Il set istruzioni, strutture di controllo in Assembly

Lezione 12. Assembly II. Set di Istruzioni MIPS Strutture di controllo in Assembly

Università degli Studi di Cassino

Corso di Calcolatori Elettronici MIPS: Istruzioni di confronto Istruzioni di controllo Formato delle istruzioni in L.M.

Richiami sull architettura del processore MIPS a 32 bit

Richiami sull architettura del processore MIPS a 32 bit

Il linguaggio assembly

ISA (Instruction Set Architecture) della CPU MIPS

Lezione 20. Assembly MIPS: Il set istruzioni, strutture di controllo in Assembly

L'architettura del processore MIPS

Istruzioni MIPS per floating point

Sommario Introduzione al linguaggio Assembly. Calcolatori Elettronici Prof. Gian Luca Marcialis. Le operazioni fondamentali

Transcript:

Istruzioni di controllo del flusso Il flusso di esecuzione è normalmente sequenziale Le istruzioni di controllo cambiano la prossima istruzione da eseguire Istruzioni di salto condizionato branch if equal beq $s4, $s5, LABEL branch if not equal bne $s6, $s5, LABEL Esempio if (i == j) i = i + j;... bne $s4, $s5, LABEL add $s4, $s4, $s5 LABEL:... Formato I-Type (operando immediato relativo a PC)

Istruzioni di controllo del flusso Salto non condizionato Esempio j LABEL if (i!= j) h = i + j; else h = i j;... beq $s4, $s5, ELSE add $3, $4, $5 j EXIT ELSE: sub $3, $4, $5 EXIT:... Formato J-Type op 26-bit constant

Istruzioni di controllo del flusso Come facciamo a esprimere Salta se minore o uguale di? In MIPS c è un istruzione aritmetica, set-on-less-than Istruzione Significato slt $t1, $s4, $s5 if ($s4 < $s5) $t1 = 1; else $t1 = 0; Formato R-Type / I-Type (versione immediata)

Esempio: Ciclo Tradurre il seguente codice C in codice assembly: while (save[i] == k) i += 1; i e k sono, rispettivamente, in $s3 e $s5 e la base dell array save è in $s6 Loop: sll $t1, $s3, 2 # Moltiplico i per 4 add $t1, $t1, $s6 # Calcolo l indirizzo di save[i] lw $t0, 0($t1) # Carico save[i] in $t0 bne $t0, $s5, Exit # Condizione di uscita dal ciclo addi $s3, $s3, 1 # Corpo del ciclo j Loop # Ricomincio Exit:

Procedure Per eseguire una procedura (detta callee, chiamato), un programma (detto caller, chiamante) deve eseguire 6 passi: 1. mettere i parametri in un luogo accessibile alla procedura 2. trasferire il controllo alla procedura 3. acquisire le risorse necessarie per l esecuzione della procedura 4. eseguire il compito richiesto 5. mettere il risultato in un luogo accessibile al chiamante 6. restituire il controllo al chiamante

Registri MIPS I 32 registri MIPS sono partizionati come segue: Reg 0 : $zero memorizza sempre la costante 0 Regs 2-3 : $v0, $v1 valori di ritorno di una procedura Regs 4-7 : $a0-$a3 valori di ingresso di una procedura Regs 8-15 : $t0-$t7 registri temporanei Regs 16-23 : $s0-$s7 registri variabili Regs 24-25 : $t8-$t9 altri registri temporanei Reg 28 : $gp global pointer Reg 29 : $sp stack pointer Reg 30 : $fp frame pointer Reg 31 : $ra return address

Jump-and-Link Un registro speciale contiene l indirizzo dell istruzione correntemente eseguita questo registro è il program counter (PC) L invocazione della procedura è eseguita invocando l istruzione jump-andlink (jal) Il valore corrente di PC (in realtà PC+4) è salvato nel registro $ra Si salta all indirizzo iniziale della procedura specificato come parametro dell istruzione jal Poiché jal potrebbe sovrascrivere un valore pre-esistente di $ra, questo deve essere salvato in memoria prima di invocare l istruzione jal Tramite l istruzione jump-register (jr) si ripristina il flusso di controllo del chiamante al termine della procedura Cosa succede se i registri $a0-$a3 e $v0, $v1 non sono sufficienti?

Stack Bisogna copiare il contenuto dei registri in memoria La struttura dati utilizzati è lo stack (pila), una coda di tipo LIFO (lastin first-out) utilizzata per salvare il contenuto dei registri Per ragioni storiche, lo stack cresce verso indirizzi di memoria bassi L indirizzo dell elemento dello stack allocato più di recente è memorizzato nello stack pointer ($sp) Inserendo dati nello stack (push), il valore di $sp diminuisce Estraendo dati dallo stack (pop), il valore di $sp aumenta Per convenzione, il contenuto dei registri $s0-$s7 deve essere salvato sullo stack prima dell invocazione di una procedura

Gestione dei dati dello stack Una nuova procedura deve creare spazio per tutte le sue variabili sullo stack Prima di eseguire la jal, il chiamante deve salvare i valori necessari dei registri $s0-$s7, $a0-$a3 e $ra nel suo stack Gli argomenti sono copiati in $a0-$a3 e l istruzione jal è eseguita Il chiamato può creare il suo spazio stack, aggiornando il valore di $sp Al termine dell invocazione, il chiamato copia il valore di ritorno in $v0 e libera lo stack se lo ha occupato Il chiamante può recuperare dallo stack i suoi valori precedentemente salvati ($s0-$s7, $a0-$a3 e $ra)

Esempio int leaf_example (int g, int h, int i, int j) { int f; f = (g + h) (i + j); return f; } indirizzi alti $sp Memoria leaf_example: addi $sp, $sp, -4 sw $s0, 0($sp) add $t0, $a0, $a1 add $t1, $a2, $a3 sub $s0, $t0, $t1 add $v0, $s0, $zero lw $s0, 0($sp) addi $sp, $sp, 4 jr $ra indirizzi bassi

Nuovi dati delle procedure

Codici ASCII load byte: lb $t0, 0($sp) store byte: sb $t0, 0($sp)

Esempio void strcpy(char x[], char y[]) { int i; i = 0; while ((x[i] = y[i])!= `\0 ) i += 1; } strcpy: addi $sp, $sp, -4 sw $s0, 0($sp) add $s0, $zero, $zero L1: add $t1, $s0, $a1 lb $t2, 0($t1) add $t3, $s0, $a0 sb $t2, 0($t3) beq $t2, $zero, L2 addi $s0, $s0, 1 j L1 L2: lw $s0, 0($sp) addi $sp, $sp, 4 jr $ra

Grandi costanti Le istruzioni immediate possono specificare solo costanti su 16 bit L istruzione lui è usata per copiare costanti a 16 bit nei 16 bit più significativi di un registro Combinando questa istruzione con un ori (OR immediato) possiamo copiare costanti a 32 bit

Grandi costanti Le istruzioni immediate possono specificare solo costanti su 16 bit L istruzione lui è usata per copiare costanti a 16 bit nei 16 bit più significativi di un registro Combinando questa istruzione con un ori (OR immediato) possiamo copiare costanti a 32 bit Nei salti condizionati (beq, bne) l indirizzo di salto (nuovo valore di PC) è una costante a 16 bit, relativa al valore corrente di PC Nel salto (j) l indirizzo di salto è una costante a 26 bit, di valore assoluto Se necessario, possiamo usare il contenuto di un altro registro come base

Metodi di indirizzamento del MIPS 1. Indirizzamento immediato: l operando è una costante contenuta nell istruzione 2. Indirizzamento tramite registro: l operando è in un registro 3. Indirizzamento tramite base e spiazzamento: l operando è in una cella di memoria individuata sommando il contenuto di un registro con una costante contenuta nell istruzione 4. Indirizzamento relativo a PC: l indirizzo di salto è ottenuto sommando il contenuto di PC con una costante contenuta nell istruzione 5. Indirizzamento pseudodiretto: l indirizzo di salto è ottenuto concatenando i 26 bit nell istruzione con i 4 bit più significativi di PC

Esercizio: scambia void scambia(int v[], int k) { int tmp; tmp = v[k]; v[k] = v[k+1]; v[k+1] = tmp; } 1. Allocazioni dei registri: due parametri e una variabile locale v $a0 k $a1 tmp $t0

Esercizio: scambia void scambia(int v[], int k) { int tmp; tmp = v[k]; v[k] = v[k+1]; v[k+1] = tmp; } 2. Calcolo indirizzo di memoria di v[k] sll $t1, $a1, 2 # registro $t1 = k * 4 add $t1, $a0, $t1 # registro $t1 = v + (k * 4) # il registro $t1 contiene # l'indirizzo di v[k]

Esercizio: scambia void scambia(int v[], int k) { int tmp; tmp = v[k]; v[k] = v[k+1]; v[k+1] = tmp; } 3. Caricare v[k] e v[k+1] dalla memoria: lw $t0, 0($t1) lw $t2, 4($t1) # registro $t0 (tmp) = v[k] # registro $t2 = v[k+1]

Esercizio: scambia void scambia(int v[], int k) { int tmp; tmp = v[k]; v[k] = v[k+1]; v[k+1] = tmp; } 4. Scambiare $t0 e $t2 e memorizzarli sw $t2, 0($t1) # v[k] = $t2 sw $t0, 4($t1) # v[k+1] = $t0 (tmp)

Esercizio: scambia void scambia(int v[], int k) { int tmp; tmp = v[k]; v[k] = v[k+1]; v[k+1] = tmp; } scambia: sll $t1, $a1, 2 add $t1, $a0, $t1 lw $t0, 0($t1) lw $t2, 4($t1) sw $t2, 0($t1) sw $t0, 4($t1) jr $ra Dato che non vengono utilizzati registri di tipo $s ed essendo scambia una procedura foglia, non dobbiamo salvare il contenuto di nessun registro