LAHF does not work ?

  • Follow


Hello
I have celeron 2.4Ghz.
Using linux gcc i launched main() which called fun6().

I wanted to write function which  returns me 0 if there is even number 
of 1 and 1 if odd. I wanted to use LAHF, parity flag. But as i see LAHF
does not change ax register! Whatever value (in line 21) will be put to 
ax, it will be returned unchanged by fun6 - lahf does not change ax. WHY ???

int fun6(int x){
     foo = x;
     asm("mov %ebx,%eax; \
          mov $0x22,%ax; \	//line 21
          lahf; \
          pop %ebp; \
          ret \
         ");
}

Thanx
Michal

0
Reply vertigo 5/11/2005 8:36:02 PM

vertigo  <spamtrap@crayne.org> wrote:
>
>I wanted to write function which  returns me 0 if there is even number 
>of 1 and 1 if odd. I wanted to use LAHF, parity flag. But as i see LAHF
>does not change ax register! Whatever value (in line 21) will be put to 
>ax, it will be returned unchanged by fun6 - lahf does not change ax. WHY ???

Because "mov" does not affect the flags.  Further, this function will
return a 16-bit value with the flags in AH and 22 in AL.  If you really
want just the parity flag in bit 0, you'll have to isolate it.

Try this:

>int fun6(int x){
>     foo = x;
>     asm("mov %ebx,%eax; \
>          mov $0x22,%ax; \	//line 21
           test %ax,%ax; \
>          lahf; \
	   shr $10, %eax; \
           and $1, %eax; \
>          pop %ebp; \
>          ret \
>         ");
>}
-- 
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.

0
Reply Tim 5/12/2005 5:48:23 AM


In article <d5toms$b28$1@nemesis.news.tpi.pl>
           spamtrap@crayne.org "vertigo " writes:

> Hello
> I have celeron 2.4Ghz.
> Using linux gcc i launched main() which called fun6().
> 
> I wanted to write function which  returns me 0 if there is even number 
> of 1 and 1 if odd. I wanted to use LAHF, parity flag. But as i see LAHF
> does not change ax register! Whatever value (in line 21) will be put to 
> ax, it will be returned unchanged by fun6 - lahf does not change ax. WHY ???
> 
> int fun6(int x){
>      foo = x;
>      asm("mov %ebx,%eax; \
>           mov $0x22,%ax; \      //line 21
>           lahf; \
>           pop %ebp; \
>           ret \
>          ");
> }

The clue is in the name: LAHF -> "Load AH from Flags".  Try 
something like this:

        or      ax, ax          ; set flags according to AX
        lahf                    ; copy low order bits to AH
        and     ah, 00000100b   ; mask parity flag
        shr     ax, 11          ; move to bit position zero

AX should now be either 0 or 1 (if I remember where the parity 
flag is!).  But this is using a sledgehammer to crack a nut -- 
simpler and quicker is:

int fun6(int x){
    return x & 1;
}

Pete
-- 
   "We have not inherited the earth from our ancestors,
    we have borrowed it from our descendants."

0
Reply spamtrap 5/12/2005 6:09:43 PM

<spamtrap@crayne.org> wrote in message news:1115874822snz@nospam.demon.co.uk...
> In article <d5toms$b28$1@nemesis.news.tpi.pl>
> > I wanted to write function which  returns me 0 if there is even number
> > of 1 and 1 if odd. I wanted to use LAHF, parity flag. But as i see LAHF
> > does not change ax register! Whatever value (in line 21) will be put to
> > ax, it will be returned unchanged by fun6 - lahf does not change ax. WHY ???
> >
> > int fun6(int x){
> >      foo = x;
> >      asm("mov %ebx,%eax; \
> >           mov $0x22,%ax; \      //line 21
> >           lahf; \
> >           pop %ebp; \
> >           ret \
> >          ");
> > }
>
> The clue is in the name: LAHF -> "Load AH from Flags".  Try
> something like this:
>
>         or      ax, ax          ; set flags according to AX
>         lahf                    ; copy low order bits to AH
>         and     ah, 00000100b   ; mask parity flag
>         shr     ax, 11          ; move to bit position zero

Yep, except that the description of the desired return value calls for 0 for an
even number of ones and 1 for an odd number.

According to Intel*:

    PF (bit 2) Parity flag - Set if the least-significant byte of the result
contains
    an even number of 1 bits; cleared otherwise.

So, we need an:

    xor   ax, 1  ; Toggle Party to comply with specified return value

Also, perhaps this is what was desired, but as noted above, the Parity Flag only
reflects the low-order byte of the result, but I see that the function is using
a 16 bit integer as it's argument.  If it's desired to determine an even numbers
of one bits in the 16 bit argument, we're only half way there with this code.

> AX should now be either 0 or 1 (if I remember where the
> parity flag is!).

You do.

> But this is using a sledgehammer to crack a nut -- 
> simpler and quicker is:
>
> int fun6(int x){
>     return x & 1;
> }

That's the odd or even state of the overall integer, that is, the state of the
least significant bit, not a test of whether it's got an odd or even number of
ones in it.

    - Bill
________
* IA-32 Intel� Architecture Software Developer's Manual, Volume 1: Basic
Architecture


0
Reply Bill 5/13/2005 3:57:55 AM

3 Replies
265 Views

(page loaded in 0.011 seconds)

Similiar Articles:













7/10/2012 12:13:22 PM


Reply: