asm woes...

Marco Leise via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue May 31 11:52:16 PDT 2016


Am Fri, 27 May 2016 10:16:48 +0000
schrieb Era Scarecrow <rtcvb32 at yahoo.com>:

> On Friday, 27 May 2016 at 10:14:31 UTC, Era Scarecrow wrote:
> >   inc dword ptr [EAX+Foo.x.offsetof];  
> 
> 
>   So just tested it, and it didn't hang, meaning all unittests 
> also passed.
> 
>   Final solution is:
> 
>    asm pure @nogc nothrow {
>      mov EAX, this;
>      add dword ptr [EAX+wideIntImpl.lo.offsetof], 1;
>      adc dword ptr [EAX+wideIntImpl.lo.offsetof+4], 0;
>      adc dword ptr [EAX+wideIntImpl.hi.offsetof], 0;
>      adc dword ptr [EAX+wideIntImpl.hi.offsetof+4], 0;
>    }

The 'this' pointer is usually in some register already. On
Linux 32-bit for example it is in EAX, on Linux 64-bit is in
RDI. What DMD does when it encounters an asm block is, it
stores every parameter (including the implicit this) on the
stack and when you do "mov EAX, this;" it loads it back from
there using EBP as the base pointer to the stack variables. The
boilerplate will look like this on 32-bit Linux:

   push   EBP                     // Save what's currently in EBP
   mov    EBP,ESP                 // Remember current stack pointer as base for variables
   push   EAX                     // Save implicit 'this' parameter on the stack
   mov    EAX,DWORD PTR [EBP-0x4] // Load 'this' into EAX as you requested
   <add and adc code here>
   mov    ESP,EBP     // Restore stack to what it was before saving parameters and variables
   pop    EBP         // Restore EBP register
   ret                // Return from function

Remember that this works only for x86 32-bit in DMD and LDC.
GDC passes inline asm right through to an arbitrary external
assembler after doing some template replacements. It will not
understand any of the asm you feed it, but forward the
external assemblers error messages.

On the other hand GDC's and LDC's extended assemblers free you
from manually loading stuff into registers. You just use a
placeholder and tell the compiler to put 'this' into some
register. The compiler will realize it is already in EAX or
RDI and do nothing but use that register instead of EAX in
your code above. Sometimes that has the additional benefit that
the same asm code works on both 32-bit and 64-bit.
Also, extended asm is transparent to the optimizer. The code
can be inlined and already loaded variables reused.

By the way, you are right that 32-bit does not have access to
64-bit machine words (actually kind of obvious), but your idea
wasn't far fetched, since there is the X32 architecture at
least for Linux. It uses 64-bit machine words, but 32-bit
pointers and allows for compact and fast programs.

-- 
Marco



More information about the Digitalmars-d-learn mailing list