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 %eax
foo
non può utilizzare il registro %ebx
baz
non può utilizzare il registro %eax
baz
non può utilizzare il registro %ebx
baz
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 ret
baz
può utilizzare %edx
senza dover preservare il suo contenuto inizialefoo
deve salvare il contenuto di %ecx
se vuole preservarne il contenuto prima di chiamare baz
foo
deve salvare il contenuto di %esi
se vuole presevarne il valore prima di chiamare baz
setl %eax
setba %al
leal (%eax, %edx, 6), %ecx
movl (%eax), 4(%esp)
leal -1(%ecx), %eax
addl %eax, $4
%eax=0x0000BEEF
, quanto vale %ecx
dopo aver eseguito l’istruzione movsbw %al, %cx
?
0x000000EF
0xFFFFFFEF
0x0000FFEF
0x0000EFEF
Se %ecx=0
, qual è il valore di %al
dopo le istruzioni testl %ecx, %ecx
e setge %al