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.rm -rf cognome.nome).Per maggiori informazioni fate riferimento al regolamento delle esercitazioni.
Tradurre nel file E1-mystrcmp/e3.s la seguente funzione C contenuta in E1-mystrcmp/e3.c che realizza la funzione di confronto di stringhe C strcmp come specificato dallo standard POSIX:
char my_strcmp(const char* s1, const char* s2) {
while (*s1 && *s1 == *s2) {
s1++;
s2++;
}
return *s1 - *s2;
}
Usare il main di prova nella directory di lavoro E1-mystrcmp compilando con gcc -m32 e1_main.c e1.s -o e1.
Tradurre nel file E2-cnt-array-eq/e2.s la seguente funzione C contenuta in E2-cnt-array-eq/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 MOVZxy/MOVSxy.
Usare il main di prova nella directory di lavoro E2-cnt-array-eq compilando con gcc -m32 e2_main.c e2.s -o e2.
Tradurre nel file E3-clone-block/e3.s la seguente funzione C contenuta in E3-clone-block/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, come malloc o memcpy, usando l’istruzione call come se fossero normali funzioni scritte dall’utente.
Usare il main di prova nella directory di lavoro E3-clone-block 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 -g -no-pie -o e3 e3_main.c e3.s
Scrivere nel file E4-drop-spaces/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.
Data la funzione C:
#include "e5.h"
int f(int x, int y) {
int b = x;
int di = y;
int a = g(b, di);
int si = a;
a = g(di, b);
a = a + si;
return a;
}
Uno studente ha tradotto la funzione in ASM nel file E5/e5.s. Purtroppo la traduzione presenta alcuni errori. Infatti, generando il binario con gcc -m32 e5_main.c e5.s -o e5 g.s -g, la funzione genera un errore (e non calcola il risultato corretto):
> ./e5
Segmentation fault (core dumped)
Usare Valgrind e GDB per analizzare step by step l’esecuzione ed identificare gli errori. Infine, correggere gli errori.
NOTA: ignorare il codice di g.s.
Domanda 1) Se una funzione 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)Domanda 2) Assumendo %al = 5, eseguire movsbl %al, %eax porta allo stesso risultato in %eax rispetto eseguire movzbl %al, %eax?
Domanda 3) Assumendo di avere una funzione 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 %ebxDomanda 4) Se una funzione 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 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 bazDomanda 5) Quale fra le seguenti istruzioni risulta essere valida:
leal (%eax, %edx, 6), %ecxmovl (%eax), 4(%esp)leal -1(%ecx), %eaxaddl %eax, $4Domanda 6) Assumendo che %eax=0x0000BEEF e %ecx=0, quanto vale %ecx dopo aver eseguito l’istruzione movsbw %al, %cx?
0x000000EF0xFFFFFFEF0x0000FFEF0x0000EFEF