www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/10/12/17:28:47

Date: Wed, 12 Oct 1994 11:38:44 -0400 (EDT)
From: Kimberley Burchett <OKRA AT max DOT tiac DOT net>
Sender: Kimberley Burchett <OKRA AT max DOT tiac DOT net>
Reply-To: Kimberley Burchett <OKRA AT max DOT tiac DOT net>
Subject: keyboard messups solved kindof
To: DJGPP Mailing List <djgpp AT sun DOT soe DOT clarkson DOT edu>

  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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019