2016-05-05 5 views
-4
; 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 

Breaks bei Anruf findCircumf mit Liste Fehlermeldung,Verfahren mit schwimmendem Punkten brechen

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). 

Ich weiß, ich habe etwas falsch gemacht. Ich gehe davon aus, dass es mit meiner Rückkehr zu tun hat. In der Prozedur ist der Reurn-Wert in ST (0). Ich bin mir nicht sicher, was ich falsch gemacht habe, ich verwende Fließkomma.

+1

Zuerst gibt es keine Rücksendeanweisungen am Ende der Prozedur (en). – GeekyDewd

+1

Wenn MASM kein "ret" für Sie einfügt, dann ist das ein Problem. Außerdem kehren deine Funktionen mit dem x87-Stack nicht leer zurück. Michael Petch und ich haben einige Intro-zu-x87-Antworten über [in einer anderen Frage] geschrieben (http://stackoverflow.com/q/36923943/224132). Außerdem gibt es eine 'fldpi'-Anweisung, die eine interne 66-Bit-Präzisionskonstante verwendet. Sie sollten 'pi' nur aus dem Speicher laden, wenn Sie eine vollständig korrekt gerundete 80-Bit-Konstante definieren wollen, und' fld tword [pi] 'verwenden. Es gibt auch eine 'fld1'-Anweisung zum Laden von 1.0. –

+1

Wie auch immer, es klingt wie Sie sollten Ihren Code in einem Debugger ausführen, und sehen, wo es stoppt. Die Tatsache, dass es irgendwo abgestürzt ist, sagt dir sehr wenig. Siehe den [FAQ-Bereich des x86-Tag-Wikis] (http://stackoverflow.com/tags/x86/info). Downvoted für nicht einmal die Zeit nehmen, einen Debugger zu verwenden und herauszufinden, wo der Code abstürzt oder was immer es tut. –

Antwort

-1

1.) Zunächst gibt es keine Rückmeldungen am Ende der Prozedur (en).

2.) Da ich Fließkomma UND STACK verwende, setze ich finit vor jedem Prozeduraufruf.

3.) I benötigen für jedes Verfahren, um einen Stapelrahmen in Beginn jeder Prozedur

push ebp    ; save base pointer 
mov  ebp, esp  ; establish stack frame 
push ebx    ; save EBX 

4.) Pop die Register aus dem Stapelrahmen vor der Rückkehr zu etablieren

pop  ebx    ; restore EBX 
pop  ebp    ; restore EBP 
ret      ; return 

Diese Dinge haben mein Problem gelöst.

+1

Sie brauchen nicht "finit", wenn Sie den x87-Stapel vor der Rückkehr aufräumen. (Verwenden Sie 'fmulp' anstelle von' fmul', zum Beispiel nach zwei 'fld's.) Wenn Sie mit zusätzlichen Sachen auf dem x87-Stapel zurückkehren, kann das zu Abstürzen an anderen Stellen im Code führen. 'finit' kann in diesem Fall als Workaround verwendet werden, da Ihr Programm einfach ist. –

+1

Wie auch immer, froh, dass Sie in der Lage waren, das Problem zu finden und zu beheben, indem Sie ein "ret" verpasst haben. –