Primeira Questão
- Item a:
push %ebp
mov %esp, %ebp
mov 16(%ebp), %eax /* empilha j */
push %eax
mov 12(%ebp), %eax /* empilha parte alta d */
push %eax
mov 8(%ebp), %eax /* empilha parte baixa d */
push %eax
mov $10, %eax /* empilha i (amarrado) */
push %eax
call f
mov %ebp, %esp
pop %ebp
ret
- Item b:
typedef int (*func_ptr) (double d, int j);
Segunda Questão
foo:
push %ebp
mov %esp, %ebp
push %ebx
push %esi
sub $28, %esp /* 8 acc + 8 mul + 4 y + 8 x */
fldz
fstpl -16(%ebp) /* acc = 0.0 */
fld1
fstpl -24(%ebp) /* mul = 1.0 */
mov $0, %ebx /* i */
mov 8(%ebp), %esi /* px */
loop:
cmp 12(%ebp), %ebx
jge fim
mov 4(%esi), %eax /* pega px->ix */
mov %eax, -28(%ebp) /* o parametro y */
flds (%esi) /* px->fx é float */
fstpl -36(%ebp) /* converte para double: o parametro x */
call boo
faddl -16(%ebp) /* soma retorno na pilha PF com acc */
fstl -16(%ebp) /* atualiza acc sem remover topo da pilha PF */
fmull -24(%ebp) /* multiplica topo pilha PF por mul */
fstpl -24(%ebp) /* atualiza mul */
add $8, %esi /* px++ -> struct tem 8 bytes */
inc %ebx
jmp loop
fim:
fldl -24(%ebp) /* retorno (mul) na pilha de PF */
mov -4(%ebp), %ebx
mov -8(%ebp), %esi
mov %ebp, %esp
pop %ebp
ret
Terceira Questão
D: last
T: func
U: s, transf, pow
Quarta Questão
#define getsig(f) ((f)>>31 & 1)
#define getexp(f) ((f)>>23 & 0xff)
#define getmant(f) ((f) & 0x7fffff)
typedef union {
float f;
unsigned int i;
} U;
int compara (float a, float b) {
U u;
unsigned int ia, ib, siga, expa, expb;
/* pega as representações binárias de a e b */
u.f = a; ia = u.i;
u.f = b; ib = u.i;
/* se sinais são diferentes, já pode decidir quem é menor */
siga = getsig(ia);
if (siga != getsig(ib))
return (siga ? -1 : 1) ; /* se a é negativo, a é menor, senão a é maior */
/* mesmo sinal: se expoentes são diferentes, já pode decidir quem é menor */
expa = getexp(ia);
expb = getexp(ib);
if (expa != expb) {
if (expa < expb)
return (siga ? 1 : -1) ; /* a tem valor absoluto menor: sinal decide */
else
return (siga ? -1 : 1) ; /* a tem valor absoluto maior: sinal decide */
}
/* mesmo sinal e expoente: mantissa decide */
ia = getmant(ia);
ib = getmant(ib);
if (ia == ib) return 0;
if (ia < ib)
return (siga ? 1 : -1) ; /* a tem valor absoluto menor: sinal decide */
else
return (siga ? -1 : 1) ; /* a tem valor absoluto maior: sinal decide */
}
Quarta Questão: alternativa Bruno Pontes (com pequenas modificações)
int compara (float a, float b) {
U u;
unsigned int ia, ib, siga;
/* pega as representações binárias de a e b */
u.f = a; ia = u.i;
u.f = b; ib = u.i;
/* se sinais são diferentes, já pode decidir quem é menor */
siga = getsig(ia);
if (siga != getsig(ib))
return (siga ? -1 : 1) ; /* se a é negativo, a é menor, senão a é maior */
/* mesmo sinal: remove bit de sinal e compara o restante expmant */
ia <<= 1;
ib <<= 1;
if (ia != ib) {
if (ia < ib)
return (siga ? 1 : -1) ; /* a tem valor absoluto menor: sinal decide */
else
return (siga ? -1 : 1) ; /* a tem valor absoluto maior: sinal decide */
}
return 0;
}