News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

the stack

Started by ecube, July 19, 2010, 01:16:02 AM

Previous topic - Next topic

ecube

Quote from: hutch-- on July 19, 2010, 03:11:19 AM
Cube,

You can pass the address of the first and calculate the rest in the called proc

can you give simple example please

KeepingRealBusy

Let me correct my first reply: "lea esp,[esp-12]".

Dave.

ecube

lea esp,[esp+4] before the call fixed it, I went with daves method, thanks guys.

jj2007

Quote from: KeepingRealBusy on July 19, 2010, 03:31:50 AM
Messy, fail prone, but doable. MASM lets you get into as much trouble as you want.
Yes :green

include \masm32\include\masm32rt.inc

MyTest PROTO: DWORD, :DWORD
MyFake PROTO: DWORD, :DWORD

.code
AppName db "Masm32 is great!", 0
Hello db "A message:", 0
start: mov ebx, esp
invoke MyTest, offset AppName, addr Hello
invoke MyFake, offset AppName, addr Hello
.if ebx!=esp
MsgBox 0, "The stack is not correct", "Hi", MB_OK
.endif
exit

MyFake proc arg1:DWORD, arg2:DWORD
  MsgBox 0, arg1, "Now we are curious, aren't we?", MB_OK
  jmp TheTrick
MyFake endp

MyTest proc arg1:DWORD, arg2:DWORD
LOCAL lv1, lv2, locbuf[260]:BYTE
TheTrick::
  MsgBox 0, arg1, arg2, MB_OK
  ret
MyTest endp

end start

dedndave

well - it may help to simply think in terms of "what should the stack look like when we get to func2"
on the stack, you want:
1) p3
2) p2
3) p1
4) return address

if #4 is the return address inside func1, then the previous methods will work
but, if there is no code in func1 after the transfer to func2, there is an even simpler method
func1 proc p1,p2,p3
;presumably some code here
jmp func2
func1 endp

func2 proc p1,p2,p3
invoke dwtoa,p1,addr mybuff
invoke MessageBox,0,addr mybuff,NULL,MB_OK
ret
func2 endp


or even simpler...
func1 proc p1,p2,p3
;presumably some code here
func1 endp

func2 proc p1,p2,p3
invoke dwtoa,p1,addr mybuff
invoke MessageBox,0,addr mybuff,NULL,MB_OK
ret
func2 endp

which let's execution "fall through" to func2

with older assemblers, we could nest procedures
that seems to be a little trickier with newer masm versions - haven't played with it much

at any rate, it may help to turn off the default prologue and epilogue when playing with these kind of tricks
the mysterious p2 to p1 shift probably occured because the prologue pushes EBP
        OPTION  PROLOGUE:NONE
        OPTION  EPILOGUE:NONE

;E^Cube stuff here

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

sinsi

Quote from: dedndave on July 19, 2010, 12:35:19 PM
func1 proc p1,p2,p3
;presumably some code here
jmp func2
func1 endp


I didn't have the nice comment but at least my code was indented  :bg
Quote from: sinsi on July 19, 2010, 01:42:36 AM

func1 proc p1,p2,p3
  jmp func2
func1 endp
Light travels faster than sound, that's why some people seem bright until you hear them.

dedndave

lol - yah - it can even be easier than that   :lol
func1:
func2 proc p1,p2,p3
invoke dwtoa,p1,addr mybuff
invoke MessageBox,0,addr mybuff,NULL,MB_OK
ret
func2 endp

or ...
func1   TEXTEQU  <func2>

jj2007

Quote from: dedndave on July 19, 2010, 12:35:19 PM
but, if there is no code in func1 after the transfer to func2, there is an even simpler method
func1 proc p1,p2,p3
;presumably some code here
jmp func2
func1 endp

func2 proc p1,p2,p3
invoke dwtoa,p1,addr mybuff
invoke MessageBox,0,addr mybuff,NULL,MB_OK
ret
func2 endp


or even simpler...
func1 proc p1,p2,p3
;presumably some code here
func1 endp

func2 proc p1,p2,p3
invoke dwtoa,p1,addr mybuff
invoke MessageBox,0,addr mybuff,NULL,MB_OK
ret
func2 endp

which let's execution "fall through" to func2

Dave, you are up for surprises :green
(take my example to find out - Olly is your friend)

dedndave

no surprises here Jochen - lol
        OPTION  PROLOGUE:NONE
        OPTION  EPILOGUE:NONE

;E^Cube stuff here

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef


in fact, i considered just using this at the beginning of my programs
        OPTION  PROLOGUE:NONE
        OPTION  EPILOGUE:NONE

because i always prefer to write that way
but, that would break compatibility with everyone in the forum   :P

back, before the advent of the internet, i used to use some abbreviations, too
i couldn't use my old abbreviations for the same reason - noone else would get it - lol
BPT     EQU     Byte Ptr
WPT     EQU     Word Ptr
DPT     EQU     Dword Ptr
OFS     EQU     Offset
SHO     EQU     Short

        mov BPT WordLabel,10h
        mov     ax,OFS ByteLabel
        jmp SHO BranchLabel

jj2007

Quote from: dedndave on July 19, 2010, 01:25:18 PM
no surprises here Jochen - lol

Dave,

fallthrough works fine if there are no local variables. Otherwise there is trouble, because part II of the framing, the sub esp, nnn is being done twice. Here is an example that works with local variables.

include \masm32\include\masm32rt.inc

MyTest PROTO: DWORD, :DWORD
MyFake PROTO: DWORD, :DWORD

.code
AppName db "Masm32 is great!", 0

start: mov ebx, esp
; int 3
invoke MyTest, offset AppName, chr$("The real thing:")
invoke MyFake, offset AppName, chr$("The fake:")
.if ebx!=esp
MsgBox 0, "The stack is not correct", "Hi", MB_OK
.endif
exit

MyFake proc arg1:DWORD, arg2:DWORD
LOCAL lv1, LocRetVal, locbuf[260]:BYTE
  MsgBox 0, arg1, "Now we are curious, aren't we?", MB_YESNOCANCEL
  mov LocRetVal, eax
  jmp TheTrick
MyFake endp

MyTest proc arg1:DWORD, arg2:DWORD
LOCAL lv1, WhatEver, locbuf[260]:BYTE
  mov WhatEver, IDNO
TheTrick::
  MsgBox 0, str$(WhatEver), arg2, MB_OK
  ret
MyTest endp

end start

dedndave

if i turn off prologues (and epilogues), the locals are literal and visible in the code   :bg