Assembly

How to use assembly with Island? I saw there is a way to do it with attribute but how?
https://docs.elementscompiler.com/Concepts/Aspects/SpecialAttributesIsland/

We donā€™t officially support asm, (Because I want to be able to improve the syntax of it), however, it does work:

Inline in a function:

  InternalCalls.VoidAsm(
    "
    movl +4(%esp), %ecx
    movl %ebx, (%ecx)
    movl %ebp, +4(%ecx)
    movl %edi, +8(%ecx)
    movl %esi, +12(%ecx)
    movl %esp, +16(%ecx)
    xor %eax,%eax", "", false, false);

A pure asm function:

[InlineAsm("
pushl %ebp
movl 8(%esp),%eax
movl 12(%esp), %ebp
calll *%eax
popl %ebp
retl
", "", false, false), DisableInlining, DisableOptimizations]
method CallCatch(aCall: NativeInt; aEBP: NativeInt): NativeInt; external;
1 Like

Oh so the future syntax will be something like this?

method CallCatch(aCall: NativeInt; aEBP: NativeInt): NativeInt;
ASM ("PUSHL ā€¦ ");
end;

Iā€™m not sure what the syntax will be yet. Hence my comment.

1 Like

Hi me again, your (least?) favourite syntax hawkā€¦ :slight_smile:

I can understand the difficulty of the legacy asm syntax, but why not simply combine two existing keywords. After all, although such code is often called assembler, strictly speaking the assembler is the thing that processes the assembly language.

And quite conveniently, assembly is already a reserved word, so could we not:

method MyClass.PureAsmMethod;
begin assembly
  pushl %ebp
  // etc ...
end;


method MyClass.HybridMethod;
begin
   var s := GoodOldOxygeneStuff;

   begin assembly
      pushl %ebp
      // etc ...
   end;

   s.MoreLovelyOxygene;
end;

Feels much more Oxygene/Pascally (to me, obviously) than attributes or function wrappers around strings. :slight_smile:

But again, I say this as someone who only ever used the inline assember (in Delphi) to create efficient conditional break points, vis:

if SomeCondition then asm int 3 end;

:slight_smile:

Hopefully mixing asm and code works with x64. Because it doesnā€™t in Delphi x64! :slight_smile:

Right. Iā€™m not opposed to any of these, just havent gotten around to making this into a proper syntax yet. Atm the voidasm call is a 1:1 translation to the clang syntax, which is rather painful. That said, it does work already. We use it in islandrtl for quite a few things

1 Like

fwiw, i too like assembly pushl %ebp end;. we can even reuse the keyword :wink:

1 Like

What is the problem with the ā€˜oldā€™ ASM syntax excactly?

@jeroen Any ā€œproblemsā€ with the old asm syntax were entirely speculation on my part, based simply on the fact that asm is not a reserved word in Oxygene so there is perhaps a concern that adopting it as such now might break old code ?

There may be further/other wrinkles generally that Iā€™m not aware of - as I said, Iā€™m not exactly a heavy user of inline assembly - so there may well be complications in the syntax that I donā€™t appreciate. :slight_smile:

@mh - If the use of just plain assembly were unambiguous in a context where it can only mean inline assembly (as opposed to a .net assembly etc) then a begin pre-amble would indeed be redundant and could be dispensed with in the syntax. Even cleaner. :slight_smile:

Both syntaxes are fine actually. Hopefully we can mix assembly with code in x64. I think only GCC can do that in C++.

As i understand it, the problem is not the syntax per se, but that LLVM allows more flexibility (such as passing local vas in and out of there assembly) that we need to figure to how to expose.

the example Carlo gave me was

static inline uint32_t farpeekl(uint16_t sel, void* off)
{
   uint32_t ret;
   asm ( "push %%fs\n\t"
         "mov  %1, %%fs\n\t"
         "mov  %%fs:(%2), %0\n\t"
         "pop  %%fs"
         : "=r"(ret) : "g"(sel), "r"(off) );
   return ret;
}
1 Like