If you disregard the size of the type, then
1111 + 0001 = 10000
That is why you get a carry (simply to indicate that the result is larger than the stored 0). This is important if you must add additional (hex) "digits".
With subtraction, you can get a similar problem:
0000 - 0001 = 1111
That actually says: 0 - 1 = 15. That is not true, so the carry is set to indicate that a borrow was performed, i.e. that, more or less, the following is performed:
10000 - 0001 = 1111 (16 - 1 = 15)
You do the same when you subtract in decimal:
34
18
---- -
To subtract 8 from 4, you must borrow 1 from the next digit, to get 14 − 8 = 6. That borrow is needed to get the subtraction of the next pair of higher digits right. 3 − 1 = 2, but you must subtract the borrow too, so now 3 − 1 − borrow = 1. That is why you (correctly) get 16 and not 26 as a result.
34
18
---- -
16
The binary borrow has the same function: it is stored in the carry flag and can be subtracted (e.g. in x86 assembler), using SBB
(subtract with borrow) instead of a plain SUB
(subtract). The value of the carry flag (which is functioning as a "borrow flag" now) is additionally subtracted from the two operands:
Value1 DW 0x1234 ; alternatively: DB 0x34,0x12
Value2 DW 0x0678 ; DB 0x78,0x06
Result DW 0
MOV AL,BYTE PTR [Value1] ; 0011 0100
SUB AL,BYTE PTR [Value2] ; 0111 1000
MOV BYTE PTR [Result],AL ; 0xBC = 1011 1100, but a borrow was needed!
MOV AL,BYTE PTR [Value1 + 1] ; 0001 0010
SBB AL,BYTE PTR [Value2 + 1] ; 0000 0110 (0x12 - 0x06 - carry = 0x0B)
MOV BYTE PTR [Result + 1],AL ; 0x0B = 0000 1011