News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Custom prologue

Started by sinsi, October 18, 2024, 02:04:52 AM

Previous topic - Next topic

sinsi

To use a custom prologue we need a macro
testprolog macro procname,flag,parmbytes,localbytes,regs,macroargs:varargWith 32-bit programs, parmbytes is correct - it's always paramcount*4
With 64-bit programs, parmbytes is incorrect - it's always paramcount*8 + 8.

Any idea why?

zedd151

Do you have a test example of its usage?

Vortex

Stack alignment to 16 bytes?

sinsi

Quote from: zedd151 on October 18, 2024, 04:24:01 AMDo you have a test example of its usage?

Microsoft (R) Macro Assembler (x64) Version 14.41.34123.0   10/18/24 03:57:56
C:\asm\testprologue\testprologue32.asm      Page 1 - 1


testprolog macro procname,flag,parmbytes,localbytes,regs,macroargs:vararg
    mov eax,parmbytes
    exitm <0>
endm

testepilog macro procname,flag,parmbytes,localbytes,regs,macroargs:vararg
endm

 00000000 .code

option prologue:testprolog

 00000000 test0 proc
 00000000  B8 00000008      1     mov eax,08H
    ret
 00000006 test0 endp

 00000006 test1 proc param1:word
 00000006  B8 00000010      1     mov eax,010H
    ret
 0000000D test1 endp

end

.386
.model flat,stdcall

testprolog macro procname,flag,parmbytes,localbytes,regs,macroargs:vararg
    mov eax,parmbytes
    exitm <0>
endm

testepilog macro procname,flag,parmbytes,localbytes,regs,macroargs:vararg
endm

 00000000 .code

option prologue:testprolog

 00000000 test0 proc
 00000000  B8 00000000      1     mov eax,00H
    ret
 00000006 test0 endp

 00000006 test1 proc param1:word
 00000006  B8 00000004      1     mov eax,04H
    ret
 0000000F test1 endp

end

Quote from: Vortex on October 18, 2024, 04:27:34 AMStack alignment to 16 bytes?
But then LOCAL/USES would possibly wreck that alignment. I thought that the whole thing about the 64-bit ABI is that the stack will be aligned to 8 on entry.
It's supposed to be the number of bytes the parameters take, which makes sense for 32-bit STDCALL when you need to use RET nn to clean the stack, but FASTCALL leaves the stack as it was (as far as cleaning up goes).

sinsi

Here's part of my prologue
if save_args EQ 1
if parmbytes GT 24
mov [rbp+40],r9
endif
if parmbytes GT 16
mov [rbp+32],r8
endif
if parmbytes GT 8
mov [rbp+24],rdx
endif
if parmbytes GT 0
mov [rbp+16],rcx
endif
endif
Because parmbytes is always at least 8, it always spills rcx. No big deal, but it's sloppy coding  :biggrin:

zedd151

Here is what I had come up with...

include \masm64\include64\masm64rt.inc

testprolog macro procname,flag,parmbytes,localbytes,regs,macroargs:vararg
mov eax,parmbytes
exitm <0>
endm

testepilog macro procname,flag,parmbytes,localbytes,regs,macroargs:vararg
endm

.data

.code

.code

option prologue:testprolog

Main proc

invoke test1, 1, 2, 3, 4, 5, 6

invoke ExitProcess, 0
Main endp


test0 proc
mov eax,08H
ret
test0 endp

test1 proc param1:word, param2:qword, param3:qword, param4:qword, param5:qword, param6:qword
mov eax,010H
ret
test1 endp

option epilogue:testepilog

end

And the result in x64dbg...
You cannot view this attachment.

I can make neither heads nor tales out of it though  :tongue:  me I'm just playing around in 64 bit-land.   :biggrin:
It crashes upon executing 'leave' in test1 procedure...

zedd151

I was originally missing one argument in the call.... I fixed the above example.   :rolleyes:

zedd151

Quote from: zedd151 on October 18, 2024, 04:52:31 AMIt crashes upon executing 'leave' in test1 procedure...
Using "option epilogue:none" removes the 'leave' instruction.  :smiley:

Quote from: sinsi on October 18, 2024, 04:36:37 AM                testepilog macro procname,flag,parmbytes,localbytes,regs,macroargs:vararg
                endm
Is this right for the epilogue??

Also, what are the arguments supposed to be (and their sizes - I only see 'word' for the first param???), what are they used for? I used generic arguments (1,2,3,4,5,6) just to see how it looks in the disassembly.

sinsi

Sorry, it isn't working code, just an example to assemble and see the resulting .list file.
I'll post an actual working example when I get home from work, but you can see the problem even here.

zedd151

Quote from: sinsi on October 18, 2024, 09:21:20 AMI'll post an actual working example when I get home from work, but you can see the problem even here.
okay   :smiley:

sinsi

#10
testprolog macro procname,flag,parmbytes,localbytes,regs,macroargs:vararg
    push    rbp
    mov     rbp,rsp
    mov     eax,parmbytes
    exitm   <localbytes>
endm

testepilog macro procname,flag,parmbytes,localbytes,regs,macroargs:vararg
    pop     rbp
    ret
endm

.code
option prologue:testprolog
option epilogue:testepilog

start proc public
;The custom prologue macro runs here
;It loads parmbytes from ML into EAX
;EAX should load 0, since there are no parameters to this proc

    ret
start endp

end
The only thing you might need to change is the entry point name.

zedd151

eax returns the following when the moving the following args  to eax. Notice the pattern...

testprolog macro procname,flag,parmbytes,localbytes,regs,macroargs:vararg
    push    rsp
    mov     rbp,rsp
   
    mov     eax, flag             ;;; eax returns "10h"
    mov     eax, parmbytes        ;;; eax returns "8"
    mov     eax, localbytes       ;;; eax returns "0"
 ;   mov     eax, regs             ;;; chokes on assembly couldnt test it
 ;   mov     eax, macroargs        ;;; chokes on assembly couldnt test it
   
    exitm   <localbytes>
endm


The last two would return negative values if the pattern would continue. Not sure what this means, but only my observation.   :cool:

NoCforMe

But those values depend on how you invoke the macro. What arguments did you invoke it with?
Assembly language programming should be fun. That's why I do it.

zedd151

Quote from: NoCforMe on October 18, 2024, 12:37:34 PMBut those values depend on how you invoke the macro. What arguments did you invoke it with?
No invoke. The macros are called upon startup, since 'start' is a procedure.
It seems to be enough that the testprolog and testepilog macros are decleared as "prologue" and "epilogue", in place of the deafult prologue and epilogue.

NoCforMe

So in other words they're being invoked without any arguments, correct? So whatever values you see there are defaults. (Shouldn't they be zero then, though?)
Assembly language programming should be fun. That's why I do it.