A = 54 = 00110110 ; B = -77 = 10110111
well actually -77 is 10110011
so
a - -b = a + b
set it up
0
00110110
+01001101
=========
and fill it in
011111000
00110110
+01001101
=========
10000011
The carry in and carry out of the msbit do not match. Also the msbits of the operands match and the msbit of the result does not. Both indicate signed overflow. The carry out of the msbit being a zero means no unsigned overflow (if this is treated as an addition, which it is not).
more correctly though it is a subtraction
a - b = a + (-b) and -b = ~b + 1
so what you really see in logic is the b operand and the carry in inverted.
1
00110110
+01001100
==========
and that gives the same result of course, but it is a subtract operation not an add operation.
You can certainly do subtraction in binary as easily as you can do it in base 10 from grade school.
00110110
-10110011
==========
Unlike grade school we would put the larger number on top then negate the result, but here we borrow from off the end if needed...
1 0
00110110
-10110011
==========
borrow
1 2
00110100
-10110011
==========
1
another borrow
1 22
00110000
-10110011
==========
0000011
another borrow
02 22
00110000
-10110011
==========
10000011
what is the extra bit here and is the carry out when using an adder, is the not borrow. When a borrow does not happen the carry out is a 1, when a borrow happens the carry out is a 0. Some architectures invert the carry out on subtract and make it a borrow bit. Some do not invert it and you have to know that a not carry is a borrow.
The beauty of twos-complement is that addition and subtraction have no notion of unsigned vs signed. So from a logic perspective bits is bits 54 - (-77) is also the same as 54 - 179 which definitely has a borrow to it. It is the user that considers the bit pattern to either be -77 or +179. Division and multiplication can care, depends on if you need to pad or not and you sign extend the padding for signed rather than zero extend for unsigned. If the operands are the right size then both a signed and unsigned multiply can be used to perform either or. But a significant percentage of the operands overflow. A proper multiply (result is 2 times the number of bits as the operand) is sensitive to sign.
54 - -77 = 131 is greater than 127 so from a signed operation perspective this result cannot fit in 8 bits. So it is a signed overflow.
54 + 205 as an example is 259 which is greater than 256 so that would be an unsigned overflow (the carry bit would be set for an add operation). but that is also -51, 54 - 51 = 3 which does not borrow, so both views work here too. 54 + 205 = 0x103 which means 0x03 with the carry out being a one.
If you work it out
msbits of the operands and the carry in of the msbit all added together
a msbit of operand a, b msbit of operand b, i carry in of the msbit, c carry out of the msbit, r result of the msbit. i != c is a signed overflow
ab i cr
00 0 = 00
00 1 = 01 signed overflow
01 0 = 01
01 1 = 10
10 0 = 01
10 1 = 10
11 0 = 10 signed overflow
11 1 = 11
so you can use the definition if the carry in and carry out of the msbit do not match it is a signed overflow.
00 1 = 01 signed overflow
^ ^
11 0 = 10 signed overflow
^ ^
Or you can use the definition of if the msbits of the operands match and the result does not match it is a signed overflow
00 1 = 01 signed overflow
^^ ^
11 0 = 10 signed overflow
^^ ^
00 0 = 00 not a signed overflow
^^ ^
11 1 = 11 not a signed overflow
^^ ^
If the msbits of the operands do not match then you cannot have a signed overflow. Do the entire combination of 3 or 4 bit operands with a program or by hand, examine them from a signed perspective and you can see that this is a true statement, you do not have to believe me.
Some folks remember it by the msbit method (which you can evaluate without having to compute the carry in and carry out), and some folks remember carry in and carry out matching or not. And as a result you will see logic operands compute it one way or the other depending on the author.
Some architectures documentation are misleading/confusing talking about a carry bit and an overflow bit without grinding in every use of the term that overflow really is the signed overflow bit. None of them go so far as to call the carry bit the unsigned overflow/signed borrow/carry bit every time they mention it...And some might even go so far as to use the overflow bit for multiplication as well as addition, so all of this just adds to the confusion.
One of the best exercises is to write a small program (only takes like 20 - 30 lines of code) feed it all the combinations of 4 bit operands 0x0 to 0xF for each 16*16 operations. Because these flags are used with a compare most of the time which is a subtract then do the subtraction (invert and such and use an adder). And compute all the flags, CNVZ. With that table you can see why the C flag alone can be used as a greater than or less than, N==V, N!=V and so on. Z or C set is the same as C not set so if you flip operands you can reduce the number of instructions the inverse of greater than is less than or equal. Invert the operands and you do not need to use the z flag you can simply jc or jnc. But this exercise also shows signed greater than vs unsigned and so on. Plus obviously signed and unsigned overflow.