0

Cプログラムから 2 つの変数のみを受け取り、最後に答えをプログラムに返すプログラムをアセンブリで作成しCました。アセンブリ ファイルの何が問題なのかを見つけるのに問題がありました。

私の目標は、FPU (nasm) を使用して、 をカウントするプログラムを作成することですarctg (x)。ここで、はユーザーが入力しxた の変数です。C2 番目の変数は精度なので、テイラー級数の整数の数です。

プログラム 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;
}

プログラム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

プログラムを入力 accuracy > 2 (dokladnosc)すると停止し、プログラムを入力すると1リターン-xではなくx

私はnasmでこれらの行を使用してコンパイルします:(私は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

結果としてST0をCに送信しようとします。それが私の目標です

4

0 に答える 0