牛顿 - 装配中的拉夫森反演算法 [英] Newton - Raphson inversion algorithm in assembly

查看:37
本文介绍了牛顿 - 装配中的拉夫森反演算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据以下等式在组装中实现牛顿 - 拉夫森反演算法:

I am trying to implement Newton - Raphson inversion algotihm in assembly according to this equation:

Xn+1 = Xn(2-b*Xn)

我的功能是:

.data
const:
    .int 2
.text
.global inversion
inversion:
    pushl   %ebp
    movl    %esp, %ebp
    fldl    8(%ebp)         # load b
    fldl    12(%ebp)        # load X0
inv:    
    fst     %st(2)          # save Xn
    fmul    %st(1), %st(0)      # b*Xn
    fsubr   const           # 2-b*Xn
    fmul    %st(2), %st(0)      # Xn(2-b*Xn)
    fcomi   %st(2), %st(0)      # check if it the same result as before
jne inv                 # jump
                    # it should return the st(0)
leave
ret

还有我的 C 程序:

#include <stdio.h>

extern float inversion (float a, float b);

int main(void)
{
    float x = inversion (5,0.1);
    printf ("%f\n", x);
    return 0;
}

我的问题是这个函数不返回任何东西,当我用 gdb 调试它时,它显示我的函数永远不会停止,因为值永远不会相同.在我看来这是加载错误的数字,这是我在堆栈上加载数据后正在阅读的内容 (st(0), st(1), st(2)):

My problem is that this function doesn't return anything, and when I am debuggin it with gdb it shows that my function never stops, because values are never the same. In my opinion it's load bad numbers, it's what I am reading after loading data on stack (st(0), st(1), st(2)):

st0            2.6342588374767957140994886365053441e-314    (raw 0x3bed9ee6666680000000)
st1            5.2386907379892329317261356891322066e-11 (raw 0x3fdce6666a0500000000)
st2            2.6342588374767957140994886365053441e-314    (raw 0x3bed9ee6666680000000)

感谢您的所有回复.

推荐答案

是的,gdb 为您指明了正确的方向:您加载的参数是错误的.在处理浮点指令时,您使用了 fldl,其中 l 表示 double.我猜你认为 l 的意思是 4 bytes.要加载 4 字节浮点数,您需要 flds 指令.

Yes, gdb pointed you in the right direction: you are loading the arguments wrong. You used fldl where the l means double when dealing with floating point instructions. I guess you thought the l meant 4 bytes. To load 4 byte floats you need the flds instruction.

此外,fsubr 需要一个浮点数,但你给它一个整数.解决方法:将.int 2改为.float 2.为了安全起见,还要更改为 fsubrs(尽管这是默认设置).

Furthermore, fsubr expects a floating point number but you give it an integer. Solution: change .int 2 to .float 2. Also change to fsubrs for safety (although that is the default).

最后,您在 fpu 堆栈上留下了 3 个值,这不符合预期的调用约定,并且可能会在以后导致问题.您应该只将返回值留在那里.

Finally, you are leaving 3 values on the fpu stack, which is not according to the expected calling convention and can cause problems later. You should only leave the return value there.

这篇关于牛顿 - 装配中的拉夫森反演算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆