This sentence seems absurd to me:
Basically, the simple act of defining the PROC with parameters means that you will be accessing the spill area.
Well of course i'm going to access the spill area, anyone would, because there(in spill area, shadow space) lies first four arguments.
Spill area / Shadow space is 32 bytes long and even more, if procedure have more than four arguments.
Otherwise, if you weren't planning on doing that then you would define a simple PROC with zero parameters.
Yes, generally, no one needs to access spill space/shadow space, if procedure doesn't have any arguments.
But what about a PROC with 5 or more arguments where we may or may not want to spill registers but we need the stack frame built and param offsets equated in order to access the 5th, 6th, 7th, or 8th parameter(s)?
Yes, and parameters/arguments are stack/base frame offset's.
Stack space is already allocated by the caller.
If your procedure have 13 arguments, then caller must allocate this space to store those arguments and have a valid call to this procedure who have 13 arguments.
If your procedure have 13 arguments, caller allocates 13 * 8 + stack alignment space.
If your procedure have 13 arguments:
1. first four arguments are passed via registers and, on procedure side they are save into spill space/shadow space/register home address space.
1.1. !!! If procedure will not save these first four arguments they might be lost due to of call of internal procedure or else.
2. other 9 arguments are already saved on stack.
+ Yes there is a need for stack frame pointer, like RBP.
Later on, in procedure that had those 13 arguments:
First argument is accessed via RBP+8*2.
Second argument is accessed via RBP+8*3.
Third argument is accessed via RBP+8*4.
And so on...
Basic idea:
Catch idea or my insanity(it seems, im the only one who understands what im talking about).
Did i ever tell you the definition of "Insanity"??x64 -> Macro idea versus plain code.
1. Macro procedure example:
; *******************************************
;
; Procedure: testProcA
; argument: ptrMessage
; argument: ptrTitle
;
; Procedure takes two arguments and call's MessageBox.
;
;
proc testProc,ptrdiff_t ptrMessage,ptrdiff_t ptrTitle
locals none
invoke MessageBox,ptrdiff_t [argv(.ptrMessage)],ptrdiff_t [argv(.ptrTitle)],0
xor rax,rax
endproc
2. Plain code procedure example:
; *******************************************
;
; Procedure: testProcA
; argument: ptrMessage
; argument: ptrTitle
;
; Procedure takes two arguments and call's MessageBox.
;
align 16
testProcA:
;
; Save arguments
;
mov [rsp+8*1],rcx
mov [rsp+8*2],rdx
%define ptrMessage rbp+8*2
%define ptrTitle rbp+8*3
;
; Create stack
;
push rbp
mov rbp,rsp
lea rsp,[rsp-8*4]
xor rcx,rcx
mov rdx,[ptrMessage]
mov r9,[ptrTitle]
xor r8,r8
call MessageBoxA
xor rax,rax
.quit:
;
; Clear stack n quit
;
lea rsp,[rsp+8*4]
pop rbp
ret
So, procedure testProcA, takes two arguments, then i save them into spill space/shadow space/home location.
Later on, i use "ptrMessage" to access first argument and so on.
And by the way, this is only my suggestion.
At least that part felt so wrong, when invoke macro,
tried to store first four arguments into stack before a call is made.At procedure, procedure code is responsible to store/save first four arguments registers into spill space/shadow space/home location.And that's it.
Bye,
Encryptor256.