www.digitalmars.com         C & C++   DMDScript  

D - inline assembler bug

reply "Jeroen van Bemmel" <anonymous somewhere.com> writes:
The function below is not compiled correctly: without the line after 'L1:'
the result value is not put in EAX, with it it gets set twice

int memcmp(void* src, void* dst, uint count) {
   asm {
      mov   ECX, count        ;  /* ECX = count */
      mov   EDI, dst          ;
      mov   ESI, src          ;

      repe              ;
      cmpsb             ;  /* for now, byte wise */
      jz L1             ;  /* if z, compare was ok -> ECX == 0 */
      sub   count, ECX  ;  /* convert to index of failing byte */
L1:   mov   EAX, count  ;  /* without this, eax is not set. With this, it's
set twice! */
   }
   return count;
}
Jan 25 2003
parent "Walter" <walter digitalmars.com> writes:
Strange as it seems, this is not a bug. In D, the last argument is passed in
EAX, in this case, 'count' is passed to memcmp() in EAX. Since EAX is not
modified in the function, EAX is the same as 'count' upon return, and so is
not reloaded.

When the line assigning 'count' to EAX is added, the code generator marks
EAX as modified, and so 'count' gets reloaded into EAX by the 'return
count;' statement.

Granted, the inline assembler could be smarter about just how EAX is
modified and avoid the redundant load, but the correct result still happens.
Also, I know of no other inline assembler that even keeps track of which
registers are modified (what they do is just stupidly assume all registers
are modified, which results in lousy prolog/epilog code, or they (i.e. gcc)
require the programmer to note which ones are modified, which is very error
prone).

The solution to this particular code is to leave off the EAX load at the
end, and let the compiler take care of it with the 'return count;'
statement.

"Jeroen van Bemmel" <anonymous somewhere.com> wrote in message
news:b0v1jj$2rpa$1 digitaldaemon.com...
 The function below is not compiled correctly: without the line after 'L1:'
 the result value is not put in EAX, with it it gets set twice

 int memcmp(void* src, void* dst, uint count) {
    asm {
       mov   ECX, count        ;  /* ECX = count */
       mov   EDI, dst          ;
       mov   ESI, src          ;

       repe              ;
       cmpsb             ;  /* for now, byte wise */
       jz L1             ;  /* if z, compare was ok -> ECX == 0 */
       sub   count, ECX  ;  /* convert to index of failing byte */
 L1:   mov   EAX, count  ;  /* without this, eax is not set. With this,

 set twice! */
    }
    return count;
 }

Feb 04 2003