Hi. Could someone point me to some good info on the stack, clearing stackframe etc? I am new to masm32 and would appreciate any help on the topic. Thanks
Posted on 2000-11-20 12:16:00 by mars_matrix
Any stack frame should be created and destroyed by MASM without you knowing in anyway, like so: func proc Arg1:DWORD,Arg2:DWORD LOCAL Local1 :DWORD LOCAL Local2 :DWORD ; MASM32 sets up your stack frame accordingly ret ; MASM32 releases your stack frame accordingly func endp However, if you want to control this yourself, good luck! Here's what I know. The stack (SS:(E)SP) loads from bottom to top, not top to bottom to keep the segment size the same, back when memory was scarse. For example, a push would decrement (E)SP while a pop increments it. So, in order to set up a stack frame, first count the number of variables you'll use and do this: ; set up stack frame, 32 bit ; if 16 bit, replace EBP with BP and ESP with SP push ebp mov ebp,esp sub esp,size_of_variables_and_arguments ; add esp,-(size_of_variables_and_arguments) is slightly faster ; clear stack frame mov esp,ebp pop ebp ret size_of_arguments_only ; This return doesn't return a value, but instead pops off ; X number of bytes. We want that to avoid stack overflow! Then, to access your variables and arguments, you must use correct indirect pointers: Argument(s) Return address (leave it alone!) Local variable(s) etc... Not exactly easy, but doable. Note to decrease (E)SP, not (E)BP. If you don't modify (E)SP, then your pushes and pops will forever screw up your local variables. =)
Posted on 2000-11-20 13:29:00 by Racso
Grrr....sorry. I meant SS: (E)SP.
Posted on 2000-11-20 13:30:00 by Racso
Gah, sorry. Was eating lunch and didn't notice a fairly major typo. :) Pointers: Arguments Return address Original Base Pointer first argument second-X arguments
Posted on 2000-11-20 13:57:00 by Racso
mars_matrix, If you actually need the practice of seting the stack manually, the technique that Rasco has shown you will do the job but unless its a matter of needing the practice, you are a lot better off by using the assembler to do this for you. The general model of writing prototypes and procedures with matching parameters makes you code one HELL of a lot more reliable and there is no size or performance gain by not using it. You also have the advantage using procedures with prototypes in that you can specify the calling convention if for example you need to pass a variable number of parameters to a procedure. Where win 32 bit is normally in STDCALL, using C calling convention allows you to make the last parameter VARARG. MASM32 version 6 has an example called "tstyle" that show what a manually code stack looks like, its not there as an example of why you should use this style, its there as an example of why you should NOT use this style. Regards, hutch@pbq.com.au
Posted on 2000-11-20 20:22:00 by hutch--
I most deceidly agree with hutch here, use the masm build-in stack frame handling macros. They are 100% reliable, YOU are not. The programmer is ALWAYS the weak link in the chain. Just one more thing to add: end all your procedures with a 'ret' This is eazy to forget, and doesn't generate any compile errors. SomeFunct PROC param1:DWORD, parma2:DWORD LOCAL L1:DWORD, L2:SomeStruct {code here} ret ; ALWAYS use 'ret'... this expands into a ; few instructions that clear the stack. ; It is acceptable to have multiple 'ret' in ; single PROC if you have mulptple exit points ; (You deceid if you don't like that coding ; convention) SomeFunct ENDP
Posted on 2000-11-20 21:01:00 by TTom
Actually, after push ebp mov ebp,esp sub esp, LocalVarsSize the ebp offsets should be start of args Old EIP (return address) Old EBP start of local variables So yes, it's easier to let the assembler do it.
Posted on 2000-11-20 23:57:00 by ub1
Yeah, I made too many typos that day. Never try to eat lunch and type at the same time, especially when you've got only got a 30 minute lunch break. :D
Posted on 2000-11-22 00:52:00 by Racso
Thanks alot for the help. I've been sick for a few days and havn't tried it yet but I will. I ran into these 'stack' problems when doing a timer callback function. cheers
Posted on 2000-11-22 13:18:00 by mars_matrix