News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

About the stack

Started by buraks, January 26, 2020, 11:00:47 AM

Previous topic - Next topic

avcaballero

Yes, that's right. You cannot exit from a procedure that has local variables or paramethers in the same way from other that has nothing of this. Though you only use "ret" for every case.


jj2007

Quote from: felipe on January 27, 2020, 08:10:23 AMOh i think i got it now, probably this "masm" behavior (don't care about other assemblers for now) of adding code when you use "ret" only happens when you use the "proc" directive, passing parameters with it

Yes, that's correct. For a simple somestuff proc without arguments and without local variables, the assembler uses retn and nothing else. There is no need for a stack frame in such a proc.

felipe

Thanks for confirming this, i really appreciate it.  :thumbsup:

hutch--

The action with the stack in 32 bit is to ensure that has the same value on exit as it has before the proc was called. This is called "balancing the stack". One of the easiest ways to test this is and display code that can output "str$(esp)". If the displayed value is the same both before and after the proc that is called, then the stack is balanced, if not you have something to fix with the code.

jj2007

#19
Related: Another good method is to use a global variable, as demonstrated below:
include \masm32\include\masm32rt.inc

.data?
globalEsp dd ?

.code
TheAlgo proc uses esi edi ebx _text, _title
Local tLen
  mov globalEsp, esp
  mov esi, _text
  mov edi, _title
  mov tLen, len(esi)
  add tLen, len(edi)
  push eax ; push is a very useful instruction, but there should be a corresponding pop
  print str$(tLen), " = len of text plus len of title", 13, 10
  pushw 123 ; oops, this pushes a word - serious trouble
  cmp globalEsp, esp
  .if !Zero?
mov eax, globalEsp
sub eax, esp
mov esp, globalEsp
push eax
sar eax, 2
.if !Sign?
print str$(eax), " = number of push instructions in excess", 13, 10
.else
print str$(eax), " = number of pop instructions in excess", 13, 10
.endif
pop eax
invoke MessageBox, 0, str$(eax), chr$("Stack is some bytes off:"), MB_OK
  .endif
  ret
TheAlgo endp
codesize TheAlgo

start:
  invoke TheAlgo, chr$("This is the text"), chr$("The title:")
  inkey "hit any key"
  exit

end start


Attached the De Luxe version - by activating the useCsb=0 line, no extra code will be generated by the CheckStackBalance macro:
include \masm32\include\masm32rt.inc
include CheckStackBalance.inc ; the macro
; useCsb=0 ; uncomment this line to see the effect

.code
TheAlgo proc uses esi edi ebx _text, _title
Local tLen
  CheckStackBalance ; after the locals
  mov esi, _text
  mov edi, _title
  mov tLen, len(esi)
  add tLen, len(edi)
  push eax ; push is a very useful instruction, but there should be a corresponding pop
  print str$(tLen), " = len of text plus len of title", 13, 10
  pushw 123 ; oops, this pushes a word - serious trouble!
  CheckStackBalance ; before the ret
  ret
TheAlgo endp
codesize TheAlgo ; ** TheAlgo is 207 bytes long **

start:
  mov esi, 123456789
  invoke TheAlgo, chr$("This is the text"), chr$("The title:")
  inkey str$(esi), " is the value of esi"
  exit

end start


Note that for useCsb=0 the code does not crash, and you will not see any warning - stack frames are a wonderful feature! But check the "value of esi" line :cool:

P.S.: Just for fun, I've added a codesize macro - to be used after the endp. Watch your output window when you build the code either with useCsb=0 or useCsb=1 (default). No extra code generated :thumbsup:

jj2007

The CheckStackBalance macro is now available, see this post

daydreamer

JJ,wasnt you who had cool SSE push/pop macro?
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

jj2007

Quote from: daydreamer on February 01, 2020, 07:58:08 PM
JJ,wasnt you who had cool SSE push/pop macro?

What do you mean? I have dedicated macros to keep XMM0...XMM3 safe, but not for public use.
fxsave and fxrstor are your friends - roll your own ;-)