Terraspace / UASM

UASM - Macro Assembler
http://www.terraspace.co.uk/uasm.html
Other
221 stars 49 forks source link

Is it possible to suppress stack alignment? #118

Closed db4 closed 4 years ago

db4 commented 5 years ago

I have a lot of code that returns result from function in CF:

.CODE

option WIN64: 1

func PROC
     ; some processing
     stc
     ret
func ENDP

END

UASM assembles that as

func:
  0000000000000000: 48 83 EC 08        sub         rsp,8
  0000000000000004: F9                 stc
  0000000000000005: 48 83 C4 08        add         rsp,8
  0000000000000009: C3                 ret

and add rsp, 8 always clears CF. How to avoid that? Looking into docs I see

Japheth introduced W64F_STACKALIGN16 in v2.12 because he was storing locals in reverse order: the first local was stored the last, so it wasn’t possible to have the first local aligned 16.

This has been changed it so that the first local is first after the stack homing area and is guaranteed to always be aligned to a 16 byte boundary.

Does it mean that sub rsp,8/ add rsp,8 cannot be suppressed?

john-terraspace commented 5 years ago

Returning results via CF isn’t really ABI compliant, but if you want to you could either switch off prologue/epilogue completely for the function or look at one of the modes that would optimise it out (given the function takes no params/no locals or invokes – however that is risky as you have to always remember that state). In this case I would opt to switch off prologue/epilogue with option proc:none

From: Dmitry Bely notifications@github.com Sent: 06 November 2019 07:14 To: Terraspace/UASM UASM@noreply.github.com Cc: Subscribed subscribed@noreply.github.com Subject: [Terraspace/UASM] Is it possible to suppress stack alignment? (#118)

I have a lot of code that returns result from function in CF:

.CODE

option WIN64: 1

func PROC

 ; some processing

 stc

 ret

func ENDP

END

UASM assembles that as

func:

0000000000000000: 48 83 EC 08 sub rsp,8

0000000000000004: F9 stc

0000000000000005: 48 83 C4 08 add rsp,8

0000000000000009: C3 ret

and add rsp, 8 always clears CF. How to avoid that? Looking into docs I see

Japheth introduced W64F_STACKALIGN16 in v2.12 because he was storing locals in reverse order: the first local was stored the last, so it wasn’t possible to have the first local aligned 16.

This has been changed it so that the first local is first after the stack homing area and is guaranteed to always be aligned to a 16 byte boundary.

Does it mean that sub rsp,8/ add rsp,8 cannot be suppressed?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Terraspace/UASM/issues/118?email_source=notifications&email_token=AEAZAVDKDHRMAZQAYFXI4W3QSJVDDA5CNFSM4JJQWBFKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HXEM4YQ , or unsubscribe https://github.com/notifications/unsubscribe-auth/AEAZAVEEOSWQGQFOT4CA4CLQSJVDDANCNFSM4JJQWBFA .

db4 commented 5 years ago

Returning results via CF isn’t really ABI compliant

These are my private functions used internally so no ABI is involved.

but if you want to you could either switch off prologue/epilogue completely for the function or look at one of the modes that would optimise it out

Unfortunately switching off prologue/epilogue is not an option. Many of my functions have USES clause that is just ignored when option proc:none is set:

.CODE

option PROC:none

func PROC PRIVATE uses rbx
     mov rbx, 0
     stc
     ret
func ENDP

UASM-generated code (no compilation error!):

func:
  0000000000000000: 48 C7 C3 00 00 00  mov         rbx,0
                    00
  0000000000000007: F9                 stc
  0000000000000008: C3                 ret

BTW, JWasm just did it right without any special efforts:

.CODE

func PROC PRIVATE uses rbx
     mov rbx, 0
     stc
     ret
func ENDP

JWasm-generated code:

func:
  0000000000000000: 53                 push        rbx
  0000000000000001: 48 C7 C3 00 00 00  mov         rbx,0
                    00
  0000000000000008: F9                 stc
  0000000000000009: 5B                 pop         rbx
  000000000000000A: C3                 ret

So my original question: can I somehow switch off 16-byte stack alignment and return to original JWasm behavior? If not, maybe it's worth an option?

db4 commented 5 years ago

@john-terraspace

Returning results via CF isn’t really ABI compliant, but if you want to you could either switch off prologue/epilogue completely for the function or look at one of the modes that would optimise it out

I finally solved the CF problem replacing sub rsp,n/add rsp,n in prologue/epilogue with lea rsp,[rsp-n]/lea rsp,[rsp+n] that preserve flags. But lea CPU instruction is one byte longer than sub/add. Is it acceptable code size increase or it should be made optional? I currently switch it on with a C define but maybe an asm run-time option is a better way to go? I'm asking this because I'm going to submit a PR.

john-terraspace commented 5 years ago

I think some sort of switch for that would be ideal, keep the regular shorter pro/epilogue and when you want to preserve flags across the call we use another switch.

I want to avoid adding more options like WIN64:n as that starts all getting very messy, perhaps a new modifier on the PROC itself

MyProc PROC FRAME PRESERVEFLAGS USES a b c ..

Something like that to keep it simple on a proc by proc basis ?

From: Dmitry Bely notifications@github.com Sent: 11 November 2019 12:21 To: Terraspace/UASM UASM@noreply.github.com Cc: John Hankinson john@terraspace.co.uk; Mention mention@noreply.github.com Subject: Re: [Terraspace/UASM] Is it possible to suppress stack alignment? (#118)

@john-terraspace https://github.com/john-terraspace

Returning results via CF isn’t really ABI compliant, but if you want to you could either switch off prologue/epilogue completely for the function or look at one of the modes that would optimise it out

I finally solved the CF problem replacing sub rsp,n/add rsp,n in prologue/epilogue with lea rsp,[rsp-n]/lea rsp,[rsp+n] that preserve flags. But lea CPU instruction is one byte longer than sub/add. Is it acceptable code size increase or it should be made optional? I currently switch it on with a C define but maybe an asm run-time option is a better way to go? I'm asking this because I'm going to submit a PR.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Terraspace/UASM/issues/118?email_source=notifications&email_token=AEAZAVH6HK4JNL2XIL76MBDQTFEZVA5CNFSM4JJQWBFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDWU45A#issuecomment-552423028 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AEAZAVF5RGBYVPJROMFOXNTQTFEZVANCNFSM4JJQWBFA .

db4 commented 5 years ago

MyProc PROC FRAME PRESERVEFLAGS USES a b c .. Something like that to keep it simple on a proc by proc basis ?

Frankly speaking, I would like to avoid this because (at least in my case) it requires massive changes to the existing code base that is currently compiled by JWasm and that I'm going to port to UASM (both Win64 and Linux64)

what about option FRAMEPRESERVEFLAGS:YES or something like that? (maybe in addition to proc parameter)

john-terraspace commented 5 years ago

I can live with that 😊

From: Dmitry Bely notifications@github.com Sent: 11 November 2019 13:48 To: Terraspace/UASM UASM@noreply.github.com Cc: John Hankinson john@terraspace.co.uk; Mention mention@noreply.github.com Subject: Re: [Terraspace/UASM] Is it possible to suppress stack alignment? (#118)

MyProc PROC FRAME PRESERVEFLAGS USES a b c .. Something like that to keep it simple on a proc by proc basis ?

Frankly speaking, I would like to avoid this because (at least in my case) it requires massive changes to the existing code base that is currently compiled by JWasm and that I'm going to port to UASM (both Win64 and Linux64)

what about option FRAMEPRESERVEFLAGS:YES or something like that? (maybe in addition to proc parameter)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Terraspace/UASM/issues/118?email_source=notifications&email_token=AEAZAVEW2UQHVY5JRPLDYN3QTFPBHA5CNFSM4JJQWBFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDW4CMQ#issuecomment-552452402 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AEAZAVEZAXCTU75VSI7WSVDQTFPBHANCNFSM4JJQWBFA .

db4 commented 5 years ago

what about option FRAMEPRESERVEFLAGS:YES

I can live with that 😊

Well, if you have a better name in your mind I would love to know it! :)

BTW, could you review https://github.com/Terraspace/UASM/pull/121? The discussed PR is based on it.

john-terraspace commented 4 years ago

Updated and merged #121 into 2.50

I've added this option as well now if you want to give 2.50 branch a test.