Hubbry Logo
Carry flagCarry flagMain
Open search
Carry flag
Community hub
Carry flag
logo
7 pages, 0 posts
0 subscribers
Be the first to start a discussion here.
Be the first to start a discussion here.
Contribute something
Carry flag
Carry flag
from Wikipedia

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.

An example is what happens if one were to add 255 and 255 using 8-bit registers. The result should be 510 which is the 9-bit value 111111110 in binary. The 8 least significant bits always stored in the register would be 11111110 binary (254 decimal) but since there is carry out of bit 7 (the eight 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.

For x86 ALU size of 8 bits, an 8-bit two's complement interpretation, the addition operation 11111111 + 11111111 results in 111111110, Carry_Flag set, Sign_Flag set, and Overflow_Flag clear.

If 11111111 represents two's complement signed integer −1 (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 (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).

The early microprocessors Intel 4004 and Intel 8008 had specific instructions to set as well as reset the carry flag explicitly. However, the later Intel 8080 (and Z80) did not include an explicit reset carry opcode as this could be done equally fast via one of the bitwise AND, OR or XOR instructions (which do not use the carry flag).

The carry flag is also often used following comparison instructions, which are typically implemented by subtractive operations, to allow a decision to be made about which of the two compared values is lower 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]

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 ab, and a borrow must be performed. If ab, the bit is cleared. A subtract with borrow (SBB) instruction will compute abC = 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 ab 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 ab, 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]

Summary of different uses of carry flag in subtraction
Carry or
borrow bit
Subtract without
carry/borrow
Subtract
with borrow
Subtract
with carry
C = 0 ab
= a + not(b) + 1
ab0
= a + not(b) + 1
ab1
= a + not(b) + 0
C = 1 ab1
= a + not(b) + 0
ab0
= 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 abC 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]
[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
The carry flag (often abbreviated as CF) is a single-bit flag in a processor's that signals whether an arithmetic operation, such as or , has produced a carry-out from the most significant bit (MSB) or required a borrow-in for the operation, primarily serving to detect overflow in unsigned arithmetic. This flag is essential for handling multi-precision arithmetic, where it propagates carry or borrow values between successive operations to compute results larger than a single register can hold. In the x86 architecture, the carry flag occupies bit 0 of the EFLAGS or RFLAGS register and is set to 1 upon a carry-out during instructions like ADD or ADC, cleared to 0 otherwise, and can be explicitly manipulated using instructions such as STC (set), CLC (clear), or CMC (complement). It distinguishes itself from the (OF), which handles signed , enabling conditional jumps (e.g., JC for jump if carry) that support efficient unsigned comparisons and loop controls in programming. Similarly, in architectures, the carry flag in the application program (APSR) is set to 1 on addition if an unsigned overflow occurs or on if no borrow is needed, and it also captures the last bit shifted out in shift operations, facilitating conditional execution of instructions based on arithmetic outcomes. The carry flag's role extends to bit manipulation instructions like shifts (SHL, SHR) and rotates (ROL, ), where it stores overflow bits to enable precise control in low-level operations, and it remains a foundational element in CPU design across architectures for ensuring arithmetic integrity without software intervention.

Fundamentals

Definition

The carry flag (CF), also known as the C flag in some architectures, is a single-bit status flag within a processor's that indicates a carry-out from the most significant bit (MSB) position during unsigned arithmetic operations, such as , or during certain instructions like shifts and rotates. In the x86 architecture, for instance, the carry flag occupies bit 0 of the EFLAGS register and is set to 1 when a carry occurs from the MSB or a borrow is required into the MSB for , while it is cleared to 0 otherwise. Similarly, in architectures, the carry flag is part of the application program status register (APSR) and reflects carry conditions from arithmetic instructions. Its primary purpose is to detect overflow in unsigned operations, signaling when the result cannot be fully represented within the operand's bit width and requires an additional bit. For example, in an 8-bit unsigned , if the sum exceeds 255 (the maximum value representable in 8 bits), a carry-out into a hypothetical 9th bit sets the to 1, enabling software to handle the overflow appropriately, such as in multi-precision arithmetic. This mechanism is essential for maintaining accuracy in computations involving unsigned values across various processor designs. In terms of binary mechanics, for an n-bit of two operands, the carry flag is set to 1 if a carry propagates out of the MSB, indicating the sum necessitates an (n+1)th bit to represent it fully. Consider a 4-bit example: adding 10112 ( 11) and 01012 ( 5) produces 100002 ( 16), where the leading 1 beyond the 4 bits sets the carry flag to 1. This flag's behavior is consistent in its role for detecting such carry-outs, though its exact setting conditions may vary slightly by instruction and .

Binary Representation

In x86 architecture, the carry flag (CF) is encoded as the least significant bit, designated as bit 0, of the EFLAGS or RFLAGS register; bit positions vary by architecture. It is set to 1 to indicate the generation of a carry out from the most significant bit during an arithmetic operation and cleared to 0 in the absence of such a carry. In x86-like architectures, dedicated instructions enable explicit manipulation of the carry flag, including STC (opcode F9) to set CF to 1, CLC (opcode F8) to clear CF to 0, and CMC (opcode F5) to complement its current value by toggling between 0 and 1. The carry flag interacts with the , also known as the status word, through automatic updates following specific operations. For instance, arithmetic instructions such as ADD set or clear CF based on whether a carry out occurs from the most significant bit, whereas non-arithmetic instructions like MOV leave CF unchanged. In operations, CF can be conceptually determined as follows: if the sum of the source and destination operands exceeds the maximum unsigned value for the operand size (2^n - 1 for n bits), then CF ← 1; otherwise, CF ← 0. Software visibility into the carry flag is provided via instructions that save or restore the entire , such as PUSHF to push it onto the stack and POPF to pop and restore it, or through direct testing in using conditional jumps like JC (jump if carry) or JNC (jump if no carry).

Arithmetic Applications

Addition Operations

In binary within computer processors, the carry flag is set to 1 if the sum of two n-bit unsigned operands exceeds 2n12^n - 1, indicating an overflow for unsigned arithmetic that requires handling beyond the n-bit width. This occurs specifically when a carry-out is generated from the most significant bit (MSB) during the . The mechanics of carry generation rely on a ripple-carry structure, where propagates from the least significant bit (LSB) to the MSB. Each bit position employs a full that takes two bits and an incoming carry-in, producing a sum bit and a carry-out to the next position. The carry ripples sequentially: if the sum at any bit exceeds 1 (considering the carry-in), it sets the carry-out to 1, potentially propagating through higher bits until reaching the MSB. The carry-out from the MSB, which sets the carry flag, follows the full adder logic: CF=(An1Bn1)((An1Bn1)Cn1)CF = (A_{n-1} \land B_{n-1}) \lor ((A_{n-1} \oplus B_{n-1}) \land C_{n-1}) where An1A_{n-1} and Bn1B_{n-1} are the MSBs of the operands, and Cn1C_{n-1} is the carry-in to the MSB. For instance, in an 8-bit addition of 255 (11111111211111111_2) and 1 (00000001200000001_2), the result is 256, which modulo 282^8 yields 00000000200000000_2 with a carry-out of 1 from the MSB, thus setting the carry flag. This flag enables efficient multi-byte addition in unsigned arithmetic, as seen in instructions like ADC (Add with Carry), which adds the operands plus the current carry flag value as carry-in to the LSB, facilitating chained operations for larger integers across multiple registers or memory words.

Subtraction and Multi-Precision

In subtraction operations within computer architectures, the carry flag (CF) functions as a borrow indicator for unsigned arithmetic. Specifically, when performing a subtraction using the SUB instruction, CF is set to 1 if the subtrahend (source operand) is greater than the minuend (destination operand), indicating that a borrow was required from a higher significance bit; otherwise, it is cleared to 0. This behavior arises because subtraction in representation is implemented as the addition of the two's complement negation of the subtrahend, where the borrow corresponds to a carry out from the most significant bit during this addition. For example, consider an 8-bit unsigned subtraction of 10 (binary 00001010) from 5 (binary 00000101). The operation yields a result of 11111011 (decimal 251 in unsigned interpretation), and CF is set to 1 because 5 < 10, requiring a borrow. In general, for unsigned operands A and B, CF = 1 if A < B after subtraction, which is logically equivalent to the negation of (A ≥ B). The carry flag also plays a crucial role in multi-precision arithmetic, where it propagates borrows across multiple limbs (fixed-width portions of larger operands) to enable operations on numbers exceeding the processor's native word size. This is typically achieved using the SBB (Subtract with Borrow) instruction, which subtracts the source operand plus the current value of CF from the destination: DEST ← DEST - (SRC + CF), setting CF based on whether an additional borrow is needed. For instance, to subtract two 64-bit unsigned integers on a 32-bit architecture, the least significant 32 bits are subtracted first with SUB (setting CF if a borrow occurs), followed by SBB on the most significant 32 bits to incorporate and propagate the borrow from the lower limb. This chaining mechanism ensures accurate handling of large integers without native support for wider operands.

Architectural Implementations

x86 Family

In the x86 architecture, the carry flag (CF) resides at bit 0 of the in 16-bit mode, the EFLAGS register in 32-bit mode, and the RFLAGS register in 64-bit mode. This positioning allows CF to indicate carry-out from the most significant bit during arithmetic operations or serve as an input for multi-precision computations across all operating modes, including real, protected, virtual-8086, and long (64-bit). Key instructions that update CF include ADD, which sets the flag if there is a carry-out from the most significant bit of the result (indicating unsigned overflow), and ADC, which adds the source , destination , and the current CF value, setting CF if a carry-out occurs from the most significant bit. Similarly, SUB sets CF if the destination is smaller than the source for unsigned operands (indicating a borrow), while SBB subtracts the source and the current CF from the destination, setting CF if a borrow is required. Rotation instructions such as (rotate left through carry) and RCR (rotate right through carry) treat CF as an extension of the operand, setting it to the bit shifted out of the most significant position or the previous CF value, depending on the rotation count. Conditional jumps based on CF include JC (jump if carry), which branches if CF is 1, and JNC (jump if no carry), which branches if CF is 0; these are commonly used in loops for multi-precision arithmetic, such as adding or subtracting numbers larger than the register size by propagating the carry or borrow across iterations. The carry flag mechanism was introduced with the microprocessor, released on June 8, 1978, as part of its 16-bit to support unsigned arithmetic and . In modern implementations, CF behavior remains consistent and size-specific: for example, a 32-bit ADD operation in 64-bit mode sets CF based on carry-out from bit 31 of the lower 32 bits, unaffected by the upper 32 bits of the 64-bit register, ensuring compatibility while allowing operand-size overrides via prefixes.

Other Instruction Sets

In the ARM architecture, the carry flag is implemented as the C bit (bit 29) in the Application Program Status Register (APSR), which is set to 1 when an instruction results in a carry condition, such as unsigned overflow during addition. This flag supports instructions like ADDS, which performs addition and updates the flags including C based on the result, and ADCS, which adds two operands along with the existing C flag value while setting the flags for the subsequent operation. RISC-V's base integer instruction set lacks a dedicated carry flag, relying instead on separate instructions to detect and propagate carry for multi-precision arithmetic. Carry detection typically uses the SLTU (set less than unsigned) instruction to check if the sum of two exceeds the first operand, effectively identifying overflow as a carry out. Extensions such as Zba ( for generation) provide instructions like add.uw that can assist in certain operations but do not introduce a persistent ; add-with-carry operations are handled implicitly through sequencing multiple instructions or control/status registers (CSRs) in extended configurations. As of 2025, proposals for dedicated carry handling extensions, such as for multi-word arithmetic, remain under development but have not been ratified. The MIPS architecture omits a dedicated carry flag entirely, simulating carry handling through temporary registers and comparison instructions for multi-word operations. Specifically, the SLTU instruction sets a register to 1 if the first operand is less than the second under unsigned interpretation, enabling carry detection in addition (e.g., by comparing the sum against one operand) and borrow simulation in subtraction without altering a global flag state. Variations across other instruction sets highlight design trade-offs in flag management. In PowerPC, the carry (CA) bit resides in the XER special-purpose register and is updated by arithmetic instructions like ADD and SUBF to indicate unsigned overflow or borrow, while the summary overflow (SO) bit in CR0 (condition register field 0) latches overflow conditions persistently until cleared. Some RISC architectures merge carry and borrow semantics into a single bit for simplicity, as seen in PowerPC's unified handling, whereas others like MIPS and base omit flags altogether to reduce hardware complexity and favor explicit register-based propagation. Portability challenges arise in flag-less architectures, where software must emulate carry propagation using additional instructions, often resulting in higher instruction counts and performance overhead compared to flag-supported designs. This emulation is essential for applications requiring big-integer operations.

Versus Borrow Flag

In many processor architectures, the carry flag serves a dual role in arithmetic operations, functioning as a borrow indicator during to facilitate multi-precision computations. For instance, in the x86 architecture, the carry flag (CF) is set to 1 when a (SUB) requires a borrow from a higher significant bit position, meaning the unsigned value of the destination is less than that of the source . This same flag is then used as an input for the subtract with borrow (SBB) instruction, which subtracts the source plus the CF value (1 for borrow pending, 0 otherwise) from the destination, enabling chained multi-word subtractions. This duality contrasts with architectures that employ a dedicated extend or borrow flag separate from the primary carry flag, though such designs are relatively uncommon due to the added hardware overhead of maintaining additional status bits. In the family, for example, the carry flag (C) indicates borrow during single-precision subtractions (e.g., SUB, CMP), set to 1 if a borrow occurs into the most significant bit. However, a distinct extend flag (X) is provided for multi-precision operations, mirroring C in most arithmetic instructions but persisting independently to propagate borrow across multiple words in instructions like SUBX (subtract extended). Not all instructions update both flags equally; for instance, certain shifts or logical operations may affect C without altering X, allowing finer control in borrow-only scenarios where no carry-in from prior additions is involved. The polarity of the borrow indication can also vary, introducing conceptual overlap but operational differences. In architectures, the carry flag (C) is cleared (0) when a subtraction generates a borrow, effectively inverting the x86 convention where CF=1 signals borrow; instead, C=1 denotes no borrow, optimizing condition code usage for conditional execution. Dedicated borrow flags remain rare outside specialized designs like certain digital signal processors (DSPs), where separate flags may reduce logic complexity for tasks but increase register size—trading simplicity for precision in borrow propagation.

Versus Overflow Flag

The carry flag (CF) and overflow flag (OF) provide distinct mechanisms for detecting arithmetic overflow in binary operations, tailored to different number interpretations. The CF signals unsigned overflow by capturing a carry out from the most significant bit (MSB) during , indicating that the result has wrapped around modulo 2n2^n for an nn-bit , without regard to sign. In contrast, the OF detects signed overflow in representation, flagging inconsistencies where the of the result does not align with the expected outcome for signed operands—specifically, when two positive numbers sum to a negative result or two negative numbers sum to a positive one. For addition, the OF is computed as the exclusive OR of the carry into the sign bit and the carry out from the sign bit: OF=Cinn1Coutn1OF = C_{in}^{n-1} \oplus C_{out}^{n-1} where Cinn1C_{in}^{n-1} is the carry generated into the MSB position from the lower bits, and Coutn1C_{out}^{n-1} is the carry generated out of the MSB. This formulation identifies signed overflow precisely because it highlights a discrepancy in carry propagation at the sign position, which would not occur in valid signed arithmetic. The CF, however, is simply set to Coutn1C_{out}^{n-1}, ignoring any sign-specific carry analysis. In an 8-bit signed addition, +127 (01111111201111111_2) + 1 (00000001200000001_2) produces 10000000210000000_2 (-128), with no carry out (CF=0CF = 0) but a carry into the differing from the carry out (OF=1OF = 1), confirming signed overflow as the positive sum exceeds the maximum representable value of +127. For unsigned interpretation of the same bits, 255 (11111111211111111_2) + 1 (00000001200000001_2) yields 00000000200000000_2 with carry out (CF=1CF = 1), but the carries into and out of the match (OF=0OF = 0), as the signed values -1 + 1 = 0 stay within bounds. The CF supports unsigned use cases like validating loop iterations or detecting modular wraparound in counters, where exceeding 2n12^n - 1 requires handling the modulo behavior. The OF is critical for signed validations, such as in algebraic computations or data processing, to prevent erroneous sign changes that could lead to incorrect results. Conditional instructions leverage both, with CF enabling jumps for unsigned conditions and OF for signed overflow checks, like JO (jump if overflow).

References

Add your contribution
Related Hubs
Contribute something
User Avatar
No comments yet.