I use nasm and FPU
x86 Instructions.
now let's say i have in FPU
st0
0.
i have variable :
jedynka: dd 1.0
and now operation:
fiadd [jedynka]
doesn't work, error in nasm:
error: opeartion size not specifed
when:
fiadd dword [jedynka]
, the result (when st0 = 0 ) is :
10652320
and not 1
assembly code:
;lepiej od 0 do n-1 dlatego
;WZOR NA PI: 4 (1 - 1/3 + 1/5 - 1/7 + 1/9...)
section .text use32
global _liczbae
_liczbae:
push ebp
mov ebp, esp ; ramka stosu
; [ebp] old EBP location ; [ebp+4] return point from procedure
; [ebp+8] the first parameter of the procedure, ; [ebp+12] the second parameter of the procedure
finit ; inicjalizacja FPU
fld1 ; st ostatni -> bit_znaku
fstp dword [bit_znaku] ; 1->dodatni, domyslnie jest jedynka
fild dword [ebp+8] ; ładujemy int n do st0
fld1
fsubp st1,st0
;jmp koniec
;fisub [minus_jedynka]
;jmp koniec
fstp dword [n] ; zapisujemy st0 pod adresem [n] i zrzucamy st0 ze stosu , mam tam n-1
fldz ;na wynik st ostatni st0
petla:
fld dword [n_biezace] ; st0 n_biezace st1 wynik
fld dword [dwojka] ;wynik w st2 teraz
fmulp st1,st0 ; 2 * biezace 'n'
fiadd dword [jedynka] ; 1 + st0
jmp koniec
;jmp koniec
; fld1
;faddp ; mam juz 2'n' +1 w st0 ; 1. 2*'0'+1 = 1.
fld1 ;wynik w st2 teraz
fxch st1 ;zamiana st1<-->st0 st0 2n+1 ,st1 1
fdivp st1,st0 ; 1/(2n+1) 1. 1/1 = 1. ;wynik st1
;czy teraz ma być ujemny element?
fld dword [bit_znaku]
ftst ; porownuje z '0'
fstsw ax ; zapisujemy stan FPU do AX
sahf ; wrzucamy rejestr AH do rejestru flag
je ujemny
jmp dodatni
ujemny:
fld1
faddp
fstp dword [bit_znaku] ; zmieniony bit_znaku zapisuje
fchs ;zmieniam znak st0
jmp dalej
dodatni:
fld1
fsubp
fstp dword [bit_znaku] ; zmieniony bit_znaku zapisuje
dalej:
faddp st1,st0 ; zapisanie do wyniku
; jmp koniec
;dodanie '1' od licznika [n_biezace]:
fild dword [n_biezace]
fld1
faddp st1,st0
;sprawdze czy 'n_biezace' = n ? jesli tak to koniec
fld dword [n]
fcomp st1 ; porownaj st1 z st0
fstsw ax
sahf
fstp dword[n_biezace] ; zapisuje nowe 'n'
jne petla ; jesli nie rowne skocz do 'petla'
koniec:
;fld dword [czworka]; razy 4 na koniec
;fmulp st1,st0;
;wynik + 1 ; bo niz uwzgledniłem n=0 np.
leave ; usuwa ramke stosu
ret ; wartosc zwracana to wartosc z rejestru st0
n_biezace: dd 0.0
n: dd 0.0 ;od n=20 do n=0
dwojka: dd 2.0
bit_znaku dd 0.0
czworka: dd 4.0
minus_jedynka: dd -1.0
jedynka: dd 1.0
C code:
#include <stdio.h>
extern double liczbae(int n);
int main()
{
int n = 10;
double wynik;
int wait = 0;
printf("Program liczy wartosc e z podana dokladnoscia");
printf("\n\nPodaj dokladnosc: ");
scanf("%d", &n);
wynik = liczbae(n);
printf("\ne = %1.16f", wynik);
scanf("%d", &wait);
return 0;
}
important lines, where i jump is 27,28:
fiadd dword [jedynka] ; 1 + st0
jmp koniec
how to fix it ?