Hello fxm :-) => for updating the ASM documentation page on wiki

Forum for discussion about the documentation project.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Hello fxm :-) => for updating the ASM documentation page on wiki

Post by D.J.Peters »

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.
Last edited by fxm on Dec 19, 2018 12:03, edited 1 time in total.
Reason: Added subject to title
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by fxm »

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.
SARG
Posts: 1755
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by SARG »

@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.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by jj2007 »

D.J.Peters wrote:All arguments are passed on the stack
; padding may be required to align the stack to 16 bytes.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by D.J.Peters »

jj2007 wrote:padding may be required to align the stack to 16 bytes.
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.

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
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by jj2007 »

D.J.Peters wrote:
jj2007 wrote:padding may be required to align the stack to 16 bytes.
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.
OK. I just made a test, and it seems Gcc does that even for a 'naked' sub. Good to know, thanks.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by srvaldez »

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)

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
easily adapted to macOS and linux with option -asm att

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.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by D.J.Peters »

srvaldez wrote:my 2 cents I think inline asm should be avoided if possible due to portability problem ...
You are right if guys posts funky stuff only for one assembler mode without a compatible alternating.

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
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by srvaldez »

D.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
no, FreeBASIC on the mac does not support intel syntax
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by jj2007 »

Don't forget conditional compiling: #If _ismac_ ... #elseif _islinux_ ...
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by D.J.Peters »

SARG wrote:... I would post later for Linux ...
I'm waiting :-)
srvaldez wrote:no, FreeBASIC on the mac does not support intel syntax
I can detect the AT&T syntax
#if __FB_ASM__ = "att"
---
#endif

But how to detect the fbc MAC version there isn't a __FB_MAC__ define ?

Joshy
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by srvaldez »

hello D.J.Peters
try __FB_DARWIN__
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by D.J.Peters »

SARG wrote:@D.J.Peters
...I would post later for Linux later.
:-(
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by coderJeff »

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.
SARG
Posts: 1755
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Hello fxm :-) => for updating the ASM documentation page on wiki

Post by SARG »

D.J.Peters wrote:
SARG wrote:@D.J.Peters
...I would post later for Linux later.
:-(
Sorry to be so late. I forgot my reply ....

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
Post Reply