Sistemi di Calcolo

Corso di Laurea in Ingegneria Informatica e Automatica

Home | Avvisi | Diario Lezioni | Esercitazioni | Esami | Materiale Didattico | Valutazioni Studenti | Lezioni di Camil Demetrescu |

[T05] Esercitazione 5

Istruzioni per l’esercitazione:

Per maggiori informazioni fate riferimento al regolamento delle esercitazioni.

Esercizio 1 (strcmp alla vaccinara)

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.

Esercizio 2 (Conto numero elementi uguali)

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.

Esercizio 3 (Clonazione buffer di memoria)

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

Esercizio 4 (Palestra C)

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.

Esercizio 5 (Debugging)

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.

Domande

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?

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:

Domanda 4) Se una funzione baz viene chiamata da una funzione foo, quale delle seguenti affermazioni risulta essere falsa:

Domanda 5) Quale fra le seguenti istruzioni risulta essere valida:

Domanda 6) Assumendo che %eax=0x0000BEEF e %ecx=0, quanto vale %ecx dopo aver eseguito l’istruzione movsbw %al, %cx?