uniroma1.*_main.c.cognome.nome. Sulle postazioni del laboratorio sarà /home/studente/Desktop/cognome.nome/.cognome.nome.zip (zip -r cognome.nome.zip cognome.nome/).cognome.nome.zip.E1/e1_eq.c equivalente a quella di partenza, ma più semplice da tradurre in assembly. Testatela con il main di prova prima di passare a scrivere la versione .s. E’ inutile tradurre la versione C equivalente se è errata!Per maggiori informazioni fate riferimento al regolamento delle esercitazioni.
Tradurre nel file E1/e1.s la seguente funzione C contenuta in E1/e1.c che calcola i numeri di Fibonacci:
int fib(int n) {
if (n<2) return 1;
return fib(n-1)+fib(n-2);
}
Usare il main di prova nella directory di lavoro E1 compilando con gcc -m32 e1_main.c e1.s -o e1.
Tradurre nel file E2/e2.s la seguente funzione C contenuta in E2/e2.c che, dati due array di short, conta il numero di indici per cui gli array hanno lo stesso valore:
int counteq(short* v1, short* v2, int n) {
int i, cnt = 0;
for (i=0; i<n; ++i) cnt += (v1[i]==v2[i]);
return cnt;
}
Suggerimento: usare le istruzioni SETcc e MOVZ/MOVS.
Usare il main di prova nella directory di lavoro E2 compilando con gcc -m32 e2_main.c e2.s -o e2.
Tradurre nel file E3/e3.s la seguente funzione C contenuta in E3/e3.c che clona un blocco di memoria di n byte all’indirizzo src.
Il nuovo blocco deve essere allocato con malloc e deve avere lo stesso contenuto del blocco src. Sarà compito del chiamante di clone deallocare il blocco di memoria allocato da clone.
#include <stdlib.h>
#include <string.h>
void* clone(const void* src, int n) {
void* des = malloc(n);
if (des==0) return 0;
memcpy(des, src, n);
return des;
}
Suggerimento: per copiare i dati src al nuovo blocco si suggerisce di usare la funzione memcpy. Si noti che è possibile chiamare funzioni di libreria C con call come se fossero normali funzioni scritte dall’utente.
Usare il main di prova nella directory di lavoro E3 compilando con gcc -m32 e3_main.c e3.s -o e3.
NOTA: in caso di errore in fase di linking su memcpy per via di PIE, usare gcc -m32 e3_main.c e3.s -o e3 -no-pie
Scrivere nel file E4/e4.c una funzione C drop_spaces che, data una stringa text, elimina tutti gli spazi.
void drop_spaces(char* text);
Usare il main di prova nella directory di lavoro E4 compilando con gcc e4_main.c e4.c -o e4.
foo ha un prologo in cui vengono salvati due registri callee-save e vengono riservati 12 byte per ospitare variabili locali, argomenti ed eventuale padding, quale di questi operandi permette di accedere al secondo argomento di foo?
(%esp)4(%esp)8(%esp)12(%esp)20(%esp)24(%esp)28(%esp)32(%esp)%al = 5, eseguire movsbl %al, %eax porta allo stesso risultato in %eax rispetto eseguire movzbl %al, %eax?
foo che chiama una funzione baz. Quale tra le seguenti affermazioni risulta essere vera:
foo non può utilizzare il registro %eaxfoo non può utilizzare il registro %ebxbaz non può utilizzare il registro %eaxbaz non può utilizzare il registro %ebxbaz viene chiamata da una funzione foo, quale delle seguenti affermazioni risulta essere falsa:
baz prima di poter utilizzare %edi deve salvare il suo contenuto e ripristinarlo prima di effettuare la retbaz può utilizzare %edx senza dover preservare il suo contenuto inizialefoo deve salvare il contenuto di %ecx se vuole preservarne il contenuto prima di chiamare bazfoo deve salvare il contenuto di %esi se vuole presevarne il valore prima di chiamare bazsetl %eaxsetba %alleal (%eax, %edx, 6), %ecxmovl (%eax), 4(%esp)leal -1(%ecx), %eaxaddl %eax, $4%eax=0x0000BEEF, quanto vale %ecx dopo aver eseguito l’istruzione movsbw %al, %cx?
0x000000EF0xFFFFFFEF0x0000FFEF0x0000EFEFSe %ecx=0, qual è il valore di %al dopo le istruzioni testl %ecx, %ecx e setge %al