Da C ad assembly
Conversione di un programma da C ad assembly
Data: April 18, 2021, 10:50 PM
Tags: Calcolatori
Programma in C da convertire
#include <iostream>
int FIB (int n) {
if (n == 0)
return 0;
else if (n < 2)
return 1;
else
return (FIB(n-1) + FIB(n-2)); // chiamo più volte FIB e ogni volta ho bisogno di salvare l'indirizzo di ritorno
}
/*int main () {
int n=5;
bool condotion = true;
while (condition) {
FIB (n);
n-=1;
condition = (n>=0) ? false : true;
}
return 0;
}*/
Gestione del registro di ritorno
$ra contiene sempre l'indirizzo di ritorno (unico per questo scopo). Con la chiamata più volte di FIB, sovrascrivo ogni volta il valore di $ra, perdendo quello precedente. Ciò riguarda qualunque altro registro che riutilizzo, andando a sovrascrivere il nuovo al vecchio. Come faccio a non perdere il contenuto? → Uso la memoria.
Devo preoccuparmi di non perdere il valore di un registro prima di sovrascriverlo. Per fare ciò, devo salvarlo/copiarlo da qualche parte (ovvero in memoria, in particolare in una cella riservata a salvare quel dato).
Convenzione per funzioni ricorsive
Si usa non la memoria in generale ma lo stack, zona di memoria "a pila".
FIB:
addi $sp, $sp, -12 # alloco lo stack
sw $ra, 8($sp) # salvo return address
sw $a0, 4($sp) # salvo n
sw $s1, 0($sp) # salvo risultato parziale
# FIB definita nel suo funzionamento
All'inizio, decremento lo stack pointer di 12 in quanto sto utilizzando tre valori da 4 Byte l'uno, ovvero 12 Byte. Devo, dunque, spostare l'indirizzo iniziale dello stack di 12 posizioni (in basso perché lo stack è una pila verso il basso). Con gli sw, salvo nelle varie zone dello stack i valori dei registri che voglio preservare. Questo è da fare all'inizio della funzione ricorsiva, per preservare i valori ogni volta.
Condizioni e salti
IF:
bgtz $a0, ELSEIF # branch -> salto a ELSEIF se n>0
add $v0, $zero, $zero # metto dentro a $v0 il valore 0 se n==0 (ovvero, se n==0 ritorna 0)
j END # mi aspettavo jr $ra -> salto all'indirizzo corrispondente al valore contenuto in $ra
# questo, invece, è sempre un salto incondizionato ma a un'etichetta specifica (END). Infatti, devo ripristinare $ra
ELSEIF:
slti $t0, $a0, 2 # set $t0 <-- 1 se $a0<2
beq $t0, $zero, ELSE # se $t0==0 salta a ELSE condizionatamente (ovvero se n>=2)
addi $v0, $zero, 1 # se n==1 ritorna 1
j END
L'uso dello stack consente di gestire correttamente l'indirizzo di ritorno ($ra) e altri registri che devono essere preservati tra le chiamate di funzioni ricorsive.
-
Conversione
-
Conversione AD-DA
-
Conversione Statica dell'Energia - Riassunti
-
Conversione Statica dell'energia