Hubbry Logo
Half-carry flagHalf-carry flagMain
Open search
Half-carry flag
Community hub
Half-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.
Half-carry flag
Half-carry flag
from Wikipedia

A half-carry flag (also known as an auxiliary flag) is a condition flag bit in the status register of many CPU families, such as the Intel 8080, Zilog Z80, the x86,[1] and the Atmel AVR series, among others. It indicates when a carry or borrow has been generated out of the least significant four bits of the accumulator register following the execution of an arithmetic instruction. It is primarily used in decimal (BCD) arithmetic instructions.

Usage

[edit]

Normally, a processor that uses binary arithmetic (which includes almost all modern CPUs) will add two 8-bit byte values according to the rules of simple binary addition. For example, adding 2516 and 4816 produces 6D16. However, for binary-coded decimal (BCD) values, where each 4-bit nibble represents a decimal digit, addition is more complicated. For example, adding the decimal value 25 and 48, which are encoded as the BCD values 2516 and 4816, the binary addition of the two values produces 6D16. Since the lower nibble of this value is a non-decimal digit (D), it must be adjusted by adding 0616 to produce the correct BCD result of 7316, which represents the decimal value 73.

  0010 0101   25
+ 0100 1000   48
-----------
  0110 1101   6D, intermediate result
+      0110   06, adjustment
-----------
  0111 0011   73, adjusted result

Likewise, adding the BCD values 3916 and 4816 produces 8116. This result does not have a non-decimal low nibble, but it does cause a carry out of the least significant digit (lower four bits) into the most significant digit (upper four bits). This is indicated by the CPU setting the half-carry flag. This value must also be corrected, by adding 0616 to 8116 to produce a corrected BCD result of 8716.

  0011 1001   39
+ 0100 1000   48
-----------
  1000 0001   81, intermediate result
+      0110   06, adjustment
-----------
  1000 0111   87, adjusted result

Finally, if an addition results in a non-decimal high digit, then 6016 must be added to the value to produce the correct BCD result. For example, adding 7216 and 7316 produces E516. Since the most significant digit of this sum is non-decimal (E), adding 6016 to it produces a corrected BCD result of 14516. (Note that the leading 1 digit is actually a carry bit.)

  0111 0010   72
+ 0111 0011   73
-----------
  1110 0101   E5, intermediate result
+ 0110        60, adjustment
-----------
1 0100 0101  145, adjusted result

Summarizing, if the result of a binary addition contains a non-decimal low digit or causes the half-carry flag to be set, the result must be corrected by adding 0616 to it; if the result contains a non-decimal high digit, the result must be further corrected by adding 6016 to produce the correct final BCD value.

The Auxiliary Carry Flag in x86

[edit]
Intel 8086 CPU status register
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 (bit position)
- - - - O D I T S Z - A - P - C Flags

The Auxiliary Carry Flag (AF) is a CPU flag in the FLAGS register of all x86-compatible CPUs,[2] and the preceding 8080-family. It has occasionally been called the Adjust Flag by Intel.[3] The flag bit is located at position 4 in the CPU flag register. It indicates when an arithmetic carry or borrow has been generated out of the four least significant bits, or lower nibble. It is primarily used to support binary-coded decimal (BCD) arithmetic.

The Auxiliary Carry flag is set (to 1) if during an "add" operation there is a carry from the low nibble (lowest four bits) to the high nibble (upper four bits), or a borrow from the high nibble to the low nibble, in the low-order 8-bit portion, during a subtraction. Otherwise, if no such carry or borrow occurs, the flag is cleared.[4]

See also

[edit]

References

[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
The half-carry flag, also known as the auxiliary carry flag, is a single-bit status flag located at bit 4 of the flag register in certain microprocessors, indicating a carry out from bit 3 to bit 4 during or a borrow from bit 4 to bit 3 during of an 8-bit . This flag is primarily utilized to facilitate (BCD) arithmetic, where each decimal digit is represented by a 4-bit (values 0-9), by detecting inter-nibble carries or borrows that require adjustment to maintain valid results. In practice, it is set to 1 when such a carry or borrow occurs and cleared to 0 otherwise, enabling instructions like the Decimal Adjust Accumulator (DAA) to add or subtract 6 from the affected nibble as needed. Introduced with the microprocessor in 1974, the half-carry flag addressed the need for efficient decimal arithmetic in early systems, where binary operations on BCD data could produce invalid results without correction. The , released in 1976 as an enhanced, software-compatible successor to the 8080, retained and expanded support for this flag, integrating it into a broader set of arithmetic instructions including ADD, ADC, SUB, SBC, INC, DEC, and CMP. In the x86 architecture, which evolved from the 8080/8086 lineage, the flag—denoted as AF in the EFLAGS register—persists for backward compatibility and continues to support BCD operations via instructions such as DAA, DAS, AAA, and AAS, though its use has diminished with the rise of binary arithmetic in modern software. Derivatives like the custom CPU in Nintendo's console, based on Z80 architecture, also employ the half-carry flag (H bit) for similar purposes in 8-bit operations. Beyond core arithmetic, the flag's behavior is undefined or reset in logical operations (e.g., , XOR) and certain rotates/shifts, ensuring it primarily serves its BCD role without unintended side effects. Its presence highlights a key design choice in microprocessor engineering to balance binary efficiency with compatibility, influencing systems from embedded controllers to early personal computers.

Overview

Definition

The half-carry flag is a single-bit indicator within a processor's status or that signals a carry or borrow between the lower and upper nibbles of an operand during arithmetic operations. It is typically located at bit 4 of the , as seen in the x86 architecture's EFLAGS register. This flag enables detection of intra-byte carry events, distinct from the full-word . The flag is set when a carry propagates out of bit 3 (the highest bit of the least significant , bits 0-3) into bit 4 during an 8-bit , or when a borrow affects bit 3 from bit 4 during . Conversely, it is cleared in the absence of such events. In the Z80 architecture, for instance, the half-carry flag (H) follows this behavior precisely, setting on a carry from bit 3 to bit 4 in or a borrow from bit 4 in . Known by alternative names across architectures, it is termed the auxiliary carry flag (AF) in x86 documentation and the H flag in Z80 processors, while sometimes referred to as the adjust flag in related technical references. This flag's state—1 for set on carry/borrow, 0 otherwise—facilitates adjustments in computations like binary-coded decimal arithmetic, though its precise role in such operations varies by implementation.

Purpose

The half-carry flag, also known as the auxiliary carry flag in some architectures, serves to detect carries or borrows occurring between the lower and upper s (bits 3 and 4) during arithmetic operations, primarily to facilitate efficient (BCD) arithmetic. By signaling nibble-level overflows or underflows, it allows processors to perform decimal adjustments only when necessary, rather than requiring dedicated correction instructions after every BCD operation. This mechanism supports the correction of binary results into valid BCD representations using instructions like DAA (Decimal Adjust Accumulator), which relies on the flag's state to add or subtract 6 from the affected nibble if a carry has occurred. In contrast to the full , which tracks overflows or underflows at the byte level (e.g., from bit 7 to bit 8), the half-carry flag specifically monitors intra-byte carries at bit 3, enabling precise handling of the 4-bit boundaries inherent in BCD encoding where each digit occupies a . This distinction ensures that BCD operations can maintain integrity without interfering with general binary arithmetic, as the half-carry flag is typically unaffected or undefined in non-arithmetic instructions like logical operations. The flag's design improves performance in systems mixing binary and BCD by permitting conditional adjustments based on its state, thereby avoiding unnecessary overhead in decimal-heavy computations. In legacy microprocessors and embedded systems, such as those used in calculators or financial software, it reduces overall instruction count and execution cycles for BCD tasks, enhancing efficiency in applications where precision is paramount without full post-adjustment computations after each add or subtract.

Usage in Arithmetic

Binary-Coded Decimal Operations

In (BCD) representation, each 4-bit encodes a single decimal digit from 0 to 9, allowing direct mapping to decimal values but requiring adjustments after binary arithmetic to ensure valid BCD results. For instance, adding 0x05 (BCD for 5) and 0x08 (BCD for 8) yields a binary sum of 0x0D, but this represents an invalid BCD digit 13 in the lower ; correction involves adding 0x06 to produce 0x13, the proper BCD for 13. The half-carry flag, set when there is a carry out of bit 3 (the upper bit of the lower ) during , plays a key role in the BCD adjustment . After a binary , if the half-carry flag is set or the lower exceeds 9 (i.e., (result & 0x0F) > 9), 0x06 is added to correct the lower overflow. For the upper , if the result exceeds 0x9F, the original carry flag is set, or a carry occurs from the lower adjustment, 0x60 is added to propagate the decimal carry correctly. This process ensures the final byte represents two valid decimal digits (00 to 99). In BCD subtraction, the half-carry flag indicates a borrow from bit 4 into the lower , guiding equivalent adjustments in decimal adjust operations. If the half-carry flag is set or the lower exceeds 9 after binary , 0x06 is subtracted from the result; similarly, for the upper , if the is set or the result exceeds 0x99 (after lower adjustment), 0x60 is subtracted to maintain valid BCD digits. These steps mirror adjustments but invert the direction to handle underflow. A representative example illustrates the process: adding 0x39 (BCD for 39) and 0x48 (BCD for 48) produces a binary sum of 0x81, with the half-carry flag set due to the lower carry (9 + 8 = 17). Adjusting by adding 0x06 yields 0x87 (BCD for 87, matching the sum 87), and since the upper 8 is valid (≤9) with no further carry, no additional 0x60 adjustment is needed. The core formula for lower adjustment in BCD addition is: if ((A & 0x0F) > 9) or half-carry set, then A += 6, where A is the accumulator or result register; this is followed by upper checks as described.

Binary and Logical Operations

In binary addition and operations, the half-carry flag is set whenever a carry occurs from bit 3 to bit 4 or a borrow is generated from bit 4 to bit 3, regardless of whether the operands are interpreted in binary or other formats. This mechanism allows detection of carries across the lower boundary (bits 0–3) without requiring explicit bit masking, which proves useful in multi-precision arithmetic for propagating carries between 4-bit units or in scenarios involving representations where nibble overflows must be flagged. For example, adding 0x08 (binary 1000) and 0x08 (binary 1000) yields 0x10 (binary 10000), with the half-carry flag set due to the carry out from bit 3, even though the overall binary result is accurate; this signals a potential overflow in a single hexadecimal digit, aiding in hex-based computations or boundary checks. In logical operations such as AND, OR, and XOR, in the Z80 the half-carry flag is set for AND and reset for OR and XOR; in x86 architectures, it is typically undefined. In the Z80 and x86, rotate and shift operations typically reset the half-carry flag, except where specifically defined otherwise. The half-carry flag supports tasks by highlighting 4-bit boundaries, facilitating operations like swaps or adjustments in data packing routines where intra-byte carries need monitoring. In emulators and debuggers, it is employed to track and verify -level carries for accurate reproduction of arithmetic behaviors across processor simulations.

Implementations in Architectures

8080 and Z80 Processors

In the , the half-carry flag, also known as the auxiliary carry (AC) flag, occupies bit 4 of the 8-bit register (often denoted as the F register or ). This flag was introduced with the 8080 in April 1974 to facilitate (BCD) arithmetic in early systems. The AC flag is set during addition operations (such as ADD and ADC) if a carry occurs from bit 3 to bit 4 of the operands, and during subtraction operations (such as SUB and SBB) if a borrow occurs from bit 4 to bit 3. Logical operations like AND, OR, and XOR generally reset the AC flag to zero in the 8080, though AND sets it based on the logical OR of bit 3 from each operand. The Decimal Adjust Accumulator (DAA) instruction relies on the to perform BCD corrections after arithmetic operations, adding 0x06 to the lower if the AC flag is set or if the lower nibble exceeds 9, and similarly adjusting the upper nibble based on the . This mechanism ensures accurate decimal results without manual adjustment in software, supporting applications in calculators and financial systems prevalent in 1970s computing. The Zilog Z80, released in 1976 as an enhanced, software-compatible successor to the 8080, retains the half-carry flag as bit 4 (H flag) in its 8-bit F register, maintaining identical positioning and core behavior for 8080 compatibility. Instructions such as ADD, SUB, AND, OR, and XOR affect the H flag based on bit 3 carry or equivalent logical conditions, similar to the 8080, while Z80 extensions like ADC and SBC propagate the half-carry from the previous operation into the current addition or subtraction. For subtraction in the Z80, the H flag is set on a borrow from bit 4 to bit 3, mirroring 8080 semantics, and logical operations leave the H flag unaffected or reset it depending on the specific opcode. The DAA instruction in the Z80 functions identically, using the H flag for BCD adjustment to support legacy 8080 code in expanded systems like the ZX Spectrum and CP/M environments.

x86 Family

In the x86 architecture, the half-carry flag is officially known as the . It occupies bit 4 of the EFLAGS register in 32-bit mode and the lower 32 bits of the RFLAGS register in 64-bit mode, serving to indicate a carry or borrow between the low-order (bits 0-3) and high-order (bits 4-7) of the during arithmetic operations. AF is set by addition instructions such as ADD and ADC if a carry occurs out of bit 3 (from the low to the high nibble), including any carry-in for ADC; it is cleared otherwise. Similarly, subtraction instructions like SUB and SBB set AF if a borrow occurs into bit 4 (from the high nibble to the low nibble), accounting for any borrow-in in the case of SBB. These updates occur based on the low nibble of the least significant byte in multi-byte operations, with higher bytes not affecting AF, though the flag is primarily relevant in 8-bit or 16-bit legacy contexts. Several adjustment instructions utilize AF to support binary-coded decimal (BCD) and ASCII arithmetic. The AAA (ASCII Adjust After Addition) instruction, for instance, checks the state of AF after an ADD operation on unpacked BCD digits in AL; if AL > 9 or AF is set, it adds 6 to AL (to correct the low nibble), adds 1 to AH (to propagate the carry), sets AF and the Carry Flag (CF), and masks AL to its low nibble (AL AND 0xF). The AAS (ASCII Adjust After Subtraction) and DAS (Decimal Adjust AL After Subtraction) instructions set AF if a borrow is needed from the high nibble (low nibble of AL > 9 or AF set), subtracting 6 from AL and potentially adjusting CF and AH for AAS. AAD (ASCII Adjust AX Before Division) leaves AF undefined after converting two unpacked BCD digits in AX to binary form. These instructions are invalid in 64-bit mode, triggering an undefined opcode (#UD) exception, limiting their use to compatibility or legacy modes. Despite the obsolescence of BCD operations in modern computing, AF persists in the x86 family for , with its update behavior by basic arithmetic instructions unchanged across 32-bit and 64-bit modes. However, outside legacy codebases, it sees minimal use, as contemporary software favors binary arithmetic over decimal adjustments.

AVR Microcontrollers

In , the half-carry flag (H) resides in bit 5 of the 8-bit (SREG), which captures the outcomes of arithmetic, logical, and shift operations. The H flag indicates a carry or borrow across the boundary between the lower (bits 3–0) and the upper (bits 7–4) during certain instructions, facilitating detection of nibble-level overflows or underflows. This flag is particularly valuable in embedded applications involving (BCD) arithmetic, where manual adjustments are required to correct results for validity. The H flag is updated by key arithmetic instructions such as ADD (add without carry), ADC (add with carry), SUB (subtract without borrow), and SBC (subtract with borrow). For ADD and ADC, H is set if a carry occurs from bit 3 to bit 4, determined by the logical condition HRd(3)Rr(3)Rr(3)R(3)R(3)Rd(3)H \leftarrow \mathrm{Rd}(3) \land \mathrm{Rr}(3) \lor \mathrm{Rr}(3) \land \overline{\mathrm{R}(3)} \lor \overline{\mathrm{R}(3)} \land \mathrm{Rd}(3), where Rd and Rr are the source and destination operands, and R is the result; for SUB and SBC, it is set analogously if a borrow affects bit 3. Unlike some architectures, AVR lacks a dedicated adjust instruction (DAA), so BCD operations rely on conditional checks of the H flag (along with the C) to manually add or subtract correction values like 0x06 to each when necessary. A representative example illustrates this behavior: adding 0x0F (binary 00001111) and 0x01 (binary 00000001) using ADD yields 0x10 (binary 00010000), with the lower overflowing (0xF + 0x1 = 0x10 in binary, generating a carry to the upper ), thus setting H to 1 for nibble overflow detection. This mechanism supports precise control in resource-constrained embedded math, such as adjusting readings to format without full BCD hardware support. AVR's rotate instructions exhibit unique H flag behavior tailored to bit manipulation tasks common in embedded systems. For ROL (rotate left through carry), H is set to the value of bit 3 in the source register before the rotation (HRd(3)H \leftarrow \mathrm{Rd}(3)), allowing detection of whether the shifted content crosses the nibble boundary; ROR (rotate right through carry) leaves H unaffected. This rotate-specific handling aids in bit-banged serial protocols, like software implementations of or custom bit streams, where tracking nibble positions optimizes data packing and transmission in 8-bit AVR devices used for interfacing or simple UI displays requiring decimal outputs.

Historical Development

Origins in Early Microprocessors

The half-carry flag, also known as the auxiliary carry flag, first appeared in the microprocessor, introduced in April 1974 as an enhanced successor to the earlier Intel 8008. This 8-bit CPU included a dedicated flag bit in its to detect carries from the lower (bits 0-3) to the upper (bits 4-7) during arithmetic operations, enabling efficient support for (BCD) arithmetic. The 8080's design addressed limitations in prior chips by incorporating this flag alongside the standard , allowing for precise adjustments in decimal computations without software overhead. The introduction of the half-carry flag was driven by the transition from mainframes and minicomputers to cost-effective microprocessors for and consumer applications, where decimal arithmetic was essential for , terminals, and equipment. Intel's early collaboration with on the 4004 chip (1971) highlighted the need for BCD handling in commercial devices, but the 8080 extended this capability to broader markets, such as video display terminals and accounting machines, by optimizing hardware for decimal operations. This shift reflected the growing demand for microprocessors in non-scientific , where binary arithmetic alone was insufficient for legacy decimal-based systems. Unlike earlier 4-bit processors like the , which relied solely on a single for BCD overflow detection without a dedicated half-carry mechanism, the 8080 formalized this feature to streamline nibble-level adjustments. The 8008, an 8-bit predecessor from 1972, also lacked a half-carry flag, using only carry, zero, sign, and parity flags for basic arithmetic. This evolution drew indirect inspiration from mainframe architectures, such as the (introduced 1964), which included condition codes for decimal overflow and supported packed BCD instructions to handle business data formats prevalent in enterprise computing. A pivotal documentation of the half-carry flag occurred in the datasheet and programming manuals released in 1974, which explicitly defined the H flag's role in the Decimal Adjust Accumulator (DAA) instruction for post-arithmetic BCD correction. The DAA (0x27) uses the H flag to add 6 to the lower if a carry from bit 3 occurs, ensuring valid BCD results and setting the accordingly for multi-byte operations. This hardware support marked a key advancement, reducing the instruction cycles needed for decimal math in early microprocessor-based systems.

Evolution and Modern Relevance

The half-carry flag, also known as the auxiliary carry flag, was adopted in key designs during the late 1970s and beyond to support efficient (BCD) arithmetic. The , introduced in July 1976, included the half-carry flag (H) in its to facilitate BCD operations by detecting carries between the lower four bits ( 0) and the upper four bits, building on the Intel 8080's design for compatibility in early personal computers and embedded systems. Similarly, 's 8086 , released in 1978, incorporated the auxiliary carry flag (AF) as part of its flags , enabling instructions like DAA (decimal adjust after addition) for BCD handling in applications such as calculators and early . This feature persisted into later architectures like the Atmel AVR family, introduced in 1996, where the half-carry flag (H in the SREG ) supports BCD arithmetic in low-power 8-bit microcontrollers for tasks including interfaces and simple displays. In contrast, reduced instruction set computing (RISC) architectures such as and MIPS omitted the half-carry flag from the outset to prioritize simplicity and performance, relying instead on software routines for any BCD needs, as hardware support for decimal operations was deemed unnecessary in general-purpose computing. 's condition flags, for instance, include only carry (C), overflow (V), zero (Z), and negative (N), without a dedicated half-carry mechanism, reflecting a design philosophy that avoids specialized flags to reduce complexity in pipelined processors. MIPS similarly lacks both a full in its basic integer operations and any half-carry equivalent, handling overflows via exceptions or software emulation where required. This omission aligned with the shift toward binary arithmetic dominance in RISC designs during the 1980s and 1990s. The flag's prominence declined in 32- and 64-bit systems, where BCD operations became less common due to the prevalence of binary floating-point and integer math, often managed through software libraries rather than hardware flags. In modern x86 architectures, while the auxiliary carry flag remains for backward compatibility, BCD is typically processed using the x87 FPU's packed BCD instructions like FBLD (load binary-coded decimal) and FBSTP (store BCD), which convert between BCD and binary formats without relying on the flag for adjustment. This software-centric approach, supported by libraries in languages like C and assembly, has rendered the half-carry flag largely vestigial in high-performance computing, though it persists in x86-64 for legacy code. Despite its decline, the half-carry flag retains niche relevance in retro , emulation, and embedded applications. In emulators for systems like the , which uses a Z80-derived CPU, accurate of the half-carry flag is essential for correct BCD handling in games involving scores or timers, as deviations can cause glitches in arithmetic-dependent routines. For embedded systems, employ the flag in BCD arithmetic to drive 7-segment LED displays or numeric interfaces in devices like digital meters, where efficient decimal output is prioritized over binary processing. Legacy operating systems such as also utilize the flag in x86 assembly code for BCD operations in utilities and early applications, maintaining compatibility with 1970s-era software. As of 2025, no significant architectural revivals or changes to the half-carry flag have emerged, with its role confined to these specialized domains amid the dominance of binary-centric designs in IoT and general .

References

Add your contribution
Related Hubs
User Avatar
No comments yet.