2016-04-02 123 views
0

我有一个即将到来的项目下周,我已经花了最后2天计算出如何做一个n根。x86汇编(NASM)如何nth根或提高浮点值与分数

我需要在装配NASM中模拟几何平均值。

我知道FPU有一个Square Rooting的指令,但是这并不会让我感到非常失望。

目前,我可以根据需要输入尽可能多的输入,并将它们相乘无任何问题。但是我被卡在'第n根'部分,因为我不知道如何与NASM做。

这是我当前的代码:

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 

或者它也可以使用外部的C函数用于提取n次方根?

编辑:试图使用从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)的格式,其是双键和返回双精度值。请检查。

+0

当然,你可以使用C'pow'功能知道'N'次方根是相同功率的'1/N'。在组装中,您可以使用对数。 – 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

圣莫里它的工作原理。谢谢你,你现在肯定会救我的皮。 –