Terraspace / UASM

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

Uasm sometimes generate unnecessary rex prefix #200

Open ntysdd opened 5 months ago

ntysdd commented 5 months ago

For the program below,

.x64
.model flat, fastcall
option win64:3
option frame:auto

.code
func proc arg1:dword
mov eax, arg1
ret
func endp
end

Uasm generates these instructions,

0000000000000000 <func>:
   0:   89 4c 24 08             mov    %ecx,0x8(%rsp)
   4:   48 55                   rex.W push %rbp
   6:   48 8b ec                mov    %rsp,%rbp
   9:   8b 45 10                mov    0x10(%rbp),%eax
   c:   48 8b e5                mov    %rbp,%rsp
   f:   5d                      pop    %rbp
  10:   c3                      ret

The rex.W before push %rbp is unnecessary because it's not the 1st instruction. As far as I know, it's only used because push %rbp is only 1-byte long and that doesn't work well with hot patching.

john-terraspace commented 5 months ago

That is the reason it generates the REX, as other M$ tools were observed to do the same. I didn’t have any clear evidence that not doing it would impact anything in future Visual Studio versions once 64bit hot editing was supported. If we can confirm it has no impact removing it I’m happy to get rid of it.

From: ntysdd @.> Sent: Saturday, April 13, 2024 6:33 AM To: Terraspace/UASM @.> Cc: Subscribed @.***> Subject: [Terraspace/UASM] Uasm sometimes generate unnecessary rex prefix (Issue #200)

For the program below,

.x64 .model flat, fastcall option win64:3 option frame:auto

.code func proc arg1:dword mov eax, arg1 ret func endp end

Uasm generates there instructions.

0000000000000000 : 0: 89 4c 24 08 mov %ecx,0x8(%rsp) 4: 48 55 rex.W push %rbp 6: 48 8b ec mov %rsp,%rbp 9: 8b 45 10 mov 0x10(%rbp),%eax c: 48 8b e5 mov %rbp,%rsp f: 5d pop %rbp 10: c3 ret

The rex.W before push %rbp is unnecessary because it's not the 1st instruction. As far as I know, it's only used because push %rbp is only 1-byte long and that doesn't work well with hot patching.

— Reply to this email directly, view it on GitHub https://github.com/Terraspace/UASM/issues/200 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AEAZAVCLGV56EUQQ76ACPS3Y5C7RBAVCNFSM6AAAAABGFFZWUCVHI2DSMVQWIX3LMV43ASLTON2WKOZSGI2DCMZSGAYDOMI . You are receiving this because you are subscribed to this thread. https://github.com/notifications/beacon/AEAZAVAFN2P7GFHLYX45QZDY5C7RBA5CNFSM6AAAAABGFFZWUCWGG33NNVSW45C7OR4XAZNFJFZXG5LFVJRW63LNMVXHIX3JMTHILF6UQ4.gif Message ID: @. @.> >

ntysdd commented 5 months ago

These articles may help.

x64 exception handling

rex_push_reg reg    Saves a nonvolatile register on the stack using a 2-byte push, and emits the appropriate unwind information (.pushreg reg). Use this macro if the push is the first instruction in the function, to ensure that the function is hot-patchable.

Why don’t Windows functions begin with a pointless MOV EDI,EDI instruction on x86-64

push: If the function pushes any registers r8 or higher, those can be pushed first, since the push of a high-numbered register is a two-byte instruction. Or the instruction could be re-encoded with a redundant REX prefix 0x48. Alternatively, the compiler could save the register in the home space, which uses a multi-byte mov [rsp+n], r instruction
john-terraspace commented 1 month ago

Fixed in 2.57