1124 words
6 minutes
Addition Using Partial Registers

In x86 assembly, partial registers allow access to smaller parts of the full CPU registers (like 8-bit or 16-bit parts of EAX, EBX, etc.). These partial registers can be used in arithmetic operations such as add.

This guide covers:

  • What are partial registers
  • How to use them with add
  • Flag effects
  • Practical examples
  • Common mistakes
  • Practice challenges

What Are Partial Registers?#

Partial registers allow access to smaller portions of the CPU’s general-purpose registers. In x86 architecture, a 32-bit register like EAX can be broken down into smaller parts:

Full Register (32-bit)16-bit Portion8-bit High8-bit Low
EAXAXAHAL
EBXBXBHBL
ECXCXCHCL
EDXDXDHDL
  • AX: Represents the lower 16 bits of EAX.
  • AH and AL: Represent the high and low 8 bits of AX, respectively.
  • In 64-bit mode, the 32-bit portion of a 64-bit register (e.g., RAX) is accessible via EAX, and the lower parts (AX, AH, AL) remain functional in the same way.

Partial registers are useful for operations where only a small amount of data is needed, such as processing ASCII characters (8-bit) or working with 16-bit values in legacy code.

Syntax for Partial Register Addition#

The add instruction in x86 assembly follows the same syntax for partial registers as for full registers:

add destination, source

However, both operands must be of the same size (e.g., both 8-bit or both 16-bit). Mixing different sizes, such as adding a 16-bit register to a 32-bit register, is invalid:

add al, bl ; Valid: 8-bit + 8-bit
add ax, bx ; Valid: 16-bit + 16-bit
add ah, bl ; Valid: 8-bit + 8-bit
add ax, ebx ; Invalid: 16-bit and 32-bit mismatch

The add instruction modifies the destination operand by adding the source value to it and stores the result in the destination.

Examples of Partial Register Addition#

Below are detailed examples demonstrating the use of partial registers with the add instruction, including their effects on registers and flags.

8-bit Addition (AL and BL)#

This example adds two 8-bit values stored in AL and BL:

mov al, 10 ; AL = 10 (0x0A)
mov bl, 5 ; BL = 5 (0x05)
add al, bl ; AL = AL + BL = 10 + 5 = 15 (0x0F)

Result:

  • AL = 15 (0x0F)
  • BL remains unchanged (5, or 0x05)
  • Flags affected (based on the result):
    • ZF (Zero Flag): 0 (result is non-zero)
    • CF (Carry Flag): 0 (no carry, as 15 < 256)
    • OF (Overflow Flag): 0 (no signed overflow)
    • SF (Sign Flag): 0 (most significant bit is 0)

High-byte Addition (AH and BL)#

This example adds the high byte of AX (AH) to BL:

mov ah, 0xF0 ; AH = 0xF0 (240)
mov bl, 0x10 ; BL = 0x10 (16)
add ah, bl ; AH = AH + BL = 0xF0 + 0x10 = 0x100

Result:

  • Since AH is an 8-bit register, the result is truncated to 8 bits: 0x100 becomes 0x00.
  • AH = 0x00
  • BL remains unchanged (0x10)
  • Flags affected:
    • ZF = 1 (result is zero)
    • CF = 1 (carry occurred, as 0x100 exceeds 8 bits)
    • OF = 0 (no signed overflow)
    • SF = 0 (most significant bit is 0)

16-bit Addition (AX and BX)#

This example adds a 16-bit value to AX:

mov ax, 0xFFFF ; AX = 0xFFFF (65535)
add ax, 1 ; AX = AX + 1 = 0xFFFF + 1 = 0x10000

Result:

  • Since AX is a 16-bit register, the result is truncated to 16 bits: 0x10000 becomes 0x0000.
  • AX = 0x0000
  • Flags affected:
    • ZF = 1 (result is zero)
    • CF = 1 (carry occurred, as 0x10000 exceeds 16 bits)
    • OF = 0 (no signed overflow)
    • SF = 0 (most significant bit is 0)

Status Flags with Partial Registers#

The add instruction, whether used with full or partial registers, updates the CPU’s FLAGS register. The following flags are commonly affected:

FlagMeaningCondition
CFCarry FlagSet if there’s a carry out of the most significant bit
OFOverflow FlagSet if there’s a signed overflow
ZFZero FlagSet if the result is zero
SFSign FlagSet if the most significant bit is 1

Even when operating on partial registers (e.g., add al, bl), the full FLAGS register is updated based on the operation.

Common Pitfalls and Best Practices#

Using partial registers requires caution to avoid common mistakes. Below are pitfalls and best practices to ensure correct usage:

Pitfalls#

  1. Mixing Register Sizes:

    add ax, eax ; Invalid: 16-bit and 32-bit mismatch

    Always ensure both operands are of the same size.

  2. Accidental Overwrite: Writing to a partial register can unintentionally affect the full register:

    mov eax, 0x12345678
    mov al, 0xFF ; EAX becomes 0x123456FF

    Writing to AL modifies only the lowest 8 bits of EAX, leaving the upper bits unchanged.

  3. Truncation and Unexpected Flags: When the result exceeds the register size, it is truncated, and the carry flag is set:

    mov al, 0xFE
    add al, 3 ; AL = 0x01, CF = 1 (0xFE + 3 = 0x101, truncated to 0x01)

Best Practices#

  • Be Explicit: Clearly specify which part of the register (AL, AH, AX) you intend to use.
  • Understand Side Effects: Writing to AX affects EAX, and writing to AL or AH affects AX and EAX.
  • Use Partial Registers Intentionally: Use partial registers for specific tasks like ASCII character manipulation or when working with small data sizes.
  • Check Flags: Always consider the impact on flags, especially CF and OF, for subsequent logic.

Practice Challenges#

Test your understanding with these challenges, ranging from easy to advanced.

Easy Challenges (chal 6)#

  1. Add Two 8-bit Values:

    • Set AL = 0x10 and BL = 0x22.
    • Perform add al, bl.
    • What is the result in AL? What flags are affected?
  2. High-byte Addition:

    • Set AH = 0xF0 and BL = 0x10.
    • Perform add ah, bl.
    • What are the final values of AH and CF?
  3. 16-bit Addition with Overflow:

    • Set AX = 0xFFFF.
    • Perform add ax, 1.
    • What is the value of AX? Which flags are set?

Intermediate Challenges (chal 7)#

  1. 8-bit Addition with Carry Check: Write a sequence that:

    • Sets AL = 0xFE and BL = 0x05.
    • Performs add al, bl and stores the result in CL.
    • Checks if a carry occurred and stores 1 in DL if CF = 1, otherwise 0.
  2. High-byte Addition with Wrap Detection: Write a sequence that:

    • Sets AH = 0xF0 and BH = 0x20.
    • Adds AH and BH, storing the result in DL.
    • If the result wraps (i.e., CF = 1), sets DH = 1; otherwise, sets DH = 0.

Advanced Challenges (chal 8)#

  1. 8-bit Addition with Overflow Detection: Write a sequence that:

    • Sets AL = 0x7F and BL = 0x01 (to cause signed overflow).
    • Performs add al, bl.
    • Uses the JO (Jump if Overflow) instruction to jump to a label if signed overflow occurs.
    • At the label, set CL = 1; otherwise, set CL = 0.
  2. Triple 8-bit Addition: Write a sequence that:

    • Sets AL = 0x30, BL = 0x20, and CL = 0x10.
    • Computes AL + BL + CL, storing the result in AL.
    • Detects signed overflow using JO and sets DL = 1 if overflow occurs, otherwise 0.

Summary#

Partial registers in x86 assembly (AL, AH, AX, etc.) allow precise control over smaller data sizes, making them ideal for byte-level or word-level operations. The add instruction behaves consistently with partial registers, but developers must be cautious of truncation, flag effects, and unintended modifications to the full register. By following best practices and understanding flag behavior, you can effectively use partial registers for efficient and accurate arithmetic operations.

Example to highlight truncation:

mov al, 0xFF
add al, 0x01 ; AL = 0x00, CF = 1
Addition Using Partial Registers
https://frqblog.vercel.app/posts/addition-using-partial-register/
Author
frqblog
Published at
2025-07-30
License
CC BY-NC-SA 4.0