Author Topic: PUSH & POP question  (Read 503 times)

Ascended

  • Member
  • ***
  • Posts: 331
PUSH & POP question
« on: May 01, 2018, 11:01:40 AM »
Hi guys,

Do you have to 'pop' every time you 'push' something on the stack?

Do 'call' and 'invoke' automatically do this for us?

Thanks in advance  :biggrin:

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5426
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: PUSH & POP question
« Reply #1 on: May 01, 2018, 11:16:15 AM »
Except in rare instances, yes. The stack for PUSH / POP work on a last on, first off basis so the POPs must be in reverse order to the PUSHs.

When a CALL is made, you need to have pushed the arguments onto the stack first. When you use the built in MACRO "invoke" it automates the push / call process. Note that any procedure you call that you wrote yourself must balance the stack on exit. This is done with the number after the RET (ret 16) and it must match the number of arguments x 4.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

jj2007

  • Member
  • *****
  • Posts: 8435
  • Assembler is fun ;-)
    • MasmBasic
Re: PUSH & POP question
« Reply #2 on: May 01, 2018, 11:16:42 AM »
YES and YES.

Note that any procedure you call that you wrote yourself must balance the stack on exit.
"Balanced" means normally that #push = #pop, but there are situations where you may want to use push push call instead of invoke, see screenshot below. I have recently started to use uppercase PUSH for these cases, so that searching for push+pop yields lowercase #push = #pop if the stack is balanced.

Note also that a program does not necessarily crash if the stack is not balanced; most procs have a stack frame, and if that gets released at the end, the stack is balanced. Great, but you have a bug...

Ascended

  • Member
  • ***
  • Posts: 331
Re: PUSH & POP question
« Reply #3 on: May 01, 2018, 11:19:17 AM »
Thanks guys.

So this would need four more pop's before pop'ping ESI?

Code: [Select]
; Display 'MessageBox'
push esi ; preserve esi

mov eax, 10h ; Error icon
push eax

lea esi, _EE ; Error title
mov ecx, esi
push ecx

lea esi, _E0 ; Error reason
mov ecx, esi
push ecx

xor eax, eax ; Window handle
push eax
call MessageBoxA

pop esi ; restore esi

Doing it all long handed for learning purposes (ie. not using 'offset' or 'invoke').

(Or a ret 16 if it was in a proc?)

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5426
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: PUSH & POP question
« Reply #4 on: May 01, 2018, 11:26:15 AM »
For the 1st and 4th argument, you can directly do a "push 0" in MASM.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

jj2007

  • Member
  • *****
  • Posts: 8435
  • Assembler is fun ;-)
    • MasmBasic
Re: PUSH & POP question
« Reply #5 on: May 01, 2018, 11:26:28 AM »
So this would need four more pop's before pop'ping ESI?
Nope. You used 4*push instead of invoke. Your stack is balanced.

If you want to dig deeper, here is a snippet (see above, "a program does not necessarily crash if the stack is not balanced"):
Code: [Select]
include \masm32\include\masm32rt.inc ; console build!

.code
SayHi proc uses esi edi ebx pMessage
Local hWnd ; force a stack frame...
  and hWnd, 0 ; set window handle to zero
  push MB_OK
  push chr$("Hi")
  push pMessage ; chr$("Hello World")
  push hWnd
  call MessageBox ; invoke MessageBox, 0, str$(eax), chr$("Title"), MB_OK
  pop edx ; a desperate attempt to balance the stack
  pop edx
  pop edx
  pop edx
  ; int 3 ; uncomment to see what happens here
  ret
SayHi endp
 
start:
  mov ebx, 123
  mov esi, 456
  mov edi, 789
  print str$(ebx), 9, "ebx before", 13, 10
  print str$(esi), 9, "esi", 13, 10
  print str$(edi), 9, "edi", 13, 10
  invoke SayHi, chr$("Hello World")
  print str$(ebx), 9, "ebx after", 13, 10
  print str$(esi), 9, "esi", 13, 10
  inkey str$(edi), 9, "edi", 13, 10
  exit

end start

Ascended

  • Member
  • ***
  • Posts: 331
Re: PUSH & POP question
« Reply #6 on: May 01, 2018, 12:11:43 PM »
Thanks guys. Got it  :t

And Hutch, the fourth arg is a 10H, but I get what you are saying.

Thanks again  8)

Ascended

  • Member
  • ***
  • Posts: 331
Re: PUSH & POP question
« Reply #7 on: May 01, 2018, 12:15:41 PM »
Also, was I right in assuming that this is the equivalent of 'offset'?

Code: [Select]
push esi
lea esi, xxx
mov ecx, esi
pop esi

[edit]
Actually OllyDbg says that it is simply 'push offset address'

I though 'offset' must have been another macro, but it is an actual keyword. There ya go  :biggrin:

jj2007

  • Member
  • *****
  • Posts: 8435
  • Assembler is fun ;-)
    • MasmBasic
Re: PUSH & POP question
« Reply #8 on: May 01, 2018, 12:33:46 PM »
lea esi, somevar is the same as mov esi, offset somevar if somevar is a global variable.

This is unnecessarily complicated:
Code: [Select]
lea esi, _EE ; Error title
mov ecx, esi
push ecx

lea esi, _E0 ; Error reason
mov ecx, esi
push ecx

Better:
Code: [Select]
mov esi, offset _EE ; Error title
push esi

mov esi, offset _E0 ; Error reason
push esi

Even better (shorter, and doesn't need esi):
Code: [Select]
push offset _EE ; Error title
push offset _E0 ; Error reason

Even better (for readability):
Code: [Select]
push chr$("There was an error:")
push chr$("But I don't know the reason")

And once you have understood how it works under the hood. you can become professional and lazy:
Code: [Select]
MsgBox 0, "But I don't know the reason", "There was an error:", MB_YESNOCANCEL or MB_ICONWHATEVER

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5426
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: PUSH & POP question
« Reply #9 on: May 01, 2018, 12:51:06 PM »
Its unfortunate that ML64 has gone the way of NASM in not using OFFSET which is a specific technical term for a distance from a location which is used to locate either data or code within an assembler binary. In 32 bit MASM (ML.EXE) it is the preferred technique for addresses. LEA will do it but you are determining the address dynamically where OFFSET puts the value in at assembly time as an immediate.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

Ascended

  • Member
  • ***
  • Posts: 331
Re: PUSH & POP question
« Reply #10 on: May 01, 2018, 12:53:29 PM »
Its unfortunate that ML64 has gone the way of NASM in not using OFFSET which is a specific technical term for a distance from a location which is used to locate either data or code within an assembler binary. In 32 bit MASM (ML.EXE) it is the preferred technique for addresses. LEA will do it but you are determining the address dynamically where OFFSET puts the value in at assembly time as an immediate.

Oh, so in ML64 you have to use LEA then?

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5426
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: PUSH & POP question
« Reply #11 on: May 01, 2018, 12:55:38 PM »
In most instances, yes. I don't like it but that is how it works.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

Ascended

  • Member
  • ***
  • Posts: 331
Re: PUSH & POP question
« Reply #12 on: May 01, 2018, 12:57:09 PM »
Bummer, good snippet to know though  :t

jj2007

  • Member
  • *****
  • Posts: 8435
  • Assembler is fun ;-)
    • MasmBasic
Re: PUSH & POP question
« Reply #13 on: May 01, 2018, 01:02:52 PM »
Its unfortunate that ML64 has gone the way of NASM in not using OFFSET

Are you sure?

Code: [Select]
  mov rsi, offset txMessage
  lea rdi, txMessage

Code: [Select]
0000000140001018   | 48 BE 02 10 00 40 01 00 00 00    | movabs rsi,140001002                    | 140001002:"Hello World"
0000000140001022   | 48 8D 3D D9 FF FF FF             | lea rdi,qword ptr ds:[140001002]        | 140001002:"Hello World"

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5426
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: PUSH & POP question
« Reply #14 on: May 01, 2018, 06:18:54 PM »
There are some places where you can use it and some places where it fails. I try for consistency and LEA is consistent across all of the uses I have found.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin: