The MASM Forum

64 bit assembler => 64 bit assembler. Conceptual Issues => Topic started by: hutch-- on December 31, 2017, 07:06:50 AM

Title: Manual entry point example.
Post by: hutch-- on December 31, 2017, 07:06:50 AM
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
Title: Re: Manual entry point example.
Post by: jj2007 on December 31, 2017, 07:41:11 AM
Works fine here. What exactly should go wrong? Can you post the exe?
Title: Re: Manual entry point example.
Post by: hutch-- on December 31, 2017, 07:51:21 AM
Done.
Title: Re: Manual entry point example.
Post by: jj2007 on December 31, 2017, 08:04:26 AM
It works like a charm, even in the debugger. What is supposed to go wrong here?
Title: Re: Manual entry point example.
Post by: 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:

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]
Title: Re: Manual entry point example.
Post by: 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.
Title: Re: Manual entry point example.
Post by: sinsi on December 31, 2017, 09:10:25 AM
This is not local

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

Title: Re: Manual entry point example.
Post by: felipe on December 31, 2017, 09:31:43 AM
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:
Title: Re: Manual entry point example.
Post by: jj2007 on December 31, 2017, 09:34:34 AM
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 ;)
Title: Re: Manual entry point example.
Post by: sinsi on December 31, 2017, 09:47:53 AM
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.
Title: Re: Manual entry point example.
Post by: hutch-- on December 31, 2017, 12:48:45 PM
 :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.
Title: Re: Manual entry point example.
Post by: sinsi on December 31, 2017, 01:43:25 PM
I also think that [rsp-32] might be clobbered by the conout call, which would eventually end up calling a windows function.
Title: Re: Manual entry point example.
Post by: hutch-- on December 31, 2017, 04:08:37 PM
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