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

Esercizi sull'ISA IA32


Nota: se gcc con l'opzione -m32 su Linux a 64 bit non riesce a trovare delle header e termina con un errore, probabilmente non sono installate le librerie C a 32 bit. In distribuzioni Linux che usano apt come package manager, provare con il comando: sudo apt-get install libc6-dev-i386.

Esercizio 1

Si traduca in C il seguente programma IA32:

e1:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        imull   %eax, %eax
        addl    12(%ebp), %eax
        popl    %ebp
        ret


Si risponda inoltre alle seguenti domande:


Esercizio 2

Si traduca in C il seguente programma IA32:

e2:
    pushl   %ebp
    movl    %esp, %ebp
    movw    8(%ebp), %ax
    movw    12(%ebp), %cx
    cmpw    %ax, %cx
    cmovgew %cx, %ax
    movswl  %ax, %eax
    popl    %ebp
    ret


Si risponda inoltre alle seguenti domande:


Esercizio 3

Si traduca in C il seguente programma IA32:

e3:
    pushl   %edi
    pushl   %esi
    xorl    %eax, %eax
    movl    20(%esp), %ecx
    movl    16(%esp), %edx
    movl    12(%esp), %esi
    jmp L4
L2:
    xorl    %eax, %eax
    jmp L6
L1:
    movl    (%edx,%eax,4), %edi
    cmpl    %edi, (%esi,%eax,4)
    jne L2
    incl    %eax
L4:
    cmpl    %ecx, %eax
    jl  L1
    movl    $1, %eax
L6:
    popl    %esi
    popl    %edi
    ret


Si risponda inoltre alle seguenti domande:


Esercizio 4

Si traduca in C il seguente programma IA32:

e4:
    pushl   %ebp          
    movl    %esp, %ebp
    pushl   %esi          
    movl    8(%ebp), %eax
    movw    (%eax), %cx
    movl    12(%ebp), %edx
    movw    (%edx), %si
    movw    %si, (%eax)
    movw    %cx, (%edx)
    popl    %esi
    popl    %ebp
    ret


Si risponda inoltre alla seguente domanda:


Esercizio 5

Si traduca in C il seguente programma IA32:

e5:
    movl 4(%esp), %ecx
    movl 8(%esp), %edx
    pushl (%ecx)
    pushl (%edx)
    popl (%ecx)
    popl (%edx)
    ret


Si risponda inoltre alla seguente domanda:


Esercizio 6

Si consideri la seguente funzione:

int e6(char x) {
    if (x>0) return 1;
    else return 0;
}


e la sua traduzione in assembly x86 IA32 usando gcc senza ottimizzazioni (livello di ottimizzazione -O0):

e6:
    subl    $12, %esp
    movb    16(%esp), %al
    movb    %al, 11(%esp)
    movb    11(%esp), %al
    cmpb    $0, %al
    jle L2
    movl    $1, (%esp)
    jmp L3
L2:
    movl    $0, (%esp)
L3:
    movl    (%esp), %eax
    movl    %eax, 4(%esp)
    movl    4(%esp), %eax
    addl    $12, %esp
    ret


Si ottenga una versione più compatta del codice assembly che usa il minor numero possibile di istruzioni.

Esercizio 7

Il seguente frammento di programma assembly IA32 è errato. Spiegare perché e correggere l'errore:

e7:
    pushl   $10
    call    f
    ret


Esercizio 8

Si completi l'intestazione della funzione e8, che calcola e8(x,y)=|x-y|:

int e8(___________) {
    if (x>y) return x-y;
    return y-x;
}


analizzando la sua traduzione in assembly IA32:

e8:
    pushl   %ebp
    movl    %esp, %ebp
    movw    12(%ebp), %cx
    movw    8(%ebp), %dx
    cmpw    %cx, %dx
    jle L3
    movswl  %dx, %eax
    movswl  %cx, %ecx
L2:
    subl    %ecx, %eax
    popl    %ebp
    ret
L3:
    movswl  %cx, %eax
    movswl  %dx, %ecx
    jmp L2


Esercizio 9

Scaricare i seguenti due file:

e9.s
    .globl  e9
e9:
    pushl   %ebp
    movl    %esp, %ebp
    movsbl  8(%ebp), %eax
    movsbl  12(%ebp), %ecx
    subl    %ecx, %eax
    popl    %ebp
    ret


e9main.c
#include <stdio.h>

int e9(char x, char y);

int main() {
    int d = e9(10,7);
    printf("%d\n", d);
    return 0;
}


e generare un file eseguibile chiamato e9 compilandoli:

Dopo aver testato il funzionamento del programma eseguendolo (il programma dovrebbe stampare 3 sul terminale), modificare il file e9.s in modo che il registro ebp non compaia più.


Esercizio 10

Scaricare i seguenti due file, contenenti una funzione e10 scritta in assembly IA32 che (dovrebbe) calcolare il massimo di due int e un main di prova:

e10.s
    .globl  e10
e10:
    pushl   %ebp
    movl    8(%ebp), %eax
    movl    4(%ebp), %ecx
    cmpl    %eax, %ecx
    cmoval  %ecx, %eax
    popl    %ebp
    ret


e10main.c
#include <stdio.h>

int e10(int x, int y); // calcola il massimo tra x e y

int main() {
    printf("%d [atteso=23]\n", e10(23,17));
    printf("%d [atteso=17]\n", e10(-23,17));
    printf("%d [atteso=41]\n", e10(19,41));
    printf("%d [atteso=-5]\n", e10(-5,-13));
    printf("%d [atteso=6]\n",  e10(6,-6));
    printf("%d [atteso=1]\n",  e10(1,1));
    return 0;
}


e generare un file eseguibile chiamato e10 compilandoli:


Il programma stamperà un risultato errato, ad esempio:

$ ./e10
-1787013415 [atteso=23]
-1787013415 [atteso=17]
-1787013415 [atteso=41]
-178701