Soluzioni fac-simile esonero (A.A. 2016-17)
[
Fac-simile esonero ]
Parte 1
# int test(int min, int max, int* x) {
# return (*x<min || *x>max) && max>min;
# }
.globl test
test:
pushl %esi
pushl %edi
movl 12(%esp), %esi # min
movl 16(%esp), %edi # max
movl 20(%esp), %edx # x
movl (%edx), %edx # *x
cmpl %esi, %edx
setl %al
cmpl %edi, %edx
setg %cl
orb %cl, %al
cmpl %esi, %edi
setg %cl
andb %cl, %al
movzbl %al, %eax
popl %edi
popl %esi
ret
Parte 2
Soluzione 1
# void fix(const int* u, int* v, int n) {
# int i;
# for (i=0; i<n-1; i++) {
# int m = media(u[i],u[i+1]);
# if (m > media(v[i],v[i+1])) v[i]=m;
# }
# }
.globl fix
fix:
pushl %ebx
pushl %esi
pushl %edi
movl 16(%esp), %ebx # u
movl 20(%esp), %esi # v
xorl %edi, %edi # i
L: movl 24(%esp), %ecx # rileggo n ad ogni iterazione: media() sporca %ecx
decl %ecx
cmpl %ecx, %edi
jge E
subl $8, %esp
movl 4(%ebx, %edi, 4), %eax # u[i+1]
movl %eax, 4(%esp)
movl (%ebx, %edi, 4), %eax # u[i]
movl %eax, (%esp)
call media
addl $8, %esp
pushl %eax # m
subl $8, %esp
movl 4(%esi, %edi, 4), %eax # v[i+1]
movl %eax, 4(%esp)
movl (%esi, %edi, 4), %eax # v[i]
movl %eax, (%esp)
call media
addl $8, %esp
popl %edx # m
incl %edi # i++
cmpl %eax, %edx #
jle L
movl %edx, -4(%esi, %edi, 4) # i รจ stato incrementato quindi -4
jmp L
E: popl %edi
popl %esi
popl %ebx
ret
Soluzione 2
# void fix(const int* u, int* v, int n) {
# int i;
# i = 0;
# n--;
# L: if (i>=n) goto E;
# int m = media(u[i],u[i+1]);
# int k = media(v[i],v[i+1]);
# if (m <= k) goto S;
# v[i]=m;
# S: i++;
# goto L;
# E: ;
# }
#
# Allocazione dei registri:
# u -> 28(%esp) (ed ecx localmente)
# v -> ebp
# n-1 -> ebx
# i -> esi
# m -> edi
# k -> eax
.globl fix
fix:
pushl %ebp
pushl %ebx
pushl %esi
pushl %edi
subl $8, %esp
movl 32(%esp), %ebp
movl 36(%esp), %ebx
xorl %esi, %esi
decl %ebx # n-1
L: cmpl %ebx, %esi
jge E
movl 28(%esp), %ecx
movl (%ecx, %esi, 4), %eax
movl %eax, (%esp)
movl 4(%ecx, %esi, 4), %eax
movl %eax, 4(%esp)
call media
movl %eax, %edi
movl (%ebp, %esi, 4), %eax
movl %eax, (%esp)
movl 4(%ebp, %esi, 4), %eax
movl %eax, 4(%esp)
call media
cmpl %eax, %edi
jle S
movl %edi, (%ebp,%esi,4)
S: incl %esi
jmp L
E: addl $8, %esp
popl %edi
popl %esi
popl %ebx
popl %ebp
ret
Soluzione 3
Soluzione avanzata proposta da uno studente che sfrutta l'aritmetica dei puntatori e LOOPNZ [doc1 doc2]
# void fix(const int* u, int* v, int n) {
# if (n==0) return;
# u += n;
# v += n;
# int c = n;
# do {
# int b = -c;
# int m = media(u[b],u[b+1]);
# if (m > media(v[b],v[b+1])) v[b] = m;
# } while (--c);
# }
.globl fix
fix:
pushl %ebx # b
pushl %esi # u
pushl %edi # v
movl 16(%esp), %esi
movl 20(%esp), %edi
movl 24(%esp), %ecx # c=n
testl %ecx, %ecx
jle E
leal (%esi, %ecx, 4), %esi # u=u+n
leal (%edi, %ecx, 4), %edi # v=v+n
subl $12, %esp
L: movl %ecx, %ebx
negl %ebx # b=-c
movl (%esi, %ebx, 4), %ecx # ecx riassegnato a fine loop
movl %ecx, (%esp)
movl 4(%esi, %ebx, 4), %ecx
movl %ecx, 4(%esp)
call media
movl %eax, 8(%esp)
movl (%edi, %ebx, 4), %ecx
movl %ecx, (%esp)
movl 4(%edi, %ebx, 4), %ecx
movl %ecx, 4(%esp)
call media
movl %ebx, %ecx
negl %ecx # c=-b
cmpl %eax, 8(%esp)
jle D
movl 8(%esp), %eax
movl %eax, (%edi, %ebx, 4)
D: loopnz L # if (--c) goto L
E: addl $12, %esp
popl %edi
popl %esi
popl %ebx
ret
Parte 3
#include "sort.h"
static int my_cmp(int* a, int* b) {
return *a-*b;
}
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
void sort(int* v, int n) {
int k, i;
for (k=0; k<n; k++) {
int changed = 0;
for (i=1; i<n; i++)
if (my_cmp(v+i-1, v+i) > 0) {
swap(v+i-1, v+i);
changed = 1;
}
if (!changed) break;
}
}
Parte 4
TBA