Question

Here is some C, found in a textbook I'm learning:

...
do {
    ...
    n--;
} while (n > 0)
...

I assume n is at %edx.

The assembly code produced is:

testl %edx, %edx 
jle .L5

I understand that jle tests for less than or equal to (SF ^ OF) | ZF. However I am unsure how this instruction corresponds to n > 0. Can anyone explain this?

Was it helpful?

Solution

Some of this has been covered, but I'll fill in a little more detail.

The general purpose of the test reg,mask instruction tests a register value against a mask (register value is internally ANDed with mask) and then sets the status flags SF, ZF, and PF according to the result. [EDIT per comment from @ChrisDodd] It also unconditionally clears the O (overflow) and C (carry) status bits.[/EDIT]

SF = sign flag (1 if sign bit is set (a 2's complement negative value))
ZF = zero flag (1 if result is 0)
PF = parity flag (1 if result has an even number of 1 bits)

In this specific example (test eax,eax), the instruction is taking eax AND eax. When this is done, the bits will be:

SF = 1 if EAX has a negative value (since sign bit will not change when ANDed with itself)
ZF = 1 if EAX is zero (the only value that yields a zero when ANDed with itself is zero)
PF = 1 if EAX has an even number of 1 bits

In other words, it's a simple test for zero or negative. It's a very common pattern in compiler code generation.

OTHER TIPS

TEST "sets the SF, ZF, and PF status flags according to the result." (Intel manual, about TEST).

So SF will reflect whether n was negative, and ZF will reflect whether n was zero.

It sets OF to zero.

So (SF ^ OF)|ZF simplifies to SF | ZF, so in conclusion, the jump will be taken if n <= 0. That seems the wrong way around, so hopefully .L5 is the label after the loop, not the label in front of the loop.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top