assembly - 汇编 x86 x87 数字处理器
问题描述
for(i=0; x1 + i*h <= x2; i++)
每次我调用另一个使用 (x1 + i*h) 作为其参数之一的函数时,由于某种原因,它会在接收它时加上 0.00000000000000001。例如,如果我发送它 0.26,它会收到 0.26000000000000001,这最终导致程序崩溃。
这是程序的C部分:
#include <stdio.h>
#include <math.h>
extern double find_delta1(double(*f)(double), double x0, double eps);
extern double find_delta2(double(*f)(double), double x1, double x2, double h, double eps);
double mysqr(double x)
{
return x*x;
} // mysqr
int main()
{
double x1 = -0.5, x2 = 1.0, x, eps = 0.001, h = 0.01;
x = (x1 + x2) / 2.0;
printf("\nfind_delta1(mysqr,%lf, %lf) = %lf\n", x, eps, find_delta1(mysqr, x, eps));
printf("\nfind_delta2(mysqr, %lf, %lf,%lf, %lf) = %lf\n", x, x2, h, eps, find_delta2(mysqr, x, x2, h, eps));
return 0;
} // main
这是组装部分:
.MODEL SMALL
.DATA
DELTA DQ ?
CURRENTX DQ ?
TEMP DQ ?
MIN DQ ?
X DQ ?
I DW ?
TWO DQ 2.0
.CODE
.386
.387
;double find_delta1(double (*f)(double),double x0, double eps)
; +4 +6 +14
PUBLIC _find_delta1
_find_delta1 PROC NEAR
PUSH BP
MOV BP,SP
FLDZ ;
FST X ;
FSTP DELTA ; Initialize parameters
FLD QWORD PTR [BP+6] ;
FABS ;
FSTP DELTA ; Delta = |X0|
LOOP1:
FLD DELTA
FDIV TWO ;
FST DELTA ; Delta = Delta / 2.0
FLD QWORD PTR [BP+6] ;
FADD ;
FSTP X ; X = X0 + Delta
PUSH X ;
CALL WORD PTR [BP+4] ;
ADD SP,8 ; ST(0) = f(X)
PUSH QWORD PTR [BP+6] ;
CALL WORD PTR [BP+4] ;
ADD SP,8 ; ST(0) = f(X0)
FSUB ;
FABS ; ST(0) = |f(X) - f(X0)|
FCOMP QWORD PTR [BP+14] ;
FSTSW AX ;
SAHF ; Compare with epsilon
JNB LOOP1
FLD DELTA ; Return Delta
POP BP
RET
_find_delta1 ENDP
;----------------------------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------------------------
;double find_delta2(double (*f)(double),double x1, double x2, double h, double eps)
; +4 +6 +14 +22 +30
PUBLIC _find_delta2
_find_delta2 PROC NEAR
PUSH BP
MOV BP,SP
MOV I,0
FLDZ ;
FST TEMP ;
FST CURRENTX ;
FSTP MIN ; Initialize parameters
PUSH QWORD PTR [BP+30] ;
PUSH QWORD PTR [BP+6] ;
PUSH WORD PTR [BP+4] ;
CALL _find_delta1 ;
ADD SP,20 ; MIN = find_delta1(mysqr, X1, eps)
FSTP MIN
LOOP2:
FLD QWORD PTR [BP+6] ; ST(0) = X1
FLD QWORD PTR [BP+22] ; ST(0) = h
FIMUL I ; ST(0) = I*h
FADD ; ST(0) = X1 + I*h
FSTP CURRENTX
PUSH QWORD PTR [BP+30] ;
PUSH CURRENTX ;
PUSH WORD PTR [BP+4] ;
CALL _find_delta1 ;
ADD SP,20 ; ST(0) = find_delta1(mysqr, X1 + I*h, eps)
FCOM MIN ;
FSTSW AX ;
SAHF ;
JNB NOTBELOW ; Compare with current minimum
FSTP MIN ; If (find_delta1(mysqr, X1 + I*h, eps) < MIN)
INC I ; -> MIN = find_delta1(mysqr, X1 + I*h, eps)
JMP SHORT NEXT ; i++
NOTBELOW: ; Else
FSTP TEMP ; -> i++
INC I ;
NEXT:
FLD CURRENTX
FCOMP QWORD PTR [BP+14] ;
FSTSW AX ;
SAHF ;
JNE LOOP2 ; Compare (X1 + I*h) with X2
FLD MIN
POP BP
RET
_find_delta2 ENDP
END
问题出现在 LOOP2 的第二次迭代中,因为第一次 I*h = 0,因此没有对 x1 应用任何更改。
如果有人能告诉我我做错了什么,我将不胜感激。
解决方案
推荐阅读
- python - Django:如何显示两个或三个模型的数据
- java - 无法加载 servlet 过滤器类:com.sap.cloud.sdk.cloudplatform.security.servlet.HttpSecurityHeadersFilter (SCP Neo)
- javascript - next 和 JWT 认证组件
- amazon-web-services - 当我启动 AWS Cloudformation 并注销我的账户时会发生什么?
- android - 过滤后listview在点击时给出错误的项目
- go - 如何分叉一个go项目?
- javascript - 手动设置网页链接
- android - room kotlin 通过 val 从另一个片段查询项目列表
- parsing - Scrapy Spider 抓取错误数据
- ios - 如何将 Swift 算术运算符加号 (+) 正确编码为 utf8 数据?