No 64-bit support?

Problems which concern EuroAssembler
ar18
Posts: 29
Joined: 27 Aug 2018 13:38

No 64-bit support?

Unread postby ar18 » 28 Aug 2018 02:50

I noticed that in all of the macros, that they only support Win32 and not Win64. Is this because €ASM is still new and that is a feature not yet available?

A few other observations:

1) I don't see where the stack is aligned on 16-byte boundaries for a Procedure as it should be per the Win64 ABI
2) No provision is made for setting registers xmm0 through xmm3 for the first four parameters of a function call per the Win64 ABI for float values
3) No provision is made for saving registers xmm6 through xmm15 to the stack when needed per the Win64 ABI

Would you like some help with this?
User avatar
vitsoft
Site Admin
Posts: 46
Joined: 04 Nov 2017 20:08
Location: Vítkov, The Czech Republic
Contact:

Re: No 64-bit support?

Unread postby vitsoft » 28 Aug 2018 22:21

ar18 wrote: 28 Aug 2018 02:50 I noticed that in all of the macros, that they only support Win32 and not Win64. Is this because €ASM is still new and that is a feature not yet available?
Many libraries shipped with €ASM contain macros for 64bit mode, as declared in the column Width at https://euroassembler.eu/maclib/
ar18 wrote: 1) I don't see where the stack is aligned on 16-byte boundaries for a Procedure as it should be per the Win64 ABI
2) No provision is made for setting registers xmm0 through xmm3 for the first four parameters of a function call per the Win64 ABI for float values
3) No provision is made for saving registers xmm6 through xmm15 to the stack when needed per the Win64 ABI
Would you like some help with this?
1) Stack alignment in 64bit WinAPI is provided by the pair of instructions PUSH RSP and ADDQ [RSP],8, which is or is not skipped depending on runtime stack alignment tested with instruction TEST SPL,1000b. I hope this mechanism is better explained in the example at https://euroassembler.eu/maclib/fastcall.htm#pcFastCall
2) 3) I don't have to bother with calee-save registers if I'm not using them in my function, do I?
Are there some API functions which use XMM for passing parameters? I know this possibility is specified in ABI but I don't see any useful application of such ABI call, which I could use for debugging. If you are experienced in using SIMD in Windows ABI, ar18, I would appreciate some ideas, of course.
ar18
Posts: 29
Joined: 27 Aug 2018 13:38

Re: No 64-bit support?

Unread postby ar18 » 29 Aug 2018 01:25

vitsoft wrote: 28 Aug 2018 22:21 Many libraries shipped with €ASM contain macros for 64bit mode, as declared in the column Width at https://euroassembler.eu/maclib/
Well let's talk about that, but first ...
vitsoft wrote: 28 Aug 2018 22:21 1) Stack alignment in 64bit WinAPI is provided by the pair of instructions PUSH RSP and ADDQ [RSP],8, which is or is not skipped depending on runtime stack alignment tested with instruction TEST SPL,1000b. I hope this mechanism is better explained in the example at https://euroassembler.eu/maclib/fastcall.htm#pcFastCall
That sounds good but that isn't what I'm seeing. I'm confused so here is what I am seeing for WinApi macro for example:

WinAPI %MACRO Function, Argument1, Argument2,,,Lib=
%ParNr %SETA %# ; Number of ordinal arguments + 1.
%WHILE %ParNr > 1
PUSHD %*{%ParNr} ; Put operands on stack, begin with the last.
%ParNr %SETA %ParNr-1
%ENDWHILE
reg %IF TYPE# %Function = 'R' ; If the function is specified in register.
CALL %Function
%ELSE reg ; The function is specified by its name.
%suffix %SET ; First assume no suffix.
fn %FOR %WinANSI ; Examine if Function is on the list %WinANSI.
%IF "%fn" === "%Function"
%suffix %SETC ('W' & (%^UNICODE)) + ('A' & ~(%^UNICODE))
%EXITFOR fn ; No need for further investigation if found.
%ENDIF
%ENDFOR fn
IMPORT %Function%suffix, Lib=%Lib
CALL %Function%suffix
%ENDIF reg
%ENDMACRO WinAPI


That is for 32-bit only, not 32- and 64-bit, so what am I missing?
vitsoft wrote: 28 Aug 2018 22:21 2) 3) I don't have to bother with calee-save registers if I'm not using them in my function, do I?
Are there some API functions which use XMM for passing parameters? I know this possibility is specified in ABI but I don't see any useful application of such ABI call, which I could use for debugging. If you are experienced in using SIMD in Windows ABI, ar18, I would appreciate some ideas, of course.
How can I explain this in simple terms? Let me try ...

I am experienced having written a few full fledged 64-bit programs, like a Paint program written completely with GoAsm, so I'm very familiar with how it works and it works like this:

invoke fnTest,p1,p2,p3,p4,p5,,,p10

push p10 ; Put operands on stack, begin with the last.
.
.
.
push p5 ; = any value, whether GP, float, or double
mov r9,p4 ; for any GP value
___________; or movss xmm3,p4 for a float/real4/single precision
___________; or movsd xmm3,p4 for a double/real8
mov r8,p3 ; or movss xmm2,p3 or movsd xmm2,p3
mov rdx,p2 ; or movss xmm1,p2 or movsd xmm1,p2
mov rcx,p1 ; or movss xmm0,p1 or movsd xmm0,p1
sub rsp,8*4 ; always reserve shadow space (even if just one param being passed) unless leaf function
call fnTest
add rsp,8*(numberOfParams)


or

invoke fnTest,p1

mov rcx,p1 ; or movss xmm0,p1 or movsd,xmm0,p1
sub rsp,8*4 ; always reserve shadow space (even if just one param being passed) unless leaf function
call fnTest
add rsp,8*4 ; minimum number of qwords is always 4, no matter how many or few params are passed


And that in a nutshell is SIMD in Windows per the Win64 ABI. Of course it can get complicated, such as when a register is passed as a parameter.

Your assembler seems very thoroughly put together, so I'm certain you probably have the equivalent of "USES" for GP and SIMD registers, am I right? For saving non-volatile xmm registers, it first needs to be moved to a GP register, then pushed, or transferred directly to the stack with a movaps [rsp+?],xmm6.
Last edited by ar18 on 29 Aug 2018 12:20, edited 4 times in total.
ar18
Posts: 29
Joined: 27 Aug 2018 13:38

Re: No 64-bit support?

Unread postby ar18 » 29 Aug 2018 01:44

vitsoft wrote: 28 Aug 2018 22:21 1) Stack alignment in 64bit WinAPI is provided by the pair of instructions PUSH RSP and ADDQ [RSP],8, which is or is not skipped depending on runtime stack alignment tested with instruction TEST SPL,1000b. I hope this mechanism is better explained in the example at https://euroassembler.eu/maclib/fastcall.htm#pcFastCall
Just FYI, that is an interesting way to align the stack. For comparison, this is how it is done by ...

GoASM: push qword ptr ss:[rsp]
_______and spl,F0

and

NASM: and rsp,0FFFFFFFFFFFFFFF0h
ar18
Posts: 29
Joined: 27 Aug 2018 13:38

Re: No 64-bit support?

Unread postby ar18 » 29 Aug 2018 13:38

vitsoft wrote: 28 Aug 2018 22:21 2) 3) I don't have to bother with calee-save registers if I'm not using them in my function, do I?
Are there some API functions which use XMM for passing parameters? I know this possibility is specified in ABI but I don't see any useful application of such ABI call, which I could use for debugging. If you are experienced in using SIMD in Windows ABI, ar18, I would appreciate some ideas, of course.
Sometimes a bit of pseudocode will help better than any explanation ...

api %MACRO Function, Argument1, Argument2,,,Lib=
____%i %SETA %#
____%j %FOR %i..1
________%IF %i=4
____________%IF TYPE# %j = 'real4'
________________movss xmm3,%j
____________%ELSEIF TYPE# %j = 'real8'
________________movsd xmm3,%j
____________%ELSE
________________mov r9,%j
________________%ENDIF
_______%ELSEIF %i=3
____________%IF TYPE# %j = 'real4'
_______________movss xmm2,%j
____________%ELSEIF TYPE# %i = 'real8'
________________movsd xmm2,%j
____________%ELSE
________________mov r8,%j
________________%ENDIF
_______%ELSEIF %i=2
___________%IF TYPE# %j = 'real4'
________________movss xmm1,%i
____________%ELSEIF TYPE# %j = 'real8'
________________movsd xmm1,%j
____________%ELSE
________________mov rdx,%j
________________%ENDIF
________%ELSEIF %i=1
____________%IF TYPE# %j = 'real4'
________________movss xmm0,%j
____________%ELSEIF TYPE# %j = 'real8'
________________movsd xmm0,%j
____________%ELSE
________________mov rcx,%j
________________%ENDIF
________%ELSE
________________%IF TYPE# %j = 'xmm'
________________movq rax,%j
________________push %j
____________%ELSE
________________push %j
________________%ENDIF
_______%i %SETA %i-1
_______%ENDFOR
____sub rsp,8*4 ; Reserve shadow space
____%IF TYPE# %Function = 'R' ; If the function is specified in register.
_______CALL %Function
____%ELSE ; The function is specified by its name.
_______%suffix %SET ; First assume no suffix.
_______%FOR %WinANSI ; Examine if Function is on the list %WinANSI.
____________%IF "%fn" === "%Function"
________________%suffix %SETC ('W' & (%^UNICODE)) + ('A' & ~(%^UNICODE))
________________%EXITFOR fn ; No need for further investigation if found.
________________%ENDIF
____________%ENDFOR
_______IMPORT %Function%suffix, Lib=%Lib
_______call %Function%suffix
_______%ENDIF
____%i %SETA %#-1
____%IF %i<4
_______%i %SETA 4
_______%ENDIF
____add rsp,8*%i
____%ENDMACRO api
Last edited by ar18 on 29 Aug 2018 23:42, edited 1 time in total.
User avatar
vitsoft
Site Admin
Posts: 46
Joined: 04 Nov 2017 20:08
Location: Vítkov, The Czech Republic
Contact:

Re: No 64-bit support?

Unread postby vitsoft » 29 Aug 2018 21:32

ar18 wrote: 29 Aug 2018 01:25 That sounds good but that isn't what I'm seeing. I'm confused so here is what I am seeing for WinApi macro for example:
The source of your confusion is that there are two versions of macro WinAPI: 32bit in the library winapi.htm, and 64bit in winabi.htm https://euroassembler.eu/maclib/winabi.htm#WinAPI, and you were looking at the former one.
Unfortunately only one of them is listed on Index page (I should do something about it, I know).
The reason to keep homonymous macro names in different libraries is to make porting from 32bit programs to 64 bit easy.
Win32 programs should include winapi.htm and Win64 should include winabi.htm. Notice that both programs in the following source are almost identical:
EUROASM CPU=X64, AMD=True

Hello32 PROGRAM Format=PE, Entry=Main:, WIDTH=32
INCLUDE winapi.htm
Main: WinAPI MessageBox,0,="Hello, world of %^WIDTH bits!",="Testing",0, Lib=user32.dll
TerminateProgram
ENDPROGRAM Hello32

Hello64 PROGRAM Format=PE, Entry=Main:, WIDTH=64
INCLUDE winabi.htm
Main: WinAPI MessageBox,0,="Hello, world of %^WIDTH bits!",="Testing",0, Lib=user32.dll
TerminateProgram
ENDPROGRAM Hello64

I'm aware that MASM, NASM or GoASM do fastcall stack alignment differently. I don't say that my method is better or worse but it works, as proved in sample 64bit Projects https://euroassembler.eu/objlib/
ar18
Posts: 29
Joined: 27 Aug 2018 13:38

Re: No 64-bit support?

Unread postby ar18 » 29 Aug 2018 23:31

vitsoft wrote: 29 Aug 2018 21:32 The source of your confusion is that there are two versions of macro WinAPI: 32bit in the library winapi.htm, and 64bit in winabi.htm https://euroassembler.eu/maclib/winabi.htm#WinAPI, and you were looking at the former one.

Unfortunately only one of them is listed on Index page (I should do something about it, I know).
Okay, now I know.
vitsoft wrote: 29 Aug 2018 21:32 The reason to keep homonymous macro names in different libraries is to make porting from 32bit programs to 64 bit easy.
Win32 programs should include winapi.htm and Win64 should include winabi.htm.
I wasn't aware of that either, but now that I am, I will start testing this tomorrow with my first program. I cannot test €ASM with the Paint program yet, since €ASM doesn't support SIMD per the Win64 ABI.
vitsoft wrote: 29 Aug 2018 21:32 I'm aware that MASM, NASM or GoASM do fastcall stack alignment differently. I don't say that my method is better or worse but it works, as proved in sample 64bit Projects https://euroassembler.eu/objlib/
Please don't take what I said as a criticism, I was just showing how differently everyone like to do this. I thought it might give you some ideas. It did with me when I used NASM because NASM has no PROC or FRAME or LOCALS and you must do everything by hand. I used the AND for alignment because it was simple and concise.

The problem with GoAsm though is that the stack is aligned and unaligned with each and every INVOKE (that is 12 bytes per INVOKE), leading to a huge amount of exe bloat. A 64-bit program that assembles to 5k with every other assembler in the world, assembles to 7k with GoAsm. My 64-bit Paint program has a whopping 10k of bloat with GoAsm, entirely due to INVOKE!

Who is online

Users browsing this forum: No registered users and 0 guests