# #c #assembly #x86 #x87
#c #собрание #x86 #x87
Вопрос:
Проблема в том, что я получаю бесконечные значения после связывания и выполнения. Мне нужно решить интеграл от(sin(100*x)/x) на интервале [0,5] методом Симпсона. Файл на C использует модуль NASM для выполнения вычислений. Как это исправить?
C: основная программа
#include lt;stdio.hgt; float sum(float a, float b); float fx(float x); int main() { float res = 0; float a = 0; float b = 3; float h = 0; float tmp1 = 0; float tmp2 = 0; float tmp3 = 0; float n = 5; float res2 = 0; h = (b - a)/n; for(int i = 0; i lt; n; i = i 1){ tmp1 = a i*h; tmp2 = a (i 1)*h; tmp3 = (tmp2-tmp1)/6.0*(fx(tmp1) 4 * fx(0.5 * (tmp1 tmp2)) fx(tmp2)); res = sum(res,tmp3); printf("%fn", res); } printf("%fn", res); return 0; }
ASM: модуль на ассемблере (NASM)
global sum global fx section .data section .bss temp: resb 4 section .text ; float Fint(float x, float y) ; return x y sum: finit fld dword [esp 8] ; st0 = x fadd dword [esp 4] ; st0 = y ret ; returns st0 to c ; float fx(float x) ; return sin(100*x)/x SinX: fld qword [eax] fsin fstp qword [ebx] ret fx: ; st1 100*x fld dword [esp 4] ; st1 = x mov dword [temp], 100 fmul dword [temp] ; st1 *= 100 ;sin(100*x) ;call SinX fsin ; st0 mov dword [temp], 1 fild dword [temp] ; st0 = 1 fdiv st0, st1 ; st0 /= st1 ret ;returns st0 to c
(проблема!)Результат: инф -инф — инф-инф-инф
Комментарии:
1. Вы можете начать с того, что избавитесь от
finit
входаsum
.2. @1201ProgramAlarm: Тогда им нужно сбалансировать свои толчки и хлопки, чтобы не переполнять очень ограниченный стек с плавающей запятой.
3. Есть ли какая-то особая причина, по которой вы пишете код x87? SSE намного удобнее и эффективнее и поддерживается практически всеми процессорами x86, выпущенными за последние 20 лет. Если это не обязательно должно быть в сборке, вы, вероятно, сделаете еще лучше, просто переписав на C; современные компиляторы довольно хорошо справляются с такими вещами.
4. О, я понимаю почему, потому что вы хотите иметь возможность использовать аппаратное
fsin
обеспечение ; правда, у SSE этого нет. Но в наши дни, вероятно, быстрее просто вызвать функцию библиотекиsin
.fsin
Инструкция редко используется и, следовательно, плохо оптимизирована в аппаратном обеспечении.