이 프로그램 아래에 있습니다. 내 어셈블리 루틴이 멈추는 것을 찾을 수없는 이유가 있습니다.이유없이 x86 어셈블리 루틴이 멈췄습니다.
나는 이미 SP
을 확인했으며 코드는 올바른 위치로 돌아가고 스택은 항상 그렇듯이 돌아갑니다.
루틴이 걸리지 않도록 한 가지 일은 JNL
으로 점프를 변경하는 것이 었습니다. 다른 점프로 인해 달라 붙습니다.
이것은 C 및 어셈블리의 코드입니다. 결국에는 어셈블리 루틴이 수행해야하는 것을 보여주는 C 코드가 있습니다.
#include <stdio.h>
#include <math.h>
#include <conio.h>
extern void two_point (double (*f1)(double, double), double (*f2)(double, double), double x, double y, double *ptr1, double *ptr2);
extern void fixed2 (double (*f1)(double, double), double (*f2)(double, double), double x0, double y0, double *ptr1, double *ptr2, double eps);
double f1 (double x, double y);
double f2 (double x, double y);
int main()
{
double x, y;
fixed2 (f1, f2, 1.4, 1.4, &x, &y, 0.001);
printf ("x= %lf, y= %lf\n", x, y);
return 0;
}
double f1 (double x, double y)
{
return sin (x+y);
}
double f2 (double x, double y)
{
return cos (x+y);
}
ASM의 CODE :
;HW4a.asm
.MODEL SMALL
.DATA
x0 DQ ?
x1 DQ ?
y0 DQ ?
y1 DQ ?
x2 DQ ?
y2 DQ ?
element DW 16;double*2
.CODE
.386
.387
;two_point (double (*f1)(double, double), double (*f2)(double, double), double x, double y, double *ptr1, double *ptr2)
;f1=BP+4, f2=BP+6, x=BP+8, y=BP+16, ptr1=BP+24, ptr2=BP+26
_two_point PROC NEAR
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
MOV SI,WORD PTR[BP+24]
MOV DI,WORD PTR[BP+26]
FLD QWORD PTR [BP+16];ST0=Y
FSTP y2
FLD QWORD PTR [BP+8];ST0=X
FSTP x2
PUSH DWORD PTR y2+4
PUSH DWORD PTR y2
PUSH DWORD PTR x2+4
PUSH DWORD PTR x2
;f1:
CALL [BP+4];CALL F1
FSTP QWORD PTR [SI];SI GET RETURNED VALUE FROM F1
MOV [BP+24],SI;PTR1=F1(X,Y)
;f2:
CALL [BP+6];CALL F2
FSTP QWORD PTR [DI];DI GET RETURNED VALUE FROM F2
MOV [BP+26],DI;PTR2=F2(X,Y)
;end:
ADD SP,element
POP DI
POP SI
POP BP
RET
_two_point ENDP
;fixed2 (double (*f1)(double, double), double (*f2)(double, double), double x0, double y0, double *ptr1, double *ptr2, double eps)
;f1=BP+4, f2=BP+6, x0=BP+8, y0=BP+16, ptr1=BP+24, ptr2=BP+26, eps=BP+28
PUBLIC _fixed2
_fixed2 PROC NEAR
PUSH BP
MOV BP,SP
;pre loop:
PUSH SI
PUSH DI
MOV SI,WORD PTR[BP+24];SI=&ptr1
MOV DI,WORD PTR[BP+26];DI=&ptr2
FLD QWORD PTR [BP+16];ST0=Y
FST y0
FSTP y1
FLD QWORD PTR [BP+8];ST0=X
FST x0
FSTP x1
LOOPER:
FLD y1
FST y0;y0=y1
FSTP QWORD PTR [DI];SI=&y1
PUSH WORD PTR DI;push &y1
FLD x1
FST x0;x0=x1
FSTP QWORD PTR [SI];SI=&x1
PUSH WORD PTR SI;push &x1
PUSH DWORD PTR y0+4
PUSH DWORD PTR y0
PUSH DWORD PTR x0+4
PUSH DWORD PTR x0
PUSH WORD PTR [BP+6];push f2
PUSH WORD PTR [BP+4];push f1
CALL _two_point
MOV DI,WORD PTR [BP-6];DI=&y0
MOV SI,WORD PTR [BP-8];SI=&x0
ADD SP,8;sizeof(f1+f2)+sizeof(*ptr1+*ptr2)
ADD SP,element
FLD QWORD PTR [SI];load x1
FST x1
FLD x0
FSUB
FABS;|x1-x0|
FLD QWORD PTR [DI];load y1
FST y1
FLD y0
FSUB
FABS;|y1-y0|
FADD;ST[0]=|y1-y0|+|x1-x0|
FLD QWORD PTR [BP+28];ST[0]=eps
FCOMPP;ST[0]-ST[1]
FSTSW AX
SAHF
JBE LOOPER;while ((fabs(x1-x0) + fabs(y1-y0))>=eps)
;end:
FLD x1
FSTP QWORD PTR [SI]
MOV WORD PTR [BP+24],SI;update *ptr1=x1
FLD y1
FSTP QWORD PTR [DI]
MOV WORD PTR [BP+26],DI;update *ptr2=y1
POP DI
POP SI
POP BP
RET
_fixed2 ENDP
END
이는 ASM가해야 할 일이다
void fixed2 (double (*f1)(double, double), double (*f2)(double, double), double x0, double y0, double *ptr1, double *ptr2, double eps)
{
double x1= x0, y1= y0;
do
{
x0= x1;
y0= y1;
two_point (f1, f2, x0, y0, &x1, &y1);
} while ((fabs(x1-x0) + fabs(y1-y0))>=eps);
*ptr1 = x1;
*ptr2 = y1;
}
F1 및 F2는 :
double f1 (double x, double y)
{
return sin (x+y);
}
double f2 (double x, double y)
{
return cos (x+y);
}
코드에서 오류를 발견하도록 다른 사람에게 질문하는 것은 생산성이 떨어집니다. 디버거에서 코드를 단계별로 실행해야합니다. 그러면 당신은 그것이 정확히 "붙어있는"곳을 발견 할 것입니다. –
날 믿어, 내가 마지막 3 일 동안 디버거에 살았어, 아직도 찾을 수 없습니다. ( 내가 볼 수 있듯이 나는 SP를 확인했다. 디버거에서보아야한다는 것을 의미한다. – shimon
글쎄, 그것은 확실히 붙어 있지 않다. 이유가 무엇인지 알아 내기 위해 디버그해야합니다. – Saggio