Алгоритм обращения Ньютона - Рафсона в сборке
Я пытаюсь реализовать инверсию Ньютона - Рафсона 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, что не соответствует ожидаемому соглашению о вызовах и может вызвать проблемы позже. Вы должны только оставить возвращаемое значение там.