2016-04-02 9 views
0

次回のプロジェクトが来週になり、最後の2日間はn番目のルートの作成方法を考え出しています。x86アセンブリ(NASM)分数を使ってn番目の浮動小数点数を浮動小数点数にする方法

アセンブリNASMの幾何平均をシミュレートする必要があります。

私はFPUが平方根のための命令を持っていることを知っていますが、それは実際にはそれほど遠くはありません。

現在、私は必要なだけ多くの入力を入力できますが、問題なくそれらを乗算します。しかし、私はNASMでそれをやる方法がわからないので、「n番目の根源」の部分に固執します。

これは私の現在のコードです:

global _main 
    extern _printf, _scanf, _system 

    section .text 

    _main: 
    mov ebp, esp; for correct debugging 
push clr 
call _system 
add esp, 4 

    ; start of INITIALIZE 
    ;printf("Enter number of elements") 
push print1 
call _printf 
add esp, 4 
    ; scanf number of elements 
push n 
push scan1 
call _scanf 
add esp, 8 

    ; printf("enter n integers") 
    push dword [n] 
push print2 
call _printf 
add esp, 8 

    fld qword [n2] 


    ; scan first element 
    push n2 
    push scan2 
    call _scanf 
    add esp, 8 

    fld qword [n2] 

    JE J1 

    MOV EBX, 1 

    CMP EBX, [n] 
    JE J1 

    L1: 

    push n2 
    push scan2 
    call _scanf 
    add esp, 8 

    fld qword [n2] 
    fmul st1, st0 
    fstp qword [ans] 

    INC EBX 
    CMP EBX, dword [n] 
    JE J1 
    LOOP L1 

    J1: 

    fst qword [ans] 

    push dword [ans+4] 
    push dword [ans] 
    push print3 
    call _printf 
    add esp, 12 

    mov dword [data8], n 

    fld qword [data7] 
    fld qword [data8] 

    fdiv st1, st0 

    fstp qword [ans] 


    fst qword [ans] 

    push dword [ans+4] 
    push dword [ans] 
    push print3 
    call _printf 
    add esp, 12 

    xor eax, eax 
    ret 

    section .data 
    clr  db "cls", 0 
    print1 db "Enter the number of elements:", 13,10,0 
    scan1 db "%d" , 0 
    scan2 db "%lf" , 0 
    n  dd 0 
    n2  dq 0.0 
    n3  dq 0.0 
    print2 db "Enter %d values:", 13,10,0 
    print3 db "Value is %g", 13, 10,0 
    data8 dq 3.0 
    ans  dq 0.0 
    loopstart dq 1.0 
    data7 dq 1.0 

それとも、n番目の根を抽出するための外部C関数を使用することも可能ですか?

EDIT:Cから_powを使用しようとしていますが、このコードがありますが、誰かを助けることができません。

 LEA ESI, [return] 

     push ESI 
     push dword [pushingthing+4] 
     push dword [pushingthing] 
     push dword [ans+4] 
     push dword [ans] 
     push pow1 
     call _pow 
     add esp, 24 

     section .data 

     return dq 0.0 
     pushingthing dq 2.0 
     pow1  dd "%g, %g", 13, 10, 0 

これは、pow(C)の形式がpow(x、y)の形式で、両方ともdoubleであり、double値を返すためです。チェックしてください。

+0

確かに、 'n'番目の根が' 1/n'の力と同じであることを知っているC 'pow'関数を使うことができます。アセンブリでは、対数を使用できます。 – Jester

+0

私はまだ浮動小数点値を返す値を持つC関数にプッシュする方法をまだよく分かりません。あなたは私に教えることが可能ですか?私は解決のためにインターネットの周りを検索してきましたが、私は困惑しています。 –

+0

これはあなたのプラットフォームの呼び出し規約(あなたが言及していない)で説明されています。一般的には、入力引数をcpuスタックに渡し、結果を 'st(0)'に戻します。 – Jester

答えて

4

pushを使用すると、引数を渡すことができます。特にダブルスは、すべての反転と半分で頭が痛くなります:)スペースを割り当てて、適切なmov命令を使用するだけです。あなたはまだあなたがどのような環境にいるのかは言いませんでしたが、そのほとんどは結果をst(0)(すなわち浮動小数点スタック)に返します。そのような例は次のようになります:

sub esp, 16   ; space for 2 doubles 
fld qword [x]  ; load 1st arg 
fstp qword [esp]  ; write to stack 
fld qword [y]  ; load 2nd arg 
fstp qword [esp+8] ; write to stack 
call _pow 
; result is now in st(0) print it 
mov dword [esp], fmt ; format string 
fstp qword [esp+4] ; pass result as arg 
call _printf 
add esp, 16   ; free stack space 

x: dq 16.0 
y: dq 0.25 
fmt: db "%g", 13, 10, 0 
+0

ホーリー・モリーそれは働く。ありがとう、あなたは間違いなく私の隠しを今保存しています。 –

関連する問題