Having trouble returning to original routine.

Routine A
INVOKE B, hWnd, hdc
at the beginning B generates
push ebp
mov ebp,esp
at the end B generates
Leave

Routine B
INVOKE C and return
at the beginning C generates
nothing
at the end C generates
nothing

INVOKE D and return
at the beginning D generates
nothing
at the end D generates
nothing

INVOKE E, hdc, hWnd and return
at the beginning E generates
push ebp
mov ebp, esp
at the end E generates
Leave

At the end of B it NEVER returns to A. Hangs up in
Krnl386.exe with a general protection fault.

Surely nested invokes work? Even with parameters.

I think I am pushing and poping the registers correctly.

If more detail is needed I will be glad to supply it.
Thanks for any help.
JPS
Posted on 2002-10-31 18:36:53 by shankle
Your explaination is fine, easy to understand the problem;
Without being able to see the code however the problem
(and solution) is impossible to determine.

Please post the code... or stripped down versions of each
function.
Posted on 2002-10-31 21:52:53 by Graebel
Are you disabling stack frames for B and C? If so...

Say B pushes 2 parameters, then you should exit with ret 8.

Use the proper stack correcting with ret (n) for both B and C.

If that is not the case....

Check the value of esp just before proc entry and just after proc exit for each proc. If one it is not the same value for entry and exit, you have found where the problem proc is. Now trace inside this proc and watch esp, eventualy you find the problem.
Posted on 2002-10-31 22:03:02 by ThoughtCriminal
Jack,

Try using RET after the LEAVE. Normally you pair ENTER/LEAVE but you can preserve the stack in what is generally a more efficient way by manually coding the entry and exit.


push ebp ; preserve base pointer
mov ebp, esp ; stack pointer into ebp

; code

mov esp, ebp ; restore stack pointer
pop ebp ; restore base pointer

ret

Regards,

hutch@movsd.com
Posted on 2002-11-01 01:26:40 by hutch--
Many thanks for the suggestions.
I have enclosed the sample code requested.
I tried inserting RET 8 where needed with no luck.
I thought RET was a kind of automatic thing. As I always use RET with
no values after it and have been getting by that way.
I tried inserting push ebp, mov ebp,esp, mov esp, ebp, pop ebp
but the assembler inserted the code a 2nd time.
The assembler also inserts Leave. I have not inserted leave.
Posted on 2002-11-01 07:33:20 by shankle
You are generating many stack frames, that you aren't cleaning up!

In the function ReadDownRight you "jmp ReadDownRight" to start again, but this is the begining of a function call, so it will generate another stack frame on each successive jump. Not only that, the EBP relative addresses for the locals will be off, so they'll get corrupted, and when it comes to returning, MASM will only clean up the outer most stack frame, and then return to whatever is then on top of the stack (probably pointing to somewhere in the middle of the stack, as it'll be one of the earlier values of ESP or EBP)... The program will then try to execute the stack, and KABOOM.

Mirno
Posted on 2002-11-01 08:01:09 by Mirno
MANY thanks fellows.
Problem solved.

I knew it was going to be stupid.
But not how Stupid.
Posted on 2002-11-01 08:33:31 by shankle