Page 1 of 2

Question about inline assembler and C backend.

Posted: Thu Feb 06, 2025 11:12 am
by Armoured
I don't have experience with assembly programming, but after testing various examples, I noticed that they only work if the C backend is not used.
I was wondering if it is currently possible to use inline assembly with the C backend, and if so, how?

Thanks

Re: Question about inline assembler and C backend.

Posted: Thu Feb 06, 2025 11:30 am
by Fred
Sure you can, but you need to use the gcc syntax: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

Re: Question about inline assembler and C backend.

Posted: Thu Feb 06, 2025 1:41 pm
by Armoured
With the asm{} keyword? Could you also provide a simple example?
Thanks.

Re: Question about inline assembler and C backend.

Posted: Thu Feb 06, 2025 3:53 pm
by jack
gcc extended asm is a very strange animal, it takes a special kind of mindset to understand it, you can find small examples on the web but it's tricky to adapt to PB
here's an ultra-simple and useless example

Code: Select all

Procedure.d get_pi()

    Define.d pi

    !asm (
    !    "fldpi\n"
    !    "fstpl   %[v_pi]\n"
    !    :[v_pi]"=m"(v_pi)::
    !);

    ProcedureReturn pi
  EndProcedure
  
  Define.d n
  n=get_pi()
  Debug n
  
fortunately you can also use intel syntax, not sure who the original author is

Code: Select all

Procedure bswap(v.l) 
  Protected ret.l 
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    !".intel_syntax noprefix";
    !"mov eax, v_v";
    !"bswap eax"; 
    !"mov v_ret, eax";
  CompilerElse 
    !mov eax, [p.v_v]
    !bswap eax 
    !mov [p.v_ret],eax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure 

x.i = $FF000000 
Debug RSet(Hex(x),8,"0")
x = bswap(x) 
Debug RSet(Hex(x),8,"0")

Re: Question about inline assembler and C backend.

Posted: Thu Feb 06, 2025 6:00 pm
by jack
a slightly more interesting example using the gcc extended inline syntax

Code: Select all

Procedure.q fib(ub.l, *f)
  If (ub<3) 
    ProcedureReturn 1
  EndIf
  ;  !set_dpfpu();
    !asm (
    !    "mov %[p_f], %%rax;"
    !    "fldz;"
    !    "fistl (%%rax);"
    !    "add $8, %%rax;"
    !    "fld1;"
    !    "fistl (%%rax);"
    !    "add $8, %%rax;"
    !    "mov %[v_ub], %%ecx;"
    !    "sub $2, %%ecx;"
    !    "fib2:"
    !    "fxch %%st(1);"
    !    "fadd %%st(1),%%st(0);"
    !    "fld %%st(0);"
    !    "fistpq (%%rax);"
    !    "add $8, %%rax;"
    !    "dec %%ecx;"
    !    "jg fib2;"
    !    "fstp %%st(0);"
    !    "fstp %%st(0);" 
    !     :[p_f]"=m"(p_f)
    !     :[v_ub]"m"(v_ub)
    !     :"rax","ecx"
    !);
    ProcedureReturn
  EndProcedure
  
  Dim fibonacci.q(20)
  n.l=20
  fib(n+1, @fibonacci(0))
  For i.l=0 To n
   Debug fibonacci(i)
  Next
  

Re: Question about inline assembler and C backend.

Posted: Thu Feb 06, 2025 6:34 pm
by Armoured
Thanks Jack! Your examples have been really helpful for understanding how to insert inline assembly code, which I couldn’t find in the PureBasic manual. I have one last question: could you point me to some tutorials or books on assembly that support this syntax (AT&T, if I understood correctly)?

Re: Question about inline assembler and C backend.

Posted: Thu Feb 06, 2025 7:28 pm
by jack
I don't know of any books or tutorials except for bits and pieces on the web, perhaps some other member knows
this could be useful https://github.com/namantam1/x86-assembly

Re: Question about inline assembler and C backend.

Posted: Thu Feb 06, 2025 10:56 pm
by mk-soft
If you use ASM code in C-Backend, you have problems at the latest if you want to run the code on a machine with ARM (Raspberry, Window for ARM) or M1 (macOS).

So I never become ASM in C-backend.

Re: Question about inline assembler and C backend.

Posted: Fri Feb 07, 2025 5:06 am
by idle
I thought about this for awhile as it would be nice to still be able to use intel asm from the c backend
and while the demo isn't particularly useful it wouldn't be to hard to turn into a compiler tool so it generates a data section and loads it.
https://www.purebasic.fr/english/viewtopic.php?t=86226

Re: Question about inline assembler and C backend.

Posted: Fri Feb 07, 2025 12:19 pm
by Armoured
mk-soft wrote: Thu Feb 06, 2025 10:56 pm If you use ASM code in C-Backend, you have problems at the latest if you want to run the code on a machine with ARM (Raspberry, Window for ARM) or M1 (macOS).

So I never become ASM in C-backend.
You are absolutely right, but unfortunately I need to generate an atomic variable to optimize a thread, and portability is not my priority in this case. If you have any alternatives that do not require the use of assembly, I'm interested.

Re: Question about inline assembler and C backend.

Posted: Fri Feb 07, 2025 12:20 pm
by Armoured
idle wrote: Fri Feb 07, 2025 5:06 am I thought about this for awhile as it would be nice to still be able to use intel asm from the c backend
and while the demo isn't particularly useful it wouldn't be to hard to turn into a compiler tool so it generates a data section and loads it.
https://www.purebasic.fr/english/viewtopic.php?t=86226
That's really interesting—thank you!

Re: Question about inline assembler and C backend.

Posted: Fri Feb 07, 2025 7:10 pm
by idle
You can easily use asm insrinsics in c backend if you need atomics.

Re: Question about inline assembler and C backend.

Posted: Sat Feb 08, 2025 12:37 am
by Armoured
idle wrote: Fri Feb 07, 2025 7:10 pm You can easily use asm insrinsics in c backend if you need atomics.
How?

Re: Question about inline assembler and C backend.

Posted: Sat Feb 08, 2025 1:26 am
by idle
Armoured wrote: Sat Feb 08, 2025 12:37 am
idle wrote: Fri Feb 07, 2025 7:10 pm You can easily use asm insrinsics in c backend if you need atomics.
How?
what functions do you need?

Re: Question about inline assembler and C backend.

Posted: Sat Feb 08, 2025 9:44 am
by Armoured
idle wrote: Sat Feb 08, 2025 1:26 am
Armoured wrote: Sat Feb 08, 2025 12:37 am
idle wrote: Fri Feb 07, 2025 7:10 pm You can easily use asm insrinsics in c backend if you need atomics.
How?
what functions do you need?
I need a function like InterlockedIncrement.