I want a more 'powerful' (meaning I want to reduce my CMP tests) way of testing values.

I was doing some testing with the CMP instruction. Immediately after doing the test I used the LAHF instruction to write the FLAGS into the AH register. I then noticed some interesting things....

Usually when people want to determine, 'do the 2 equal each other or not' and 'is one of the values a zero', they will do 2 tests. I want a way of doing 3 things in 1 test, with 2 jumps and 1 'fall through' if the 2 tests failed. For example:

I have 2 values I want to test. Val1 and Val2 ... here are the FLAGS after the CMP. Also I listed the 'common' flags set.

Val1 = 0
Val2 = 123
Flags = 1001 0011
CARRY? = 1
SIGN? = 1

Val1 = 123
Val2 = 0
Flags = 0000 0110

Val1 = 123
Val2 = 123
Flags = 0100 0110
ZERO = 1

Val1 = 12
Val2 = 123
Flags = 1000 0011
CARRY? = 1
SIGN? = 1

ecx = 123
uMsg = 12
Flags = 0001 0110

For reference:
Flags === Sign | Zero | xx | Aux | xx | Parity | xx | Carry

Now, my question is this, the Aux (Auxiliary Flag) seems to be used at a few critical/crutial moments in the CMP instruction. I could deffinately use it! But I haven't found a JMP instruction that tests it! So unless I write the flags to AH, how will I determine if the Flag is set? As you can see, just about everything can be determined by the 1 cmp instruction! Also, there are times when an 'unnamed' flag is used (6th Flag)! Why? When?

Am I missing anything here? I just want to test 2 unsigned DWORDS! As is often done!

Most importantly for me is ... how do I test the Aux flag???

Posted on 2004-07-01 04:41:24 by SubEvil
Look at the Jcc section of the manual. It states which flag conditions result in a jump. Obviously, the condition must be based on two or more flags - one should be the carry flag to provide you with the most instruction options. See: JNA, JNBE, JNLE, JNG.

I've used:

jmp @F ; ...

jnc _x
; {process last bit}

bt [esi], ecx ; set CF
dec ecx ; set ZF (don't effect CF)
jnbe @B ; ^ if CF=0 and ZF=0
je exit
; {do something when the bit is set}
jmp @B
...cool stuff, huh? :)

The AUX flag was not designed for Jcc use.
Posted on 2004-07-01 08:32:24 by bitRAKE
Hi Bitrake,

I think you underestimate the limitations of the Jump instructions without the ability to test the AF. There are NO jump instructions that test the Auxiliary Flag! This Flag is pivotal in gaining more insight into the tested values (especially with cmp)! Others have coded MACRO's to test this Flag. Let me give you an example.

Say for example you had something like this:

cmp uMsg, WM_COMMAND

Under normal cirumstances, with the Intel Jump instructions, there are only 2 things you can 'test'/jump to. Is it or is it not equal? You cannot, test at the same time if uMsg is NULL (But you can with the AF)

So, if they are equal, fine, go somewhere ...

HOWEVER, if they are not equal, you cannot test (with any jump) if the uMsg value is a Zero? ... without the Auxiliary Flag. Look at the examples above. This is difficult to explain for me!

Take these 2:

Val1 = 0 AKA uMsg
Val2 = 123 AKA WM_COMMAND (hypothetical)
Flags = 1001 0011
CARRY? = 1
SIGN? = 1

Val1 = 12 AKA uMsg
Val2 = 123 AKA WM_COMMAND (hypothetical)
Flags = 1000 0011
CARRY? = 1
SIGN? = 1

These are the Flag settings after a CMP Val1, Val2. As you can see, only the CF and SF can be tested. However, interesting to note, is the top one has the AF set, because it's ZERO! But with normal Jump instructions, we cannot check this! Because we cannot test the AF. Usually people perform another test, like test eax, eax. What I'm saying is that you can determine all 3 states, (is equal, is not equal, is zero) in 1 cmp by checking the AF.

Anyway, all this doesn't matter because it's computationally expensive to check AF anyway, because Intel doesn't give us a jump instruction that tests AF :(
Posted on 2004-07-01 08:58:40 by SubEvil
mov eax, 0
cmp val1, val2
shr eax, 8-2

Not very useful, but it gets the job done. :(

The Svin, had something to say on this topic. Maybe, review his posts. For me, I just reformulate the problem to match the instructions, but I certainly have things left to learn.
Posted on 2004-07-01 09:48:00 by bitRAKE
The Auxiliary Flag has nothing to do with a value of 0 in any of the two numbers being compared.

Remember than a comparison simulates a subtraction without changing the values of the two numbers.

Also remember that the AF will be affected whenever bit4 of the destination (in this case the number listed first for a comparison) would be modified by the operation.

Try repeating your comparisons with small values such as 1,2,3,... instead of 0 and watch what happens.

Posted on 2004-07-01 11:10:40 by Raymond
Exactly, Aux is not found because it is almost never required to be used. As Ramond was indicating, the AUX bit is a "Half-Carry" bit. Just like how the carry bit is set, when a number exceeds 8 bits, the AUX half carry bit is set when a number exceeds 4 bits. (hence the half carry since its half of 8 bits..).

I believe it was origionally provided for BCD (Binary coded decimal) stuff in the old x86 days... I have yet to see any real use for it to date.....

Posted on 2004-07-01 13:43:42 by NaN
aww man the Aux Flag, this flag gave me a headache while emulating the BCD instructions in my Z80 CPU emulator. I do use the aux flag in my Z80 CPU emulator but I have to do the:

test ah,10h

Though in other code, barely use it, heck I stay far away from the BCD instructions, it seems the AMD64 architecture has ditched some of them, the CPU will invoke the invalid opcode handler if it comes across the BCD instructions( in 64-bit mode of coursE).
Posted on 2004-07-01 20:32:22 by x86asm