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 | 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. | ||
%ifdef WIN32 | |||
%define probar _probar | |||
%endif | |||
; 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) | |||
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 | |||
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