News:

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

Main Menu

Environment issue? Simple or not so simple?

Started by Nate523, September 13, 2024, 07:03:43 AM

Previous topic - Next topic

Vortex

Hi ognil,

Quote1. Don't touch the stack - it's aligned from the start.

Consider the simple 64-bit example below, why 28h is substracted from rsp instead of 4*8=20h ?

option casemap:none

EXTERN MessageBoxA:proc
EXTERN ExitProcess:proc

.data

text    db 'Hello world', 0
caption db '64-bit test', 0

.code

main PROC

    sub     rsp,28h
    xor     r9d,r9d
    lea     r8,caption
    lea     rdx,text
    xor     rcx,rcx
    call    MessageBoxA

    xor     ecx, ecx
    call    ExitProcess

main ENDP

END

ognil

#61
Thank you Vortex for the perfect example :thumbsup:
"Not keeping emotions under control is another type of mental distortion."

sinsi

Quote from: ognil on September 22, 2024, 05:21:17 AM1. Don't touch the stack - it's aligned from the start.
Only if you use a custom prologue which does it for you.

Quote from: ognil on September 22, 2024, 05:21:17 AM2. Forget about push, pop, invoke and macros, sub rsp, number, add rsp, number
If you know what you are doing, these instructions are perfectly fine to use.

Quote from: ognil on September 22, 2024, 05:21:17 AM3. Use ONLY global variables for arguments
Sorry, that's just wrong. Like NoCforMe said, what about recursion? Or multithreading?


We are talking about bare ASM, the mechanics of 64-bit programming using ML64.


Vortex

ognil,

I hope you are aware of the difference of my code and yours.

ognil

Thank you Vortex,

The difference is explained well in tenkey's post on page 3.
"Not keeping emotions under control is another type of mental distortion."

sinsi

ognil, the original post (and problem) didn't use masm64rt.inc so stack adjustment was needed.

Quote from: sinsi on September 22, 2024, 07:55:42 AMWe are talking about bare ASM, the mechanics of 64-bit programming using ML64.

ognil

Thank you sinsi,

I already agreed with you - see:
Quotefrom sinsi: The Usual Way is to allocate m...

and my:

'I agree with sinsi about "The Usual Way".....'
 :smiley:
"Not keeping emotions under control is another type of mental distortion."

mineiro

Windows have a loader, to load your program from device to memory. After, it do some management, relocation if necessary and call the entry point of your program.
So, if you look the RSP register value at entry point(mainCRTStartup), it will be something like: RSP=??????????????8h
The interrogation means that the RSP digits value in your machine can be different from my machine.
But, windows rule say: align stack to 16. Remember, stack walks from up to down.
Look for the rightmost hexadecimal digit from RSP. That 8 or 0?
If that is 8, means stack not aligned to 16, if that is 0 means stack aligned to 16.

Write down multiples of 16 and see the last nibble in hexadecimal base:
16*0 =  00h
16*1 =  10h
16*2 =  20h
16*3 =  30h
...
All mulitplications above ends with ?0h. So, at entry point of our program, we need subtract (up to down) 1*8 from RSP register to align.


So ok, stack is aligned to 16.
It's not done yet. Have a thing called "shadow space". We need reserve 4*8 bytes for it before using a call to an external function.
By luck, 4*8 in hexadecimal is 20h. And stack was aligned before, so, if we subtract from aligned stack the value 20h the stack value will continue aligned to 16.

This is why sub rsp,28h means:
sub rsp,(1*8)+(4*8)

After all is done, we need correct stack value back again, so we add:
add rsp,(1*8)+(4*8)

;ml64 /c test.asm
;link /entry:mainCRTStartup /subsystem:console test.obj
;test
option casemap:none
.code
mainCRTStartup PROC
                        ;rsp == ???????????????8
    sub     rsp,1*8     ;rsp == ???????????????0
    sub     rsp,4*8     ;rsp == ???????????????0

    ;stack aligned, we can call an external function from this point
    ;if that function uses more than 4 parameters (rcx,rdx,r8,r9), so, windows rule say that next parameters should be
    ;passed by stack, and this means that we need do stack arithmetic (align) again
   
    add     rsp,4*8     ;rsp == ???????????????0
    add     rsp,1*8     ;rsp == ???????????????8
    ret
mainCRTStartup ENDP
END
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

mineiro

So, if you aligned stack correctly, what problems can happen in a future?
Well, we need call external functions contained in libraries (.dll).
Most parameters that function uses generaly accepts qwords (8 bytes) as values.

So, lets write down again:
8*0 = 0h
8*1 = 8h
8*2 = 10h
8*3 = 18h
...

So, we can conclude from comparing multiplication from 8 and 16 that we need even number of paramenters instead of odd number of parameters.
If a function uses 6,8,10,12,... parameters thats ok, stack continue aligned.
If a function uses 5,7,9,11,,,, parameters, so we need store the last(s) parameter(s) in stack and this will unalign our aligned stack.

So, be even.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything