Author Topic: About the stack  (Read 619 times)

caballero

  • Member
  • *****
  • Posts: 1352
  • Matrix - Noah
    • abre ojos ensamblador
Re: About the stack
« Reply #15 on: January 27, 2020, 08:32:19 AM »
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.

The logic of the error is hidden among the most unexpected lines of the program

jj2007

  • Member
  • *****
  • Posts: 10112
  • Assembler is fun ;-)
    • MasmBasic
Re: About the stack
« Reply #16 on: January 27, 2020, 09:47:21 AM »
Oh 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

  • Member
  • *****
  • Posts: 1265
  • Eagles are just great!
Re: About the stack
« Reply #17 on: January 27, 2020, 11:37:02 AM »
Thanks for confirming this, i really appreciate it.  :thumbsup:
Felipe.

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 7058
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: About the stack
« Reply #18 on: January 27, 2020, 12:10:06 PM »
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.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

jj2007

  • Member
  • *****
  • Posts: 10112
  • Assembler is fun ;-)
    • MasmBasic
Re: About the stack
« Reply #19 on: January 27, 2020, 05:13:48 PM »
Related: Another good method is to use a global variable, as demonstrated below:
Code: [Select]
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:
Code: [Select]
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:
« Last Edit: January 27, 2020, 06:20:09 PM by jj2007 »

jj2007

  • Member
  • *****
  • Posts: 10112
  • Assembler is fun ;-)
    • MasmBasic
Re: About the stack
« Reply #20 on: February 01, 2020, 03:54:51 PM »
The CheckStackBalance macro is now available, see this post

daydreamer

  • Member
  • *****
  • Posts: 1156
  • I also want a stargate
Re: About the stack
« Reply #21 on: February 01, 2020, 07:58:08 PM »
JJ,wasnt you who had cool SSE push/pop macro?
Quote from Flashdance
Nick  :  When you give up your dream, you die
*wears a flameproof asbestos suit*
Gone serverside programming p:  :D
I love assembly,because its legal to write
princess:lea eax,luke
:)

jj2007

  • Member
  • *****
  • Posts: 10112
  • Assembler is fun ;-)
    • MasmBasic
Re: About the stack
« Reply #22 on: February 01, 2020, 09:28:25 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 ;-)