In assembler, you only discern between signed values and unsigned values when you make decisions (i.e. conditional jumps). The ALU operates the same way for signed integers and unsigned integers. Some ALU flags, like OF
(overflow) make sense if operands and result are interpreted as signed numbers. Others, like CF
(carry) make sense if they are interpreted as unsigned numbers. Finally, others like ZF
(zero) can be used with both interpretations.
For example: let's say you are using 8-bit registers (just for the sake of simplicity) and you come up with this code:
mov $0xff,%al
mov $0x01,%bl
add %bl,%al
This sequence can be interpreted two ways (remember that both operands and result are 8 bits wide):
- Add -1 + 1, with result 0
- Add 255 + 1, with result 0
How you interpret this depends on the decisions you make upon the result of this operation. Imagine that you want to check whether this operation worked ok, and there wasn't any kind of overrun with the result.
If you consider that your values are unsigned, then you added 255
plus 1
, resulting in a number (256
) which cannot be store in 8 bits, hence there is overrun and the actual result is not what you expected (0
). You have to look at the carry flag to check for this:
jc .operation_overrun
This particular example will make this jump to be taken, because there was an overrun condition.
But if you consider that your values are signed, then you added -1
plus 1
, which equals 0
. To check for overruns here, you have to look at the overflow flag:
jo .operation_overrun
This particular example will make this jump to not to be taken, because there wasn't an overrun.
Another example: imagine that you compare two numbers held in two 32-bit registers, %eax
and %ebx
. You want to jump to another place if the number in %eax
is greater than the number in %ebx
. How do you do this? You must decide how you will interpret your numbers, because if you may come up with, for example, EAX=0xFFFFFFFF
and EBX=0x00000001
...
;...If both numbers are considered to be unsigned...
cmp %ebx,%eax ;compare EAX with EBX
ja .another_place ; ...this will jump because EAX=4294967295,
; which way much greater than EBX=1
;...But if both numbers are considered to be signed...
cmp %ebx,%eax ;compare EAX with EBX
jg .another_place ; ...this will NOT jump because EAX=-1,
; which is not greater than EBX=1
Once again, the operation (comparison, actually a substraction) is the same in these two cases, but the decision we make (the flags we look at when we perform a conditional jump) is different for each case. The first jump, ja
, looked at the value of the carry flag (CF
) and zero flag (ZF
). The second jump, jg
looked at the value of the sign flag (SF
) and the overflow flag (OF
).
For a detailed list of which flags are used for each particular conditional jump, see http://www.unixwiz.net/techtips/x86-jumps.html