I'm doing an assignment for school and this week we are working with procedure calling and stack pushing and popping.
The procedure I wrote is a square root function and all the calculations work but when the program quits it crashes.
As far as I can tell, but I can't say for sure, the program is exiting with values still on the stack. I don't know how to check for something like that but if I comment out the push, call, and pop in the main section of the code it doesn't crash. I'm running on windows7 btw. I read a lot of posts talking about interrupts causing errors but I can't see how that's an issue here. I've been racking my brain for the past 4 hours and it's due tonight. Thanks for any help you can offer.
.386
.model flat,stdcall
option casemap:none
include \masm32\include\msvcrt.inc
includelib \masm32\lib\msvcrt.lib
.data ;data segment
aSquares dd 36, 169, 9801, 51984, 105625
PrintRoot db 'sqrt(%d) = %d', 10, 0
QuitLine db 'Press any key to quit.', 0
sqrt_val equ 8[EBP]
sqrt_ret equ 16[EBP]
.code ;code segment
;Square root function ~~~~~~~~~
sqrt proc near
push EBP
mov EBP, ESP
push EAX
push ECX
;Set up variables for rootLooping
mov EAX, sqrt_val
mov ECX, 0
mov ESI, 1
rootLoop: ;Calculates the square root
sub EAX, ESI
add ESI, 2
inc ECX
cmp EAX, 0 ;if EAX > 0 keep looping
ja rootLoop
mov sqrt_ret, ECX
pop ECX
pop EAX
pop EBP
ret 8
sqrt endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
start:
;int 3
mov ECX, 0
loadLoop:
lea EBX, aSquares
mov ESI, ECX
add ESI, ESI
add ESI, ESI
mov EDX, [EBX][ESI]
push EAX
push EDX
call sqrt
pop EAX
pushad
invoke crt_printf, addr PrintRoot, EDX, EAX
popad
inc ECX
cmp ECX, 5
jl loadLoop
pushad
invoke crt_printf, addr QuitLine
popad
;pushad
;invoke crt__getch
;popad
end start
without looking at the whole thing, i can see that you are missing a call to ExitProcess
;
;
pushad
invoke crt_printf, addr QuitLine
popad
;pushad
;invoke crt__getch
;popad
INVOKE ExitProcess,0
end start
or, the masm32 package has a macro that saves you a little typing
;
;
pushad
invoke crt_printf, addr QuitLine
popad
;pushad
;invoke crt__getch
;popad
exit
end start
nice job on the rest of it :U
When you exit a program you need to use ExitProcess(). See if that cleans it up for you. Also your code needs to properly preserve the required registers EBX, ESI & EDI where they are used as you are interfacing with MSVCRT which is fully Intel ABI compliant with its register usage.
Well I included the following:
include \masm32\include\masm32rt.inc
include \masm32\macros\macros.asm
and called:
exit
Now it works perfectly fine. Thankyou very much. My teacher never mentioned the exit protocol so I didn't even know it existed.
Just note that the "exit" macro is a wrapper for ExitProcess().
Quote from: lmanrodt on October 24, 2011, 12:27:36 AM
Well I included the following:
include \masm32\include\masm32rt.inc
include \masm32\macros\macros.asm
and called:
exit
Now it works perfectly fine. Thankyou very much. My teacher never mentioned the exit protocol so I didn't even know it existed.
macros.asm is already included in masm32rt.inc, no need for that line. And your teacher might be happy see
invoke ExitProcess, 0 instead of a macro (exit) that he does not know.
Hi
Can you tell me why do you push EAX and pop EAX
when sqrt saves EAX ?
Why this trick if sqrt can exit with the value in EAX ?
loadLoop:
lea EBX, aSquares
mov ESI, ECX
add ESI, ESI
add ESI, ESI
mov EDX, [EBX][ESI]
push EAX ; <<<<<<<<<<<<<<<<<
push EDX
call sqrt
pop EAX ; <<<<<<<<<<<<<<<<<
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include \masm32\include\masm32rt.inc
include \masm32\include\msvcrt.inc
includelib \masm32\lib\msvcrt.lib
.data ;data segment
aSquares dd 36, 169, 9801, 51984, 105625
PrintRoot db 'sqrt(%d) = %d', 10, 0
QuitLine db 'Press any key to quit.', 0
.code ;code segment
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Square root function ~~~~~~~~~
sqrtX proc
push ECX
;Set up variables for rootLooping
mov EAX, [ESP+8]
mov ECX, 0
mov ESI, 1
rootLoop: ;Calculates the square root
sub EAX, ESI
add ESI, 2
inc ECX
cmp EAX, 0 ;if EAX > 0 keep looping
ja rootLoop
mov EAX, ECX
pop ECX
ret 4
sqrtX endp
start:
;int 3
mov ECX, 0
loadLoop:
lea EBX, aSquares
mov ESI, ECX
add ESI, ESI
add ESI, ESI
mov EDX, [EBX + ESI]
push EDX
call sqrtX
pushad
invoke crt_printf, addr PrintRoot, EDX, EAX
popad
inc ECX
cmp ECX, 5
jl loadLoop
pushad
invoke crt_printf, addr QuitLine
popad
pushad
invoke crt__getch
popad
INVOKE ExitProcess,0
end start