Mail Archives: djgpp/1994/10/12/17:28:47
Okay, Peter Jones and I have both independantly found the bug.
FixRotate() uses FixMul which is a #defined inline assembler thing. The
assembler destroys registers %edx, %eax and the condition code which I
clearly marked in the declaration of FixMul as being ruined. The
compiler, however, makes the silly mistake of running one FixMul, then
storing the result in %edx right before it does FixMul again! so the
temporary result is wiped out by the second FixMul. It looks like this:
/APP
imul %ecx; shrdl $16,%edx,%eax
/NO_APP
movl %eax,%edx
movl %edi,%eax
/APP
imul %esi; shrdl $16,%edx,%eax
/NO_APP
Now, if you push %edx and then pop it later in order to preserve it,
everything works fine. Here's the declaration of FixMul for you again:
#define FixMul(x, y) \
({ fixed result; \
asm("imul %1; shrdl $16,%%edx,%%eax" : \
"=a" (result) : "r" (x), "a" (y) : \
"%%eax", "%%edx", "cc"); \
result;})
This bug only turns up when FixRotate() is declared inline and the
while loop doesn't have a getch() in it. *grump*
Kim
- Raw text -