In most modern circumstances (it wasn't always so easy to say this), the part of the ALU that performs addition and subtraction is fundamentally agnostic about signed and unsigned operations. It doesn't know about signed values and it doesn't care about signed values. The ALU simply performs an unsigned operation and that's all it does.
For subtraction, the subtrahend is simply inverted and the operation's carry-in, which in addition is set to 0, will be set to 1, instead. That's it. It's all just an ADD operation with some modifications done to one of the inputs and the carry-in, if you choose SUB instead of ADD. The exact same ADD operation takes place, either way.
It's brain-dead easy.
Because some operations need to be extended to multi-word, the ALU includes a copy of a bit you otherwise would not get -- the carry-out of the word operation. It saves this bit into the C status bit. This is a simple capture. All it does is snap a copy of the carry-out of the ALU ADD logic block. If you are doing unsigned operations, the C status bit tells you if you had an unsigned arithmetic overflow. (And need multi-word storage, likely.) But what it actually means is entirely up to you. The ALU simply doesn't care. It's just "being helpful" in case you care.
The Z status bit is 1 if the ALU operation result is zero and 0 otherwise. Usually, this is the case not only for ADD and SUB but also for many other logical operations -- check the manual to be sure as there is usually a giant mux and a designer may or may not use this detection for other operations.
The Z status bit is very important because of the very common need of decrementing some counter and detecting when it goes to zero, quickly branching out of a loop. There are other important uses (signed operations, included), but this is the primary reason. You very often want to know when an operation produces an exact zero result. So designers add the extra (cheap) logic to save you an instruction or two and hand the answer to you on a silver platter, instead.
The V status bit is there because it is also cheap to generate and you can use it, if you are working with signed interpretations. It signifies an arithmetic overflow and is calculated as the XOR of the carry out of the next-to-most significant bit and the carry bit itself. Again, the ALU doesn't really care about signed values and doesn't have any logic to observe them. It's just calculating a flag that is helpful for detecting signed arithmetic overflow. If it is set, and if you think you are working with signed values, then you had such an overflow. You don't care about the V status bit if you imagine you are doing unsigned operations.
So,
- If you believe you are using unsigned values then watch the C status flag to detect something requiring extra attention. You don't care about the V status flag.
- If you believe you are using signed values then watch the V status flag to detect something requiring extra attention. You don't care about the C status flag.
Since it's not important to think about this with wide words, we can drop back to 3-bit words to keep it simple. Here, there are only 8 symbols:
Unsigned Signed Subtrahend
000 0 0 111
001 1 1 110
010 2 2 101
011 3 3 100
100 4 -4 011
101 5 -3 010
110 6 -2 001
111 7 -1 000
Result Unsigned Signed
Operation Actual Operation V C ALU Interpretation Interpretation
ADD 011 + 001 = ADD 011 + 001 + 0 = 1 0 100 3 + 1 = 4 3 + 1 = 4 E
ADD 011 + 110 = ADD 011 + 110 + 0 = 0 1 001 3 + 6 = 9 E 3 + -2 = 1
SUB 011 - 001 = ADD 011 + 110 + 1 = 0 1 010 3 - 1 = 2 3 - 1 = 2
SUB 011 - 110 = ADD 011 + 001 + 1 = 1 0 101 3 - 6 = -3 E 3 - -2 = 5 E
From the above (E is an error) you can see how to interpret the bits. In unsigned addition, C=1 is an error (carry required.) In unsigned subtraction, C=0 is an error (failure to borrow.) In signed addition, V=1 is an error (signed carry required.) In signed subtraction, V=0 is an error (failure to signed-borrow.)
See also this discussion for a specific case of signed conditional branching.