January 25, 2003 inline assembler bug | ||||
---|---|---|---|---|
| ||||
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; } |
February 04, 2003 Re: inline assembler bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeroen van Bemmel | 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, it's > set twice! */ > } > return count; > } > > |
Copyright © 1999-2021 by the D Language Foundation