SBB subtracts the source and then the carry flag from the destination: the result is destination − source − CF. After a subtraction, CF holds the borrow, so SBB lets a borrow from the lower word reach the next word up. Operand forms and flag effects are the same as for SUB.
Multi-word subtraction
Subtract the low words with SUB, then the high words with SBB. Here 00020000h − 1 = 0001FFFFh: the low word underflows to FFFFh and borrows, and SBB takes that 1 from the high word.
MOV AX, [BIG] ; low word: 0000hMOV DX, [BIG+2] ; high word: 0002hSUB AX, 1 ; AX = FFFFh, CF = 1 (borrow)SBB DX, 0 ; DX = 0002h - 0 - 1 = 0001hMOV AL, DL ; prints 1ADD AL, '0' ; digit -> characterMOV DL, ALMOV AH, 02h ; DOS: print DLINT 21hBIG DW 0000h, 0002h ; 00020000h, low word first
For longer numbers continue with SBB for every further word. As with ADC, nothing between the steps may change CF; MOV, LEA, INC and DEC are safe.
Comparing 32-bit numbers
To compare DX:AX with CX:BX as unsigned numbers without destroying them, subtract on copies: after SUB of the low words and SBB of the high words, CF = 1 exactly when DX:AX was the smaller value, so JB can test it.
A mask from the carry
SBB AX, AX computes AX − AX − CF, which is 0 when CF was 0 and FFFFh (−1) when CF was 1. That turns the carry into an all-zeros or all-ones mask without a jump.
CMP AX, BX ; CF = 1 if AX < BX (unsigned)SBB CX, CX ; CX = FFFFh if AX < BX, else 0
Pitfall
If a loop subtracts every word with SBB, clear CF with CLC before the first pass so an old borrow is not subtracted.