Sistemi di Calcolo

Corso di Laurea in Ingegneria Informatica e Automatica - A.A. 2017-2018

HomePage | Avvisi | Diario lezioni | Programma | Materiale didattico | Esami | Forum | Login

Soluzioni Esercizi sull'ISA IA32


Esercizio 1

Si traduca in C il seguente programma IA32:

e1:                             ; parametro x in 8(%ebp) e y in 12(%ebp) - interi 4 byte
        pushl   %ebp            ; prologo
        movl    %esp, %ebp      
        movl    8(%ebp), %eax   ; z = x
        imull   %eax, %eax      ; z = z * z
        addl    12(%ebp), %eax  ; z = z + y
        popl    %ebp            ; epilogo
        ret                     ; return z


Si risponda inoltre alle seguenti domande:

Soluzione:

T e1(T x, T y) {
    return x*x+y;
}


dove T è indifferentemente int, unsigned, long o unsigned long (un intero con o senza segno a 32 bit).

Risposte domande:


Esercizio 2

Si traduca in C il seguente programma IA32:

e2:
    pushl   %ebp           ; prologo
    movl    %esp, %ebp
    movw    8(%ebp), %ax   ; primo parametro (intero a 2 byte) in ax
    movw    12(%ebp), %cx  ; secondo parametro (intero a 2 byte) in cx
    cmpw    %ax, %cx       ; calcola cx-ax
    cmovgew %cx, %ax       ; sovrascrive ax con cx (2 byte) se cx-ax >= 0 (ge, confronto con segno)
    movswl  %ax, %eax      ; copia ax in eax (con segno)
    popl    %ebp           ; epilogo
    ret                    ; restituisce eax


Si risponda inoltre alle seguenti domande:

Soluzione:

short e2(short x, short y) {
    return x > y ? x : y;
}


Si noti che sarebbe stato errato usare unsigned short invece di short poiché il testo usa cmovgew e movswl. Se avessimo trovato cmovaew e movzwl avremmo concluso che il tipo è unsigned short.

Risposte domande:

e2:
    movw    4(%esp), %ax     ; usiamo esp invece di ebp
    movw    8(%esp), %cx     ; usiamo esp invece di ebp
    cmpw    %ax, %cx
    cmovgew %cx, %ax
    movswl  %ax, %eax
    ret



e2:
    pushl   %ebp
    pushl   %ebx
    movl    %esp, %ebp
    movw    12(%ebp), %ax
    movw    16(%ebp), %bx
    cmpw    %ax, %bx
    cmovgew %bx, %ax
    movswl  %ax, %eax
    popl    %ebx
    popl    %ebp
    ret


Esercizio 3

Si traduca in C il seguente programma IA32:

e3:
    pushl   %edi                 ; prologo: salva registri callee-save edi ed esi
    pushl   %esi
    xorl    %eax, %eax           ; assegna eax = 0, indice di scorrimento array
    movl    20(%esp), %ecx       ; terzo parametro in ecx
    movl    16(%esp), %edx       ; secondo parametro in edx
    movl    12(%esp), %esi       ; primo parametro in esi
    jmp L4
L2:
    xorl    %eax, %eax           ; assegna eax = 0, valore restituito
    jmp L6                       ; salta alla fine della funzione
L1:
    movl    (%edx,%eax,4), %edi  ; assegna edi = edx[eax] => edx è puntatore a intero a 4 byte
    cmpl    %edi, (%esi,%eax,4)  ; calcola esi[eax]-edx[eax] => esi è puntatore a intero a 4 byte
    jne L2                       ; salta a L2 se esi[eax]-edx[eax] != 0, cioè esi[eax] != edx[eax]
    incl    %eax                 ; eax++
L4:
    cmpl    %ecx, %eax           ; calcola eax-ecx
    jl  L1                       ; salta a L1 se eax-ecx < 0 (l=less, con segno) - rimane in ciclo
    movl    $1, %eax             ; assegna eax = 1, valore restituito
L6:
    popl    %esi                 ; prologo: ripristina registri callee-save edi ed esi
    popl    %edi
    ret


Si risponda inoltre alle seguenti domande:

Soluzione:

Usando come nomi di variabili i corrispondenti nomi dei registri IA32 usati nel codice assembly, otteniamo:

int e3(T* esi, T* edx, int ecx) {
    int eax;
    for (eax=0; eax<ecx; eax++)
        if (esi[eax]!=edx[eax]) return 0;
    return 1;
}


Usando dei nomi di variabili più familiari:

int e3(T* a, T* b, int n) {
    int i;
    for (i=0; i<n; i++)
        if (a[i]!=b[i]) return 0;
    return 1;
}


dove T è indifferentemente int, unsigned, long o unsigned long (un intero con o senza segno a 32 bit).

Risposte domande:


Esercizio 4

Si traduca in C il seguente programma IA32:

e4:
    pushl   %ebp              ; prologo
    movl    %esp, %ebp
    pushl   %esi              ; salva registro callee-save
    movl    8(%ebp), %eax     ; primo parametro in eax
    movw    (%eax), %cx       ; cx = *eax (legge 2 byte dall'indirizzo eax)
    movl    12(%ebp), %edx    ; secondo parametro in edx
    movw    (%edx), %si       ; si = *edx (legge 2 byte dall'indirizzo edx)
    movw    %si, (%eax)       ; *eax = si (scrive all'indirizzo eax i 2 byte precedentemente letti dall'indirizzo edx)
    movw    %cx, (%edx)       ; *edx = cx (scrive all'indirizzo edx i 2 byte precedentemente letti dall'indirizzo eax)
    popl    %esi              ; epilogo - ripristina registro callee-save
    popl    %ebp
    ret


Si risponda inoltre alla seguente domanda:

Soluzione:

void e4(T* eax, T* edx) {
    T cx = *eax;
    T si = *edx;
    *eax = si;
    *edx = cx;
}


dove T è indifferentemente short oppure unsigned short. Usando dei nomi di variabili più familiari e una sola variabile locale:

void e4(T* x, T* y) {
    T tmp = *x;
    *x = *y;
    *y = tmp;
}


Si noti che, poiché alla fine il registro eax contiene il primo parametro, avrebbe anche potuto essere:

T* e4(T* x, T* y) {
    T tmp = *x;
    *x = *y;
    *y = tmp;
    return x;
}


o anche:

int e4(T* x, T* y) {
    T tmp = *x;
    *x = *y;
    *y = tmp;
    return (int)x;
}


Risposta domanda:


Esercizio 5

Si traduca in C il seguente programma IA32:

e5:
    movl 4(%esp), %ecx   ; primo parametro in eax
    movl 8(%esp), %edx   ; secondo parametro in eax<