Function 带浮点中断的过程

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

调用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)

; 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
的问题。