NASM装配积分计算器

时间:2016-03-24 06:24:05

标签: assembly nasm integral

我必须构建一个NASM汇编程序,它将使用具有1000个切片的梯形规则获取a到b的定积分。对于那些不知道那是什么的人,它是ba / 2N *(f(x)+ 2(f(x1)+ 2(f(x2))+ ... + 2(f (xN))+ 2(f(xN + 1))。

f的函数是sin(x),因此每次迭代必须具有(x +间隔(间隔由我的代码中的' n'表示))并且乘以2的罪。我有完全不使用特殊操作符或函数在子例程中执行此操作。 main函数仅接受初始x值和结束x值的值,并将它们传递给子例程。子例程返回y值,该值是函数的总和。我得到它至少可以使用x的正弦并将其乘以2并存储它以添加到x的下一个正弦,但最终在循环之后的30次左右迭代之后,它给了我NaN ..

以下是我的代码到目前为止的子程序:

.data

two             REAL8   2.0
half            REAL8   0.5 
x               REAL8   ?
n               REAL8   ?
i               dword   1000
thos            REAL8   1000.0
sum             REAL8   0.0
sum2            REAL8   ?
sum3            REAL8   ?

.code
integral1   PROC

PARAMS = 2*TYPE DWORD
NPARAMS = 3
x2$ = PARAMS+0*TYPE DWORD
x1$ = PARAMS+1*TYPE DWORD
y$  = PARAMS+2*TYPE DWORD

pushfd
;BELOW: Calculate interval
mov     ebx,x2$[esp]
fld     REAL8 PTR [ebx]

mov     ebx,x1$[esp]
fld     REAL8 PTR [ebx]
fsub
fdiv    thos
fstp    n

;BELOW: calculate 1/2 of interval per trapezoidal rule
fld     n
fld     half
fdiv
fstp    half
;BELOW: load 1000 into counter register and store x variable
mov     ecx,i
fld     REAL8 PTR [x1]
fstp    x
;BELOW: f(x) calculation
fld     REAL8 PTR [x]
fsin
fstp    sum2


for_loop:
fld     REAL8 PTR [x]
;load x onto stack
fld     REAL8 PTR [n]
;load interval onto stack
fadd
;add x and interval
fst     x
;store value in x for later use
fsin
;take sine of x
fmul    two
;multiply by 2 to get 2(f(x))
fst     sum3
;store value in arbitrary variable
fld     sum
;load current total of functions
fadd
;add sum3 to sum
fst     sum
;store sum and loop

cmp     ecx,0
je      end_for
dec     ecx
jmp     for_loop

end_for:
fld     REAL8 PTR [sum]
fmul    half
;multiply sum by 1/2
fadd    sum2
;add sine(x) to total before pushing back to main
mov     ebx,y$[esp]
fstp    REAL8 PTR [ebx]
popfd
ret NPARAMS*TYPE DWORD

integral1   ENDP

END main

如果有人能帮助我理解为什么会这样做,或者我的错误在哪里,或者如何纠正,我将永远感激不尽。我已经工作了6个多小时,而且我没有想法。

0 个答案:

没有答案