Hello fxm :-) => for updating the ASM documentation page on wiki
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Hello fxm :-) => for updating the ASM documentation page on wiki
Hello fxm I collected for my next FreeBASIC project in 2019 some notes about inline assembler from different places.
Can you add this short info's (if missing) to the right section in the wiki please.
The FreeBASIC ARM related stuff follows in 2019 if I port my new project for my Raspberry PI and the BeagleBone black.
My written English is to bad to do such official tasks.
Thank you my wiki hero :-)
Joshy
x86_32:
All arguments are passed on the stack.
The cdecl caller removes the arguments from the stack.
The stdcall called function removes the arguments from the stack.
An integer or pointer return value is returned in the eax register,
An 64-bit return value is returned in edx:eax .
while a floating-point return value is returned in st0.
A function must preserve ebx,ebp,esi,edi,esp
eax, ecx, edx are volatile.
x86_64:
The calling convention for cdecl and sdtcall are same !
The first four integer or pointer parameters are passed in the rcx, rdx, r8, and r9 registers.
The first four floating-point parameters are passed in the first four SSE registers, xmm0,xmm1, xmm2, xmm3.
The caller reserves space on the stack for arguments passed in registers.
The called function can use this space to spill the contents of registers to the stack.
Any additional arguments are passed on the stack.
An integer or pointer return value is returned in the rax register,
while a floating-point return value is returned in xmm0.
rax, rcx, rdx, r8, r9, r10, r11 are volatile.
rbx, rbp, rdi, rsi, r12, r13, r14, r15 are nonvolatile.
The calling convention for OOP is very similar.
The this pointer is passed as an implicit first parameter.
The next three parameters are passed in registers,
while the rest are passed on the stack.
Can you add this short info's (if missing) to the right section in the wiki please.
The FreeBASIC ARM related stuff follows in 2019 if I port my new project for my Raspberry PI and the BeagleBone black.
My written English is to bad to do such official tasks.
Thank you my wiki hero :-)
Joshy
x86_32:
All arguments are passed on the stack.
The cdecl caller removes the arguments from the stack.
The stdcall called function removes the arguments from the stack.
An integer or pointer return value is returned in the eax register,
An 64-bit return value is returned in edx:eax .
while a floating-point return value is returned in st0.
A function must preserve ebx,ebp,esi,edi,esp
eax, ecx, edx are volatile.
x86_64:
The calling convention for cdecl and sdtcall are same !
The first four integer or pointer parameters are passed in the rcx, rdx, r8, and r9 registers.
The first four floating-point parameters are passed in the first four SSE registers, xmm0,xmm1, xmm2, xmm3.
The caller reserves space on the stack for arguments passed in registers.
The called function can use this space to spill the contents of registers to the stack.
Any additional arguments are passed on the stack.
An integer or pointer return value is returned in the rax register,
while a floating-point return value is returned in xmm0.
rax, rcx, rdx, r8, r9, r10, r11 are volatile.
rbx, rbp, rdi, rsi, r12, r13, r14, r15 are nonvolatile.
The calling convention for OOP is very similar.
The this pointer is passed as an implicit first parameter.
The next three parameters are passed in registers,
while the rest are passed on the stack.
Last edited by fxm on Dec 19, 2018 12:03, edited 1 time in total.
Reason: Added subject to title
Reason: Added subject to title
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
I do not know the assembler and so not use the FreeBASIC Online Assembler.
I see differences, or even contradictions, between your information and those already existing in the ASM documentation page.
So I suggest to an assembler expert to see how to update the Asm documentation page:
- either by updating it directly on the wiki page,
- or by proposing in this topic a text of update which I would integrate then.
I see differences, or even contradictions, between your information and those already existing in the ASM documentation page.
So I suggest to an assembler expert to see how to update the Asm documentation page:
- either by updating it directly on the wiki page,
- or by proposing in this topic a text of update which I would integrate then.
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
@D.J.Peters,
About x86_64 only true for windows. Under Linux rules are a bit different (more registers used for parameters, "Red zone", volatile/non volatile).
I would post later for Linux later.
About x86_64 only true for windows. Under Linux rules are a bit different (more registers used for parameters, "Red zone", volatile/non volatile).
I would post later for Linux later.
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
; padding may be required to align the stack to 16 bytes.D.J.Peters wrote:All arguments are passed on the stack
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
You need stack alignment only if you create a stack frame from assembler code in case of FreeBASIC gcc does the stack alignment for us.jj2007 wrote:padding may be required to align the stack to 16 bytes.
Anyway it's a good point for the wiki documentation.
@SARG yes post the 64-bit Linux related assembler info's please.
I'm a old 16/32 bit assembler coder DOS, WINDOWS and hardcore Linux.
For example I wrote the ZIP drive kernel drivers
and some X-ORG VESA drivers for video Chip-sets without VESA 1 compatibility.
If you don't know what ZIP drives are: https://en.wikipedia.org/wiki/Zip_drive
How ever x86_64-bit and ARM assembler are new for me.
Joshy
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
OK. I just made a test, and it seems Gcc does that even for a 'naked' sub. Good to know, thanks.D.J.Peters wrote:You need stack alignment only if you create a stack frame from assembler code in case of FreeBASIC gcc does the stack alignment for us.jj2007 wrote:padding may be required to align the stack to 16 bytes.
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
my 2 cents
I think inline asm should be avoided if possible due to portability problem, however, there are times when it's needed or at least, convenient.
if performance is important, I would opt for naked functions or naked subs instead of inlining, when inlining you run the risk of altering registers that may be used for other purposes, like loop counters. [edit] don't know if gcc will automatically detect register usage and adjust accordingly
of course, you must always be careful about register use regardless.
here's an illustration of using a naked function and a macro, note that you can pass literals to the naked function but not to the macro (you can, but it will crash)
easily adapted to macOS and linux with option -asm att
I think inline asm should be avoided if possible due to portability problem, however, there are times when it's needed or at least, convenient.
if performance is important, I would opt for naked functions or naked subs instead of inlining, when inlining you run the risk of altering registers that may be used for other purposes, like loop counters. [edit] don't know if gcc will automatically detect register usage and adjust accordingly
of course, you must always be careful about register use regardless.
here's an illustration of using a naked function and a macro, note that you can pass literals to the naked function but not to the macro (you can, but it will crash)
Code: Select all
'' Windows x64, FB x64
'' first integer argument RCX
'' second integer argument RDX
'' third integer argument R8
'' fourth integer argument R9
function qr naked cdecl (byval a as ulongint , byval b as ulongint, byref r as ulongint ) as ulongint
asm
mov r9, rdx ''save value of b, because cqo will clobber it
mov rax, rcx''move value of a into rax
xor edx, edx
div r9 ''div a,b
mov [r8], rdx''move remainder into r
ret '' quotient in rax
end asm
end function
#macro qr_macro(a , b, q, r )
asm
mov rcx, [b]''move value of b into rcx
mov rax, [a]''move value of a into rax
xor edx, edx
div rcx ''div a,b
mov [r], rdx''move remainder into r
mov [q], rax''move quotient into q
end asm
#endmacro
dim as ulongint a, b, q, r
a=10
b=3
qr_macro(a,b,q,r)
print q,r
q=qr(a,b,r)
print q,r
q=qr(10,3,r)
print q,r
Code: Select all
function qr naked cdecl (byval a as ulongint , byval b as ulongint, byref r as ulongint ) as ulongint
asm
"mov %rdx, %r11" ''save address of r, because cqo will clobber it
"mov %rdi, %rax"''move value of a into rax
"xor %edx, %edx"
"div %rsi" ''div a,b
"mov %rdx, (%r11)"''move remainder into r
"ret" '' quotient in rax
end asm
end function
Last edited by srvaldez on Dec 20, 2018 2:34, edited 1 time in total.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
You are right if guys posts funky stuff only for one assembler mode without a compatible alternating.srvaldez wrote:my 2 cents I think inline asm should be avoided if possible due to portability problem ...
Why do you use the AT&T assembly syntax your FreeBASIC MAC version doesn't allow the INTEL syntax
like "fbc -w all -gen gcc -asm intel file.bas" ?
Joshy
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
no, FreeBASIC on the mac does not support intel syntaxD.J.Peters wrote: Why do you use the AT&T assembly syntax your FreeBASIC MAC version doesn't allow the INTEL syntax
like "fbc -w all -gen gcc -asm intel file.bas" ?
Joshy
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
Don't forget conditional compiling: #If _ismac_ ... #elseif _islinux_ ...
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
I'm waiting :-)SARG wrote:... I would post later for Linux ...
I can detect the AT&T syntaxsrvaldez wrote:no, FreeBASIC on the mac does not support intel syntax
#if __FB_ASM__ = "att"
---
#endif
But how to detect the fbc MAC version there isn't a __FB_MAC__ define ?
Joshy
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
hello D.J.Peters
try __FB_DARWIN__
try __FB_DARWIN__
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
:-(SARG wrote:@D.J.Peters
...I would post later for Linux later.
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
Joshy, thanks for the notes.
I think proper places would be:
Calling Conventions
stdcall
cdecl
pascal
asm
Looks like all these pages needs updates.
I started working on adding "thiscall" calling convention to fbc a few weeks back (another side quest adventure, hopefully I find my way back to the main quest line eventually).
thiscall on x86_64: meaningless
thiscall on x86_32, win32, "THIS" parameter in ECX register (for member procs by default), Right to Left, callee clean-up
thiscall on x86_32, linux, still investigating, caller clean-up, I think. Not all my tests pass.
I have been writing tests for cdecl, stdcall, thiscall, in fbc to call gcc/g++ classes & overloaded operators. x86 on win32 needs the thiscall convention to call member procs. But I've been finding either bugs or my own misunderstanding about the call conventions on each platform. So it's slow work. And -gen gcc only for now. There's no point in trying to modify -gen gas, until understand all that's going on in -gen gcc.
If anyone has experience with "thiscall" assembly and can add notes here, please do.
I think proper places would be:
Calling Conventions
stdcall
cdecl
pascal
asm
Looks like all these pages needs updates.
I started working on adding "thiscall" calling convention to fbc a few weeks back (another side quest adventure, hopefully I find my way back to the main quest line eventually).
thiscall on x86_64: meaningless
thiscall on x86_32, win32, "THIS" parameter in ECX register (for member procs by default), Right to Left, callee clean-up
thiscall on x86_32, linux, still investigating, caller clean-up, I think. Not all my tests pass.
I have been writing tests for cdecl, stdcall, thiscall, in fbc to call gcc/g++ classes & overloaded operators. x86 on win32 needs the thiscall convention to call member procs. But I've been finding either bugs or my own misunderstanding about the call conventions on each platform. So it's slow work. And -gen gcc only for now. There's no point in trying to modify -gen gas, until understand all that's going on in -gen gcc.
If anyone has experience with "thiscall" assembly and can add notes here, please do.
Re: Hello fxm :-) => for updating the ASM documentation page on wiki
Sorry to be so late. I forgot my reply ....D.J.Peters wrote::-(SARG wrote:@D.J.Peters
...I would post later for Linux later.
Windows ABI
-----------
params : rcx,rdx,r8,r9 + xmm0 to xmm3
Space for these registers also reserved on the stack to store them at the beginning of proc.
Important note : if the first arg is an integer number (not a float) it is put in rcx and if the second one is a float it is put in xmm0. But if the third
one is an integer, r8 (not rdx) is used. And so on. So only four registers (rNN or xmmN) are used. Other parameters are put on the stack.
ex : integer, float,integer, float -> rcx,xmm0,r8,xmm2
rbp,rbx,rdi,rsi,r12,r13,r14,r15 belong to calling proc, if used by called need to be saved by called
rcx,rdx,r8,r9,rax,r10,r11 belong to called proc, if used by calling need to be saved (before call)
Linux ABI
---------
params : rdi,rsi,rdx,rcx,r8,r9 + xmm0 to xmm7
Space for these registers also reserved on the stack to store them at the beginning of proc.
Differently from Windows ABI all the registers (rNN or xmmN) could be used for passing parameters. Other parameters are put on the stack.
rbx, r12 to r15 belong to calling proc, if used by called need to be saved by called
parameters + r10 r11 rax belong to called proc, if used by calling need to be saved (before call)
Red zone : an area (128 bytes= 16 regs * 8) should be reserved on the stack, seems not often used