News:

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

Main Menu

Manual entry point example.

Started by hutch--, December 31, 2017, 07:06:50 AM

Previous topic - Next topic

hutch--

For those hardy souls who want to manually construct their stack frame, here is a simple example of why I prefer to use the ENTER / LEAVE pair instead of doing it manually. If you dis-assemble this simple code you will see why.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

NOSTACKFRAME                       ; turn the stackframe off

entry_point proc

    push rbp                        ; manually construct stack frame
    mov rbp, rsp                    ; store stack pointer in rbp
    sub rsp, 128                    ; allocate local space

    mov QWORD PTR [rsp-32], 0       ; write value to local

  ; ---------------------------
  ; call a stackframe procedure
  ; ---------------------------
    invoke showtext,"The time has come, the walrus said, to speak of many things"
    waitkey                         ; call a library procedure

  ; -----------------------------------------------
  ; call API with a manually defined local variable
  ; -----------------------------------------------
    invoke ExitProcess,QWORD PTR [rsp-32]

    mov rsp, rbp                    ; exit the stack frame
    pop rbp

    ret

entry_point endp

STACKFRAME                         ; turn the stack frame back on again

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

showtext proc text:QWORD

    conout text,lf,lf               ; display the text

    ret

showtext endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end

jj2007

Works fine here. What exactly should go wrong? Can you post the exe?

hutch--


jj2007

It works like a charm, even in the debugger. What is supposed to go wrong here?

felipe

I don't know (almost nothing) of 64 bits yet, but looks pretty much (this code example) as 32 bits. This:

mov QWORD PTR [rsp-32], 0       ; write value to local

Shouldn't be this?:

mov QWORD PTR [rbp-32], 0       ; write value to local

And then this:

invoke ExitProcess,QWORD PTR [rsp-32]

this instead?:

invoke ExitProcess,QWORD PTR [rbp-32]

aw27

Quote from: felipe on December 31, 2017, 08:40:57 AM
I don't know (almost nothing) of 64 bits yet, but looks pretty much (this code example) as 32 bits. This:
:biggrin: of course.

sinsi

This is not local

    mov QWORD PTR [rsp-32], 0       ; write value to local


felipe

Quote from: aw27 on December 31, 2017, 08:49:33 AM
Quote from: felipe on December 31, 2017, 08:40:57 AM
I don't know (almost nothing) of 64 bits yet, but looks pretty much (this code example) as 32 bits. This:
:biggrin: of course.

:biggrin: Come on, at least tell me which of the statements above (or both) are you referring.  :biggrin:

jj2007

Quote from: sinsi on December 31, 2017, 09:10:25 AM
This is not local

    mov QWORD PTR [rsp-32], 0       ; write value to local


Right, it's somewhere in the wild. But that should cause any trouble (and it doesn't, indeed), because it's below the stackpointer.
The code works just fine, so I really wonder what is Hutch' intention here ;)

sinsi

Worst case (admittedly stretching things here)

;rsp = stackbase + 128 + 16
   sub rsp, 128                    ; allocate local space
;rsp = stackbase + 16
   mov QWORD PTR [rsp-32], 0       ; write value to local
;rsp-32 = stackbase - 16 = access violation?


No harm done usually, since if your stack is that low you have other issues, but not a good habit to form methinks.

hutch--

 :biggrin:

> so I really wonder what is Hutch' intention here

It was supposed to work OK but the answer was in the original post "why I prefer to use the ENTER / LEAVE pair instead of doing it manually".

Sinsi,
You are right but it was not the point of the example.

sinsi

I also think that [rsp-32] might be clobbered by the conout call, which would eventually end up calling a windows function.

hutch--

About the only problem  I can see with using RSP at the entry point instead of RBP is you have to use addresses for RSP based local values lower than with RBP.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

NOSTACKFRAME

entry_point proc

    push rbp                                ; align the stack
    mov rbp, rsp                            ; store stack pointer in rbp
    sub rsp, 128                            ; allocate local space

    mov QWORD PTR [rbp-16], 0
    mov QWORD PTR [rbp-24], 1234

    invoke showtext,"The time has come, the walrus said, to speak of many things"
    conout str$(QWORD PTR [rbp-16]),lf
    conout str$(QWORD PTR [rbp-24]),lf
    waitkey

    invoke ExitProcess,QWORD PTR [rbp-16]

    mov rsp, rbp                            ; never gets here
    pop rbp

    ret

entry_point endp

STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

showtext proc text:QWORD

    LOCAL unused1   :QWORD
    LOCAL unused2   :QWORD

    mov unused1, 100
    mov unused2, 200

    conout text,lf                          ; display the text

    ret

showtext endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end