From: Christopher Nelson <paradox@BBHC.ORG> - 2005-04-01 17:46:12
> >If you notice at
> > 8000e25d: f0 0f bc d2 lock bsf %edx,%edx
> > The instruction is generated using the same register as source and
> > destination. However,
> > asm volatile("lock; bsfl %1, %0"
> > : "=3Dr" (bit)
> > : "rm" (_libkernel_portmap) );
> Nothing about this asm statement prevents the same register being used
> for the source and destination.
> >Obviously the code is incorrect since the %edx register is not
> >sourced afterwards. (Meaning, on entry to that instruction %edx
> >contains the base address of the array, and afterwards its also
> >to contain that value. (Consider the lea on 8000e264).
> No, the %edx register is used correctly. The "lea" instruction is
> the "port =3D (index<<5) + (bit);" statement in your code. This
> adds %edx ("bit") to %eax ("index << 5") and stores the result in %ebx
> ("port"). After the "lea" instruction your code breaks from the loop
> and the value in %edx ("bit") is never used again.
> The bug is in your code. You want to use "_libkernel_portmap[index]"
> as the source operand in the asm statement quoted above.
Actually, that *was* part of the problem. The other part, though, was
that the "lock" prefix is apparently not useable with bsfl. Removing
the lock prefix and correcting the _libkernel_portmap to be
_libkernel_portmap[index] made the problem go away. Sorry, and thanks!