Я ищу реализацию pow(real, real)
в x86 Assembly. Также я хотел бы понять, как работает алгоритм.Практическое руководство: pow (real, real) in x86
ответ
Просто вычислите его как 2^(y*log2(x))
.
Существует инструкция x86 FYL2X для вычисления y * log2 (x) и инструкции x86 F86X1 для выполнения возведения в степень. F2XM1 требует аргумента в диапазоне [-1,1], поэтому вам нужно будет добавить некоторый код между ними, чтобы извлечь целую часть и оставшуюся часть, увеличив остаток, используйте FSCALE для масштабирования результата с соответствующей мощностью 2.
+1 Такой простой, изящный ответ! – templatetypedef
Супер, спасибо за обмен и приятное воскресенье. –
Я знаю, что это старый поток, но вот реализация: [madwizard.org] (http://www.madwizard.org/programming/snippets?id=36) – Matth
OK, я внедрил power(double a, double b, double * result);
в x86 так же, как вы рекомендовали.
Код: http://pastebin.com/VWfE9CZT
%define a QWORD [ebp+8]
%define b QWORD [ebp+16]
%define result DWORD [ebp+24]
%define ctrlWord WORD [ebp-2]
%define tmp DWORD [ebp-6]
segment .text
global power
power:
push ebp
mov ebp, esp
sub esp, 6
push ebx
fstcw ctrlWord
or ctrlWord, 110000000000b
fldcw ctrlWord
fld b
fld a
fyl2x
fist tmp
fild tmp
fsub
f2xm1
fld1
fadd
fild tmp
fxch
fscale
mov ebx, result
fst QWORD [ebx]
pop ebx
mov esp, ebp
pop ebp
ret
Могу ли я рекомендовать вам продолжить и включить этот код здесь, в вашем ответе? –
Готово, в комплекте. –
Вы должны 'sub esp, 8', чтобы выровнять его для нажатия ebx. Вы также можете поменять tmp и ControlWord, например. '% define tmp DWORD [ebp-4]', поэтому он выровнен. –
вы используете x87 или SSE? –
реализация glibc функции 'pow()' [в sysdeps/ieee754/dbl-64/e_pow.c] (http://repo.or.cz/glibc.git/blob/HEAD:/sysdeps/ieee754/ ДВМ-64/e_pow.c). Он использует некоторое целочисленное исследование битовых шаблонов FP, а некоторые FP умножает и добавляет, но не использует никаких специальных инструкций x87. Для x86-64 он скомпилируется в '__ieee754_pow_sse2()' ([этим кодом, который # включает его] (http://repo.or.cz/glibc.git/blob/455d6e4373c81da49892d39f33dc312b0c54097d:/sysdeps/x86_64/fpu/ мультиархитектурная/e_pow.c)). Во всяком случае, x87 - это не лучший способ сделать это на современных процессорах. –
Я предполагаю, что код glibc является более точным или быстрее, чем x87. Возможно, и то и другое, но, возможно, просто более точное (правильно округленное до ближайшего). Он не использует цикл, хотя и однократный по инструкциям, для * pow (1.175, 33.75) 'не существует * * *. FYL2X - очень медленная команда (~ 100 циклов) на современных процессорах, поэтому ее не должно бить так сложно. –