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