Assembler taylor series arctg x

691 Views Asked by At

I wrote program in assembly that takes only two variables from C program, then returns the answer to C program at the end. I got problem with finding what is wrong in assembly file.

My goal is to write program using FPU (nasm), that will count arctg (x), where x is a variable in C, typed in by user. Second variable is accuracy, so the number of taylor series integers.

program C:

extern float arctg(float x, int dokladnosc); //deklaracja funkcji zewnętrznej
#include <stdio.h>

int main()
{
        float a;
        int b;
        printf("1.Napisz program, ktory oblicza arctg(x), gdzie x jest argumentem podanym przez\n uzytkownika,podobnie jak dokladnosc obliczenia.\n");
        printf("\nPodaj wartosc X z przedzialu (-1,1): ");
        scanf("%f",&a);
        if(a>=1 || a<=-1)
        {
        printf("zly argument!! ");
        getch();
        return 0;
        }
        printf("Dokladnosc: ");

        scanf("%i",&b);
        if(b<1)
        {
        printf("zly argument!! ");
        getch();
        return 0;
        }
        printf("Wartosc funkcji Arctg(%f) = %f\n", a, arctg(a, b));
        getch();
        return 0;
}

program assembler:

section .text   use32                  
global _arctg                  
_arctg:

%idefine x [ebp+8]
%idefine dokl [ebp+12]
push ebp                               
mov ebp, esp           


finit                                          
fld             dword x                
;?fst dword x          
fild    dword dokl             
; st1 x   st0  dokl  
  fld1
  fsubp st1,st0
  ; st1 x   st0  dokl-1 (tak jak we wzorze od zera->do n-1)
fldz ; nowa dokladnosc -> dokl !! dopoki bd rowne :X !
; st2 x   st1  dokl-1  st0 0 <-mnoznik do tego!

fld1 ;jezeli tu bd jedynka to wyraz bedzie dodatni!!
; st3 x   st2  dokl-1  st1 0 <-mnoznik do tego!  st0 1(znaku)


;na obliczenia:
fldz
; st4 x   st3  dokl-1  st2 0 <-mnoznik do tego!  st1 1(znaku)=1  st0 obliczenia=1

licz_kolejny_wyraz_szeregu:

;to wiemy, ze nastepny bedzie ujemny, jesli bedzie nastepny.
; st4 x   st3  dokl-1  st2 0 <-mnoznik do tego!  st1 1(znaku)=1  st0 obliczenia=1
;ustawiam znak st2->'0'


;1.sprawdzamy znak:

fld1
fcomp st2 ; jakiego znaku?
fstsw ax
sahf
je dodatni
;jmp ujemny
ujemny:
;dodaje 1 do bitu znaku '1' = dodatni ,
fld1
faddp st2,st0
;to samo co w dodatni, ale ze zmiana znaku

jmp dodatni_gdzie_bit_znaku_rowny_1



dodatni:
;odejmuje 1 od bitu znaku '1' = dodatni ,
fld1
fsubp st2,st0
dodatni_gdzie_bit_znaku_rowny_1:
;mozemy przejsc do liczenia pierwszego wyrazu(dodatniego)
;najpierw x^(2n+1)
;fld1 ;1szy nowy element
;petla do potegi ^2n+1, gdzie n->stała; np.3 razy
;fmul st0,st5 ; st0 x
;stworzymy biezace 2n+1 :o
; st4 x   st3  dokl-1  st2 0 <-mnoznik do tego!  st1 1(znaku)=0  st0 obliczenia=1
fld1 ;1szy nowy element
fld1
faddp ; mamy 2 , teraz razy biezace 'n'
fmul st0,st3  
; st5 x   st4  dokl-1  st3 0 <-mnoznik do tego!  st2 1(znaku)=0  st1 obliczenia=1   st0  2*0
fld1
faddp st1,st0 ; jest '1' przy pierwszej rundzie.
; st5 x   st4  dokl-1  st3 0 <-mnoznik do tego!  st2 1(znaku)=0  st1 obliczenia=1   st0  1->mnoznik_obecnej_petli
;licznik petli utworzony, wiec liczmy w petli !
fld1 ;2-gi nowy element
; st6 x   st5  dokl-1  st4 0 <-mnoznik do tego!  st3 1(znaku)=0  st2 obliczenia=1   st1  1->mnoznik_obecnej_petli   st0 1
potegowanie:
fmul st0,st6 ; st0 x
; st6 x   st5  dokl-1  st4 0 <-mnoznik do tego!  st3 1(znaku)=0  st2 obliczenia=1   st1  1->mnoznik_obecnej_petli   st0 x
;odjac 1 od licznika i sprawdzic czy jest rowny zero.
fld1
fsubp st2,st0
; st6 x   st5  dokl-1  st4 0 <-mnoznik do tego!  st3 1(znaku)=0  st2 obliczenia=1   st1  0->mnoznik_obecnej_petli   st0 x
;porownanie wartosc licznika z zerem:
fldz
fcomp st2
; st6 x   st5  dokl-1  st4 0 <-mnoznik do tego!  st3 1(znaku)=0  st2 obliczenia=1   st1  0->mnoznik_obecnej_petli   st0 x
sahf
je licznik_rowny_zero
jmp potegowanie


licznik_rowny_zero:
;teraz mianownik i dzielimy:
fxch st1 ;zamian 'potegi' z licznikiem petli

; st6 x   st5  dokl-1  st4 0 <-mnoznik do tego!  st3 1(znaku)=0  st2 obliczenia=1  st1 x      st0  0->mnoznik_obecnej_petli  
;od nowa ustawiam nowy mnoznik biezacej petli
fld1
faddp st1,st0
fld1
faddp st1,st0
fmul st0,st4
fld1
faddp st1,st0
; st6 x   st5  dokl-1  st4 0 <-mnoznik do tego!  st3 1(znaku)=0  st2 obliczenia=1  st1 x      st0 mianownik:  2n+1 ->1
fdivp st1,st0
 ; st5 x   st4  dokl-1  st3 0 <-mnoznik do tego!  st2 1(znaku)=0  st1 obliczenia=1  st0 x/(2n+1)    
;fmulp st1,st0
;zabawa ze znakiem: jezeli bit_znaku = 0 liczba dodatnia, jezeli bit_znaku = 1 , liczba ujemna, zmieniamy znak


fld1
fcomp st3
sahf
je ujemna_jednak
jmp dodatnia_jednak
ujemna_jednak:
fchs ;zmieniam znak i tyle.

dodatnia_jednak:

faddp st1,st0
; st4 x   st3  dokl-1  st2 0 <-mnoznik do tego!  st1 1(znaku)=0  st0 obliczenia= x/(2n+1)    

; st4 x   st3  dokl-1  st2 0 <-mnoznik do tego!  st1 1(znaku)=0  st0  +/-  obliczenia= x/(2n+1)  
;obliczyłem 1-szy wyraz szeregu czas na sprawdzenie czy mnoznik_do_tego = dokladnosci wyrazow jakie chcemy:
fld1   ;st0 = 1
fmul st0,st3  ;st0 = st3
fcomp st4 ; 0 = dokl -1  ??
fstsw ax
sahf
fld1  ; dodajmy do mnoznika 1
faddp st3,st0

jne licz_kolejny_wyraz_szeregu

;fst dword dokl
;mov eax, dokl
leave                                  
ret                    

section .data
mnoznik:    dd 1.0
cos    dd 1.0

When I type accuracy > 2 (dokladnosc) program stops, and when I type 1 program returns -x, not x

I compile using these lines in nasm: (i am using gcc)

cd C:\Users\jaa\Desktop\infa\architektura\projekt2\moje takie

nasm -f coff p4.asm -o plik.o

set path=%pah%;C:\mingw\bin

gcc  p2.c -c -o plik1.o

gcc plik.o plik1.o -o plik.exe

i try to send ST0 to C as result , that is my goal

0

There are 0 best solutions below