Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly NASM汇编积分计算器_Assembly_Nasm_Integral - Fatal编程技术网

Assembly NASM汇编积分计算器

Assembly NASM汇编积分计算器,assembly,nasm,integral,Assembly,Nasm,Integral,我必须建立一个NASM汇编程序,它将使用1000个切片的梯形规则对a到b进行定积分。对于任何不知道这是什么的人来说,它是b-a/2N*(f(x)+2(f(x1)+2(f(x2))+…+2(f(xN))+2(f(xN+1)) f的函数是sin(x),所以每次迭代都必须有sin(x+interval(interval在我的代码中用'n'表示))取并乘以2。我必须在子例程中完全不使用特殊运算符或函数进行此操作。主函数只接受初始x值和结束x值的值,并将它们传递给子例程。子例程返回一个y值,它是函数的和。

我必须建立一个NASM汇编程序,它将使用1000个切片的梯形规则对a到b进行定积分。对于任何不知道这是什么的人来说,它是b-a/2N*(f(x)+2(f(x1)+2(f(x2))+…+2(f(xN))+2(f(xN+1))

f的函数是sin(x),所以每次迭代都必须有sin(x+interval(interval在我的代码中用'n'表示))取并乘以2。我必须在子例程中完全不使用特殊运算符或函数进行此操作。主函数只接受初始x值和结束x值的值,并将它们传递给子例程。子例程返回一个y值,它是函数的和。我让它至少在取将x的正弦值乘以2,并将其存储到下一个x的正弦值中,但最终经过大约30次循环后,它会给我一个

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

.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个多小时了,我已经没有主意了。

你确定这是NASM。代码似乎是MASM?x87基本上已经过时了,除了80位精度,64位双精度还不够。如果您使用的是64位临时变量,那么您就失去了x87相对于SSE/SSE2的唯一优势。(还要注意,
fsin
指令比好的数学库
sin
实现更慢、更不准确。不过,我认为准确度是。请参阅关于该线程的讨论,了解您可以预期的ULP错误数量)I,即使是不需要缩小范围的小参数也会发生这种情况。相比之下,FP mul/add/sub结果始终精确到0.5 ulp(即正确四舍五入).我认为glibc的libm实现的目标是在数学函数中达到这样的精度水平。这可能对你来说很重要,也可能不重要。我假设你这样做是作为一个asm学习练习,因为C会更容易。在未问问题的领域,这是带有Irvine库的NASM汇编程序。我没有问关于精度的问题,这不是iss我必须计算纸上的绝对和相对误差。NASM不使用您正在使用的语法。您确定没有将其与MASM(Microsoft Assembler)混淆。NASM不使用REAL8(或REAL4),它不理解
.code
.data
指令,并且不支持内存操作数上的
ptr
修饰符。但是,所有这些都可以与MASM一起使用