extended asm and register clobbers

dw limegreensocks@yahoo.com
Sat Mar 30 21:04:00 GMT 2013


I read this line from the docs:

"If you refer to a particular hardware register from the assembler code, 
you probably have to list the register after the third colon to tell the 
compiler the register's value is modified."

My own observation shows that this is true.  However, attempting to add 
the register in question to the clobber list is returning a compile error.

The asm (essentially memset):

     __CRT_INLINE VOID __stosb(PBYTE Dest, BYTE Data, SIZE_T Count)
     {
       __asm__
       (
         "cld; rep; stosb"
         :
         : "D" (Dest), "a" (Data), "c" (Count)
         : "edi", "memory", "cc"
       );
     }

The error:

error: can't find a register in class 'DIREG' while reloading 'asm'
error: 'asm' operand has impossible constraints

Without the edi clobber, this c++ code:

    __stosb((PBYTE)&c, 0, sizeof(c));
    __stosb((PBYTE)&c, 0, sizeof(c));

generates this asm:

   402cd3:    cld
   402cd4:    rep stos BYTE PTR es:[rdi],al
   402cd6:    cld
   402cd7:    rep stos BYTE PTR es:[rdi],al

Since rdi is not clobbered, gcc doesn't reload it between calls 
(likewise with rcx).

While I might be able to fake the compiler out by specifying outputs 
(probably need the volatile qualifier too), I don't really want to 
change Dest, I just want to use it as an input.

What's the right way to go here?

dw



More information about the Gcc-help mailing list