Diferencia entre revisiones de «Ejemplo de FPU (Organización del Computador II)»

De Cuba-Wiki
Sin resumen de edición
Sin resumen de edición
(No se muestran 2 ediciones intermedias del mismo usuario)
Línea 1: Línea 1:
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.
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>  
  #include <math.h>  
Línea 21: Línea 21:
  }
  }


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


  global _probar  
  %ifdef WIN32
%define probar _probar
%endif
   
   
  section .data
  ; exporto la funcion probar
global probar
   
   
section .data
  cinco  dd 5  
  cinco  dd 5  
  cuatro dd 4  
  cuatro dd 4  
Línea 32: Línea 36:
   
   
  section .text  
  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)
   
   
_probar:
    frndint
    fsub st1, st0
    ; st3 = (1/5) * sen(x) * cos(z)
    ; st2 = 3/2
    ; st1 = dec(log2(e))
    ; st0 = int(log2(e))
   
   
;obtengo (1/5)*sen(x)*cos(z) en st0:
    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))
   
   
fld1  
    fstp st1
fild dword [cinco]
    fxch st1
fdivp st1,st0  
    ; st3 = (1/5) * sen(x) * cos(z)
fld dword [esp+4]
    ; st2 = 3/2
fsin
    ; st1 = 2^int(log2(e))
fld dword [esp+8]
    ; st0 = dec(log2(e))
fcos
   
fmulp st1,st0  
    f2xm1
fmulp st1,st0  
    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
   
   
;obtengo (3/2)*e^2 en st0: 
    fmulp st1, st0
    ; st2 = (1/5) * sen(x) * cos(z)
    ; st1 = 3/2
    ; st0 = e^2
   
   
fld1
    fmulp st1, st0
fld1
    ; st1 = (1/5) * sen(x) * cos(z)
fadd st1,st0  
    ; st0 = (3/2) * e^2
fadd st0,st1  
fdivrp st1,st0  
   
   
fldl2e
    fild dword [siete]
fldl2e
    fild dword [cuatro]
frndint
    fdivp st1, st0
fsub st1,st0  
    ; st2 = (1/5) * sen(x) * cos(z)
fld1
    ; st1 = (3/2) * e^2
fscale
    ; st0 = 7/4
fstp st1  
   
fxch st1  
    fld dword [esp + 4]
f2xm1
    fldpi
fld1
    fadd st0, st1
faddp st1,st0  
    fld st0
fmulp st1,st0  
    fmulp st1, st0
fld st0  
    ; st4 = (1/5) * sen(x) * cos(z)
fmulp st1,st0
    ; 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  
    fmulp st1,st0  
    fsubp st1,st0  
;obtengo cos((7/4) * a) = ((7/4) * ((x - PI)² + (x + PI)²)) en st0:
    ; st0 = magia!
    ret
fld dword [esp+4]
fld st0
fldpi
fsubp st1,st0  
fld st0
fmulp st1,st0
fld st1
fldpi
faddp st1,st0
fld st0
fmulp st1,st0
faddp st1,st0
fild dword [siete]
fild dword [cuatro]
fdivp st1,st0
fmulp st1,st0
fcos
fstp st1
;situacion hasta el momento:
;
;st2 = | (1/5)*sen(x)*cos(z)  |
;st1 = | (3/2)*e^2            |
;st0 = | cos((7/4) * a)      | 
;termino de hacer las cuentas:
fmulp st1,st0
fsubp st1,st0
ret

Revisión del 12:33 14 nov 2006

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