Carry flag
In computer processors, the carry flag (usually indicated as the C flag) is a single bit in a system status register/flag register used to indicate when an arithmetic carry or borrow has been generated out of the most significant arithmetic logic unit (ALU) bit position. The carry flag enables numbers larger than a single ALU width to be added/subtracted by carrying (adding) a binary digit from a partial addition/subtraction to the least significant bit position of a more significant word. This is typically programmed by the user of the processor on the assembly or machine code level, but can also happen internally in certain processors, via digital logic or microcode, where some processors have wider registers and arithmetic instructions than (combinatorial, or "physical") ALU.[1] It is also used to extend bit shifts and rotates in a similar manner on many processors (sometimes done via a dedicated flag). For subtractive operations, two (opposite) conventions are employed as most machines set the carry flag on borrow while some machines (such as the 6502 and the PIC) instead reset the carry flag on borrow (and vice versa).
Uses
[edit]The carry flag is affected by the result of most arithmetic (and typically several bitwise) instructions and is also used as an input to many of them. Several of these instructions have two forms which either read or ignore the carry. In assembly languages these instructions are represented by mnemonics such as ADD/SUB, ADC/SBC (ADD/SUB including carry), SHL/SHR (bit shifts), ROL/ROR (bit rotates), RCR/RCL (rotate through carry), and so on.[2] The use of the carry flag in this manner enables multi-word add, subtract, shift, and rotate operations.
Consider adding 255 + 255 (11111111 + 11111111). The result should be 510, which is the 9-bit value 111111110 in binary. However, if using an 8-bit register, only the 8 least significant bits will be stored in the register, binary 11111110 (decimal 254 decimal). Since there is carry out of bit 7 (the eighth bit), the carry is set, indicating that the result needs 9 bits. The valid 9-bit result is the concatenation of the carry flag with the result.
The other common ALU status register bits will be Sign_Flag set, Zero_flag clear, and Overflow_Flag clear.
If 11111111 represents two's complement signed integer −1 (x86 instruction ADD al,-1), then the interpretation of the result is −2 because Overflow_Flag is clear, and Carry_Flag is ignored. The sign of the result is negative, because Sign_Flag is set. 11111110 is the two's complement form of signed integer −2.
If 11111111 represents unsigned integer binary number 255 (x86 instruction ADD al,255), then the interpretation of the result would be 254, which is not correct, because the most significant bit of the result went into the Carry_Flag, which therefore cannot be ignored. The Overflow_Flag and the Sign_Flag are ignored.
Another example may be an 8-bit register with the bit pattern 01010101 and the carry flag set; if we execute a rotate left through carry instruction, the result would be 10101011 with the carry flag cleared because the most significant bit (bit 7) was rotated into the carry while the carry was rotated into the least significant bit (bit 0).
Most microprocessors, all the way back to the Intel 4004 and Intel 8008, have specific instructions to set and reset the carry flag. One exception was the Intel 8080 (and its derivative Z80), which did not include an explicit reset carry opcode, as the operation could be performed by any of the bitwise logical instructions (AND, OR, XOR), which cleared the carry flag.
The carry flag is also often used following comparison instructions, which are typically implemented as subtraction operations, to allow a decision to be made about which of the two compared values is less than (or greater or equal to) the other. Branch instructions which examine the carry flag are often represented by mnemonics such as BCC and BCS to branch if the carry is clear, or branch if the carry is set respectively. When used in this way the carry flag provides a mechanism for comparing the values as unsigned integers. This is in contrast to the overflow flag which provides a mechanism for comparing the values as signed integer values.
Vs. borrow flag
[edit]This section needs additional citations for verification. (July 2015) |
While the carry flag is well-defined for addition, there are two ways in common use to use the carry flag for subtraction operations.
The first uses the bit as a borrow flag, setting it if a<b when computing a−b, and a borrow must be performed. If a≥b, the bit is cleared. A subtract with borrow (SBB) instruction will compute a−b−C = a−(b+C), while a subtract without borrow (SUB) acts as if the borrow bit were clear. The 6800, 680x0, 8051, 8080/Z80, and x86[2] families (among others) use a borrow bit.
The second uses the identity that −x = (not x)+1 directly (i.e. without storing the carry bit inverted) and computes a−b as a+(not b)+1. The carry flag is set according to this addition, and subtract with carry computes a+not(b)+C, while subtract without carry acts as if the carry bit were set. The result is that the carry bit is set if a≥b, and clear if a<b. The System/360,[3] ARM, POWER/PowerPC, 6502, MSP430, COP8, Am29000, i960, and 88000 processors use this convention. The 6502 is a particularly well-known example because it does not have a subtract without carry operation, so programmers must ensure that the carry flag is set before every subtract operation where a borrow is not required.[4]
| Carry or borrow bit |
Subtract without carry/borrow |
Subtract with borrow |
Subtract with carry |
|---|---|---|---|
| C = 0 | a − b = a + not(b) + 1 |
a − b − 0 = a + not(b) + 1 |
a − b − 1 = a + not(b) + 0 |
| C = 1 | a − b − 1 = a + not(b) + 0 |
a − b − 0 = a + not(b) + 1 |
The processors listed above, which include the most popular microprocessors of the last few decades, call these operations "subtract with borrow" and "subtract with carry", respectively, but the nomenclature is far from consistent. The VAX, NS320xx, Fairchild Clipper and Atmel AVR architectures use the borrow bit convention, but call their a−b−C operation "subtract with carry" (SBWC, SUBC, SUBWC and SBC). The PA-RISC and PICmicro architectures use the carry bit convention, but call their a+not(b)+C operation "subtract with borrow" (SUBB and SUBWFB). Still others, such as the H8, call theirs "subtract extended" (SUBX). SPARC uses the borrow convention, the SUBX mnemonic, and the "subtract with carry" name.
The Motorola 6809 uses the borrow bit convention and both nomenclatures, calling the operation "subtract with borrow", but assigning it the mnemonic abbreviation SBC.[5]
The ST6 8-bit microcontrollers go both ways in a different sense. Although they do not have any sort of "subtract with carry" instruction, they do have a carry bit which is set by a subtract instruction, and the convention depends on the processor model. The ST60 processor uses the "carry" convention, while the ST62 and ST63 processors use the "borrow" convention.[6]
See also
[edit]References
[edit]- ^ The well known Z80 and 68000 are examples of such CPUs, among many others.
- ^ a b "Intel Architecture Software Developer's Manual, Volume 2: Instruction Set Reference Manual" (PDF). Retrieved 2007-10-25.
- ^ IBM System/360 Principles of Operation (PDF). p. 28. IBM Form A22-6821-0.
- ^ Tan, B.T.G. (May 1983). "SBC, TSX and TXS instructions of the 6800 and 6502" (PDF). Dr. Dobb's Journal (79): 67–68.
- ^ Motorola Inc. (March 1981). MC6809-MC6809E Microprocessor Programming Manual. p. A-61. M6809PM/AD. Archived from the original on 2025-01-23. Retrieved 2025-01-03.
{{cite book}}: CS1 maint: bot: original URL status unknown (link) - ^ "ST6 Family Programming Manual" (PDF). Revision 2.0. STMicroelectronics. October 2004. pp. 21–22, 42. Retrieved 2017-02-28.