Function 带浮点中断的过程
调用findCircumf时中断,错误列表为Function 带浮点中断的过程,function,assembly,stack,Function,Assembly,Stack,调用findCircumf时中断,错误列表为 ; Author: ; Date: ; This is the Visual Studio 2012 version ; Preprocessor directives .586 ; use the 80586 set of instructions .MODEL FLAT ; use the flat memory model (only 32 bit addresses, no segment:offset) ; Externa
; Author:
; Date:
; This is the Visual Studio 2012 version
; Preprocessor directives
.586 ; use the 80586 set of instructions
.MODEL FLAT ; use the flat memory model (only 32 bit addresses, no segment:offset)
; External source files
INCLUDE io.h ; header file for input/output
INCLUDE fio.h ; header file for floating point conversions to and from ASCII
; Stack configuration
.STACK 4096 ; allocate 4096 bytes for the stack
; Named memory allocation and initialization
; Use REAL4 for floating point values
.DATA
prompt1 BYTE "Enter circumference: ", 0 ; Basic prompt
string BYTE 40 DUP (?)
BoxLabel1 BYTE "The radius is "
radius BYTE 12 DUP (?), 0
msg1 BYTE "The circle circumference is: ", 0ah
circumf2 BYTE 12 DUP (?), 0ah
msg2 BYTE "The circle area is: ", 0ah
area2 BYTE 12 DUP (?), 0
radiusInput REAL4 1.0
pi REAL4 3.14
two REAL4 2.0
areA REAL4 1.0
circumf REAL4 1.0
; procedure definitions
.CODE
_MainProc PROC
;************ INPUT *************
input prompt1, string, 40 ; read ASCII characters
atof radiusInput, string ; Convert (ASCII TO FLOAT) macro
;********************************
finit
push radiusInput
call findCircumf ; BREAKS HERE!!!!
; call findArea
;done:
;************ OUTPUT ************
ftoa radius, radiusInput
ftoa area2, areA
ftoa circumf2, circumf
output BoxLabel1, msg1
;********************************
;*********** CLEAN-UP ***********
mov EAX, 0 ; exit with return code 0
ret
;********************************
_MainProc ENDP
;##################### findCircumf PROCEDURE ##################
findCircumf PROC
; ******** CIRCUMFERENCE ********
; Formula 2*Pi*R
fld two ; ST(0) has 2.0
fld pi ; ST(0) has 3.14 ST(1) 2.0
fmul st(0), st(1) ; ST(0) has 6.28 2*Pi
fld radiusInput ; ST(0) has radius input (3.5) ST(1) has 6.28
fmul ST(0), ST(1) ; ST(0) has 21.98 2*Pi*R
fst circumf
;********************************
findCircumf ENDP
;###################### findArea PROCEDURE #####################
findArea PROC
;************ AREA **************
; Forumla R*R*Pi
fld radiusInput ; ST(0) has radius input (3.5)
fmul st(0), st(0) ; ST(0) has 12.25 R*R (or R^2)
fld pi ; ST(0) has 3.14 ST(1) has 12.25
fmul st(0), st(1) ; ST(0) has 38.465 R*R*Pi
fstp areA ; areA has 38.465
;********************************
findArea ENDP
END ; end of source code
我知道我做错了什么。我想这与我的回归有关。
在该过程中,reurn值以ST(0)表示。我不确定我做错了什么,我使用的是浮点。1。)首先,过程末尾没有返回语句 2.)因为我使用浮点和堆栈,所以我在每个过程调用之前都使用finit 3.)我需要在每个过程开始时建立堆栈框架
windows32.exe has triggered a breakpoint.
The thread 0x1570 has exited with code 0 (0x0).
The program '[628] windows32.exe' has exited with code 0 (0x0).
push ebp ; save base pointer
mov ebp, esp ; establish stack frame
push ebx ; save EBX
4.)在每个过程返回之前,从堆栈帧弹出寄存器
windows32.exe has triggered a breakpoint.
The thread 0x1570 has exited with code 0 (0x0).
The program '[628] windows32.exe' has exited with code 0 (0x0).
push ebp ; save base pointer
mov ebp, esp ; establish stack frame
push ebx ; save EBX
这些事情解决了我的问题。首先,在过程结束时没有返回语句。如果MASM没有为您插入
ret
,那么这就是一个问题。此外,函数返回时x87堆栈不是空的。迈克尔·佩奇和我写了一些关于x87的介绍。除此之外,还有一条fldpi
指令,它使用一个内部66位精度常数。如果要将其定义为一个完全正确舍入的80位常量并使用fld tword[pi]
,则只应从内存中加载pi
。还有一条fld1
指令要加载1.0。无论如何,听起来你应该在调试器中运行你的代码,看看它停在哪里。它在某处坠毁的事实告诉你很少。看。不赞成甚至不花时间使用调试器并找出代码崩溃的地方或它在做什么。等一下,你是问我链接的另一个问题的人,这个问题的弹出量没有你在x87堆栈上推的那么多。是否有多人使用您的帐户?你为什么对自己的问题留下评论?根据你的回答,call
指令本身并不是错误所在。正如我所说,您没有显示哪条指令实际上是错误的,只是在它发生之前的某个点。如果您在返回之前清理x87堆栈,则不需要finit
。(例如,在两个fld
s之后使用fmulp
而不是fmul
。)在x87堆栈上使用额外内容返回可能会导致代码中其他地方的崩溃finit
在这种情况下可以用作解决方法,因为您的程序很简单。无论如何,很高兴您能够跟踪并修复缺少ret
的问题。