views:

340

answers:

4

suppose we use the addl instruction to perform the equivalent of the C expression "t=a+b",where a,b,t are variables of type int,then the conditional code will be set according to the following C expression:

CF: (unsigned t) < (unsigned a) Unsigned Overflow

ZF: (t==0) Zero

SF: (t<0) Negative

OF: (a<0 == b<0) && (t<0 != a<0) Signed Overflow

Quted from a computer system textbook.

  • CF is the carry flag.
  • ZF is the zero flag.
  • SF is the sign flag.
  • OF is the overflow flag.

i can't figure out why these C expressions have the effect mentioned above.for example,why the expression (t<0) will set the SF flag?? t<0 is either true,or false(since the textbook only told the type of these variables),but why the sign flag has been set?I'm really confused,please help..thanks!

A: 

It's still not a clear question but here is what I gleaned. I think you want to know "Why is the Sign Flag (SF) set when all I'm doing is t=a+b?" I'll answer that.

The simple answer is that the 'int' C type is signed, you have to say 'unsigned int' to get the unsigned version. Therefore, in the situation t=a+b, those variables are all signed. Now for why the flag could be set:

let a = 5, b = -10
t = a+b
t = 5 - 10
t = -5 (SF will be set because of the negative)

let a = 5, b = 10
t = a+b
t = 5 + 10
t = 15 (SF will not be set because of the positive)

If you want to know more about signs on numbers as they appear in C then I would suggest that you look at Ones Complement and Twos Complement.

I hope that answers the question.

Robert Massaioli
+1  A: 

The CPU sets those flags after carrying out arithmetic operations. What you call "C expressions" are really a description of the conditions under which the various CPU flags are set. For example, if the result is 0, the zero flag will be set.

Or to address you specific question, the following:

SF: (t<0) Negative

means that if the result of an arithmetic operation is negative, the CPU sets the SF flag. The 't<0' is not a C expression - it just explains when the flag is set.

The flags can be used later for control flow, using instructions that branch conditionally on the value of the flags.

Ori Pessach
got it..thanks!: )
yfel
A: 

It is the other way round. When you write t < 0 in C, this is compiled to a branch which is conditional on the S flag (also often called N for Negative). In the processor the S flag is just copied from the highest bit of the result.

starblue
+1  A: 

CF, ZF, SF, and OF are singular bits within the CC (condition code) register. There are also other bits which are set under other conditions. Whenever the CPU executes certain instructions (including add and sub), it sets those bits according to the result of the operation. The instructions cmp and test function identically to the sub and and instructions respectively, except they completely discard the result, and the only output is the condition flags.

Suppose we have the following C code:

int a, b;
...
a -= b;
if(a < 0)
{
    // stuff...
}

A naïve compiler might compile this as so:

    ; Suppose a is in the eax register and b is in the edx register
    sub %eax, %edx  ; subtract b from a, store result in a
    cmp $0, %eax    ; compare a to 0
    jl end_of_stuff ; if a < 0, goto end_of_stuff
    ; code for stuff goes here
end_of_stuff:
    ; code after if block goes here

A smarter compiler, though, would realize that the sub instruction already sets the condition codes, so it could compile it like this:

    sub %eax, %edx
    jl end_of_stuff   ; if a < 0, goto end_of_stuff
    ; code for stuff goes here
end_of_stuff:
    ; code after if block goes here

Note that the jl instruction (jump if less than) takes the jump if and only if SF ≠ OF. That is, it jumps if the result is negative and overflow did not occur, or if the result is positive and overflow did occur. This is necessary to ensure that the correct result is obtained when the difference overflows (e.g. comparing INT_MIN with INT_MAX).

Adam Rosenfield