Ejemplo de FPU (Organización del Computador II)

De Cuba-Wiki
Saltar a: navegación, buscar
Back.png Volver a la página de la materia

Calculo la funcion usando la libreria math.h de C y despues llamo a mi programa hecho en assembler para comparar resultados, por cierto recuerden que como probar es de tipo float entonces devuelve en st0.

#include <math.h> 

extern float probar(float,float); 

int main(int argc, char *argv[]) 
{ 
   //y = (1/5)sen(x)cos(z) – (3/2)cos(7a/4)e² 
   //a = (x - PI)² + (x + PI)² 
   
   float x = 7.0; 
   float z = 5.0; 
   float a = (x-M_PI)*(x-M_PI) + (x+M_PI)*(x+M_PI);    
   float y = (1.0/5.0) * sin(x) * cos(z) -
             (3.0/2.0) * cos((7.0/4.0)*a) * pow(exp(1.0),2.0);
   printf("\ny: %f\n\n", y); 
   printf("\ndevolvi: %f\n\n", probar(x,z)); 
   system("PAUSE"); 
   return 0; 
}

Aca esta el programa en assembler, paso a paso vamos viendo como se transforma la pila de la FPU luego de aplicar las funciones.

%ifdef WIN32
%define probar _probar
%endif

; exporto la funcion probar
global probar

section .data
cinco  dd 5 
cuatro dd 4 
siete  dd 7 

section .text 
probar:
    fld1
    fild dword [cinco]
    fdivp st1, st0
    ; st0 = 1/5
    
    fld dword [esp + 4]
    fsin
    ; st1 = 1/5
    ; st0 = sen(x)
    
    fld dword [esp + 8]
    fcos
    ; st2 = 1/5
    ; st1 = sen(x)
    ; st0 = cos(z)
    
    fmulp st1, st0
    fmulp st1, st0
    ; st0 = (1/5) * sen(x) * cos(z)
    
    fld1
    fld1
    fadd st1, st0
    fadd st0, st1
    fdivrp st1, st0
    ; st1 = (1/5) * sen(x) * cos(z)
    ; st0 = 3/2
    
    fldl2e
    fldl2e
    ; st3 = (1/5) * sen(x) * cos(z)
    ; st2 = 3/2
    ; st1 = log2(e)
    ; st0 = log2(e)

    frndint
    fsub st1, st0
    ; st3 = (1/5) * sen(x) * cos(z)
    ; st2 = 3/2
    ; st1 = dec(log2(e))
    ; st0 = int(log2(e))

    fld1
    ; st4 = (1/5) * sen(x) * cos(z)
    ; st3 = 3/2
    ; st2 = dec(log2(e))
    ; st1 = int(log2(e))
    ; st0 = 1.0
    
    fscale
    ; st4 = (1/5) * sen(x) * cos(z)
    ; st3 = 3/2
    ; st2 = dec(log2(e))
    ; st1 = int(log2(e))
    ; st0 = 2^int(log2(e))

    fstp st1
    fxch st1
    ; st3 = (1/5) * sen(x) * cos(z)
    ; st2 = 3/2
    ; st1 = 2^int(log2(e))
    ; st0 = dec(log2(e))
    
    f2xm1
    fld1
    faddp st1, st0
    ; st3 = (1/5) * sen(x) * cos(z)
    ; st2 = 3/2
    ; st1 = 2^int(log2(e))
    ; st0 = 2^dec(log2(e))
    
    fmulp st1, st0
    ; st2 = (1/5) * sen(x) * cos(z)
    ; st1 = 3/2
    ; st0 = 2^int(log2(e)) * 2^dec(log2(e)) = 2^log2(e) = e
    
    fld st0
    ; st3 = (1/5) * sen(x) * cos(z)
    ; st2 = 3/2
    ; st1 = e
    ; st0 = e

    fmulp st1, st0
    ; st2 = (1/5) * sen(x) * cos(z)
    ; st1 = 3/2
    ; st0 = e^2

    fmulp st1, st0
    ; st1 = (1/5) * sen(x) * cos(z)
    ; st0 = (3/2) * e^2

    fild dword [siete]
    fild dword [cuatro]
    fdivp st1, st0
    ; st2 = (1/5) * sen(x) * cos(z)
    ; st1 = (3/2) * e^2
    ; st0 = 7/4
    
    fld dword [esp + 4]
    fldpi
    fadd st0, st1
    fld st0
    fmulp st1, st0
    ; st4 = (1/5) * sen(x) * cos(z)
    ; st3 = (3/2) * e^2
    ; st2 = 7/4
    ; st1 = x
    ; st0 = (x + PI)^2
    
    fxch st1
    fldpi
    fsubp st1, st0
    fld st0
    fmulp st1, st0
    ; st4 = (1/5) * sen(x) * cos(z)
    ; st3 = (3/2) * e^2
    ; st2 = 7/4
    ; st1 = (x + PI)^2
    ; st0 = (x - PI)^2
    
    faddp st1, st0
    fmulp st1, st0
    fcos
    ; st2 = (1/5) * sen(x) * cos(z)
    ; st1 = (3/2) * e^2
    ; st0 = cos((7/4) * ((x + PI)^2 + (x - PI)^2))

    fmulp st1,st0 
    fsubp st1,st0 
    ; st0 = magia!
    ret