Author Topic: When is the stack cleared in assembly?  (Read 22081 times)

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
When is the stack cleared in assembly?
« on: March 23, 2013, 03:37:47 AM »
when we call interrupt and after we do multiplication, subtraction, addition or division, right?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: When is the stack cleared in assembly?
« Reply #1 on: March 23, 2013, 05:42:27 AM »
Which assembly?

I don't think I understand the question, Maplesirop. The thing that's not too obvious about the stack, at first, is that the "call" instruction uses the stack to store its return address. When the code gets to "ret", it gets the address to return to from the stack - essentially "popping" it. That return address had BETTER be the next thing on the stack, or we're off into deep muddy water! To that extent, we need to clear the stack... if we've disturbed it. The "int" instruction uses the stack, but it takes care of itself. None of the arithmetic instructions you mention does anything with the stack (with a possible exception...)...
Code: [Select]
_start:
    call myfunc
...
; exit cleanly, as always

myfunc:
    add eax, eax
    ret

But if we disturb the stack....

Code: [Select]
_start:
    call myfunc
...
; exit cleanly, as always

myfunc:
    add eax, eax
    push eax  ; for no good reason
; now we have to "clean up the stack" before we can "ret"
    pop eax ; or "add esp, 4" would do it
    ret

We sometimes pass parameters on the stack. In this case, sometimes the called function removes them (called "stdcall" - Windows APIs use this)...
Code: [Select]
myfunc:
    push 0
    push caption
    push message
    push 0
    call MessageBoxA
; no need to clean up stack
    ret

... but more likely (in Linux) we're using the "cdecl" calling convention, which means that the caller is responsible for removing parameters...

Code: [Select]
_start:
    call myfunc
...
; exit cleanly, as always

myfunc:
    add eax, eax
    push eax
    push eax
    push format_string ; pretend it prints two integers
    call printf
    add esp, 4 * 3  ; four bytes per parameter, three parameters
; (that's the exception)
    ret

Is that what you're asking about? Anywhere close? :)

Best,
Frank


Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: When is the stack cleared in assembly?
« Reply #2 on: March 27, 2013, 03:37:04 AM »
yeah thanks

but i did an exercise on post-fix notation and we cleared the stack every time we had operator as opposed to operands.

can you tell me when the stack is cleared? like are you saying that the stack is cleared only when we return the address and the address is the only element on the stack?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: When is the stack cleared in assembly?
« Reply #3 on: March 29, 2013, 04:42:47 AM »
Well, if you're using the stack to store operands for post-fix notation, and you come to an operator, you'd remove the operands from the stack and, uhhh... operate on 'em. At this point I guess you could say the stack was "cleared", although there are almost certainly other values on the stack...

For purposes of keeping our program from crashing,   the stack should be "cleared, up to the return address" when we get to "ret". The return address doesn't have to be the "only" thing on the stack, it just has to be the "next" thing on the stack.

That's if there IS a return address on the stack. If your entrypoint is "main", there's a return address and you can "ret" from it. But "_start" is jumped to, not called. The very first thing on the stack is the argument count ("first" meaning [esp], as esp is when we first get it). Then, working up the stack four bytes at a time, there's a pointer to the program name - a zero-terminated string. Pointers to command line parameters are next, if any, followed by a (dword) 0. Then there are pointers to environment variables (zero-terminated strings), again followed by a 0. There's some more stuff up there that may be of interest, but I haven''t delved into it. Furthermore, these "pointers to zero-terminated strings", as far as I can determine, point to stack memory. Apparently, the loader has used the stack to pass us our copy of the environment variables... and who knows what else. So if "cleared" means "no more values on it"... never, for practical purposes.

I still don't feel like I'm answering the right question here. Don't give up until you understand what you need to!

Best,
Frank


Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: When is the stack cleared in assembly?
« Reply #4 on: March 29, 2013, 10:44:22 PM »
Thanks a lot.

I just need to understand how stacks works.

So basically when we make calculation the stack clears all the operands and operator that were used and before the ret statement everything before the return address is automatically cleared?

Offline hhh3h

  • Jr. Member
  • *
  • Posts: 41
Re: When is the stack cleared in assembly?
« Reply #5 on: April 04, 2013, 05:37:46 AM »
No, the stack is not cleared by math operations, and it's not cleared automatically either.  Every time you go into a function, the stack "grows". This is because the return address is added to the stack as well as any arguments that the function has. While inside the function, you can also grow the stack even more my storing new local variables there.

When its time for the function to end, you need to "return" to the place you were before calling that function... What address is that? Like I said above, that return address is on the stack.  But now it's burried by any local variables that you created.  Also, those arguments will be on top of it too.  In order to get to that return address, you have to clear ("pop") all those things off of the stack until the return address is visible.  Then and only then can you use the "ret" command.

You DON'T want to clear the whole stack, if that's what you're asking!  Do that and you won't have a working program.  When your program ends will be the only time that your stack is "clear".

To summarize, a proper program will constantly be adding stuff to the stack, using it, removing those items, rinse and repeat.
« Last Edit: April 04, 2013, 05:43:11 AM by hhh3h »