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 |

[T02] Esercitazione

Istruzioni per l’esercitazione:

Per maggiori informazioni fate riferimento al regolamento delle esercitazioni.

Esercizio 1 (Calcolo di espressioni)

Tradurre nel file E1/e1.s la seguente funzione C contenuta in E1/e1.c, senza semplificare l’espressione manualmente:

int f() {
    int x = ((2+3)*(4-2)-(2+3))*3;
    return x + 1;
}

Usare il main di prova nella directory di lavoro E1 compilando con gcc -m32 e1_main.c e1.s -o e1

Esercizio 2 (Calcolo di espressioni con un parametro)

Tradurre nel file E2/e2.s la seguente funzione C contenuta in E2/e2.c che calcola un polinomio a valori interi:

int f(int x) {
    return 2*x*x-7*x+1;
}

Usare il main di prova nella directory di lavoro E2 compilando con gcc -m32 e2_main.c e2.s -o e2

Esercizio 3 (Calcolo di espressioni con due parametri)

Tradurre nel file E3/e3.s la seguente funzione C contenuta in E3/e3.c che calcola un polinomio a valori interi:

int f(int x, int y) {
    return (x+y)*(x-y);
}

Usare il main di prova nella directory di lavoro E3 compilando con gcc -m32 e3_main.c e3.s -o e3

Esercizio 4 (Palestra C)

Scrivere nel file E4/e4.c la vostra versione personale della funzione della libreria standard libc strcat che appende la stringa src alla stringa nel buffer dest e restituisce dest. Il prototipo della funzione da realizzare è il seguente:

char *my_strcat(char *dest, const char *src);

Usare il main di prova nella directory di lavoro E4 compilando con gcc e4_main.c e4.c -o e4

NOTA: non è permesso l’utilizzo di alcuna funzione di libreria (es. strcat, strlen, etc).

Domande

Domanda 1 Quale dei seguenti frammenti di codice potrebbe essere scritto in linguaggio macchina?

Domanda 2 Quanti bit servono per rappresentare il numero esadecimale 0xDEADBEEF?

Domanda 3 Il comando gcc hello.s -o hello attiva i seguenti stadi della toolchain di compilazione:

Domanda 4 Il comando gcc hello.o -o hello attiva i seguenti stadi della toolchain di compilazione:

Domanda 5 Fra i seguenti, qual è il tipo primitivo C con la dimensione (sizeof) minore che consente di rappresentare il numero 256?

Domanda 6 Per quale operatore bit-a-bit OP si ha che 0x13 OP 0x21 == 0x32?

Domanda 7 Dati:

char s[]="hello";
int a=sizeof(s), b=strlen(s), c=sizeof("hello");

quale delle seguenti affermazioni è vera? Assumere puntatori a 64 bit.

Soluzioni

Esercizio 1 (Calcolo di espressioni)

Versione C equivalente, creato a partire dall’alberto sintattico dell’espressione (come visto a lezione):

int f() {  // codice C equivalente
    int a = 2;
    a = a + 3;
    int c = 4;
    c = c - 2;
    a = a * c;
    c = 2;
    c = c + 3;
    a = a - c;
    a = a * 3;
    a = a + 1;
    return a;
}

Versione IA32:

.globl f

f:
    movl $2, %eax    #     int a = 2;
    addl $3, %eax    #     a = a + 3;
    movl $4, %ecx    #     int c = 4;
    subl $2, %ecx    #     c = c - 2;
    imull %ecx, %eax #     a = a * c;
    movl $2, %ecx    #     c = 2;
    addl $3, %ecx    #     c = c + 3;
    subl %ecx, %eax  #     a = a - c;
    imull $3, %eax   #     a = a * 3;
    incl %eax        #     a = a + 1;
    ret

Esercizio 2 (Calcolo di espressioni con un parametro)

Versione C equivalente, creato a partire dall’alberto sintattico dell’espressione (come visto a lezione):

int f(int x) {
    int a = x;
    a = a * a;
    a = a * 2;
    int c = x;
    c = c * 7;
    a = a - c;
    a = a + 1;
    return a;
}

Versione IA32:

.globl f

f:
    movl 4(%esp), %eax  # int a = x;
    imull %eax, %eax    # a = a * a;
    imull $2, %eax      # a = a * 2;
    movl 4(%esp), %ecx  # int c = x;
    imull $7, %ecx      # c = c * 7;
    subl %ecx, %eax     # a = a - c;
    incl %eax           # a = a + 1;
    ret                 # return a;

Esercizio 3 (Calcolo di espressioni con due parametri)

Versione C equivalente, creato a partire dall’alberto sintattico dell’espressione (come visto a lezione):

int f(int x, int y) { // x <-> c, y <-> d
    int c = x;
    int d = y;
    int a = c;
    a = a + d;
    c = c - d;
    a = a * c;
    return a;
}

Versione IA32:

.globl f

f:
    movl 4(%esp), %ecx  #     int c = x;
    movl 8(%esp), %edx  #     int d = y;
    movl %ecx, %eax     #     int a = c;
    addl %edx, %eax     #     a = a + d;
    subl %edx, %ecx     #     c = c - d;
    imull %ecx, %eax    #     a = a * c;
    ret                 #     return a;
    
Esercizio 4 (Palestra C)
#include <string.h>

char *my_strcat(char *dest, const char *src) {
    char* d = dest;
    while (*dest) dest++;
    while (*src) *dest++ = *src++;
    *dest = 0;
    return d;
}
Domande
  1. A - 55 23 C3 D3 00 00 00 C3 il linguaggio macchina è una sequenza di numeri.

  2. D - 32, ogni cifra esadecimale corrisponde a 4 bit.

  3. A - Assemblatore e linker: hello.s va prima assemblato per creare il file oggetto .o e poi il tutto va linkato per generare il file eseguibile hello.

  4. C - Linker: si parte già da un modulo oggetto che è stato assemblato, quindi rimane solo da creare l’eseguibile hello con il linker.

  5. C - short. 256 è 2^8, quindi sevono > 8 bit per rappresentare il valore.

  6. D - ^ (XOR) tradotto in binario si ha 0001 0011 xor 0010 0001 = 0011 0010

  7. A - a=6, b=5, c=6, infatti sia la variabile s che il letterale "hello" denotano un array di 6 byte che include il terminatore zero della stringa. Invece strlen restituisce il numero di caratteri escluso il terminatore.