Алгоритм обращения Ньютона - Рафсона в сборке

Я пытаюсь реализовать инверсию Ньютона - Рафсона algotihm в сборке в соответствии с этим уравнением:

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)):

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

Спасибо за все ваши ответы.

1 ответ

Решение

Да, gdb указал вам в правильном направлении: вы загружаете аргументы неправильно. Ты использовал fldl где l средства double при работе с инструкциями с плавающей запятой. Я думаю, вы думали l означало 4 bytes, Для загрузки 4-х байтовых операций вам нужно flds инструкция.

Более того, fsubr ожидает число с плавающей запятой, но вы даете ему целое число. Решение: изменить .int 2 в .float 2, Также измените на fsubrs для безопасности (хотя это по умолчанию).

Наконец, вы оставляете 3 значения в стеке fpu, что не соответствует ожидаемому соглашению о вызовах и может вызвать проблемы позже. Вы должны только оставить возвращаемое значение там.

Другие вопросы по тегам