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 Portion | 8-bit High | 8-bit Low |
---|---|---|---|
EAX | AX | AH | AL |
EBX | BX | BH | BL |
ECX | CX | CH | CL |
EDX | DX | DH | DL |
- 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 viaEAX
, 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-bitadd ax, bx ; Valid: 16-bit + 16-bitadd ah, bl ; Valid: 8-bit + 8-bitadd 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
becomes0x00
. AH
= 0x00BL
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
becomes0x0000
. 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:
Flag | Meaning | Condition |
---|---|---|
CF | Carry Flag | Set if there’s a carry out of the most significant bit |
OF | Overflow Flag | Set if there’s a signed overflow |
ZF | Zero Flag | Set if the result is zero |
SF | Sign Flag | Set 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
-
Mixing Register Sizes:
add ax, eax ; Invalid: 16-bit and 32-bit mismatchAlways ensure both operands are of the same size.
-
Accidental Overwrite: Writing to a partial register can unintentionally affect the full register:
mov eax, 0x12345678mov al, 0xFF ; EAX becomes 0x123456FFWriting to
AL
modifies only the lowest 8 bits ofEAX
, leaving the upper bits unchanged. -
Truncation and Unexpected Flags: When the result exceeds the register size, it is truncated, and the carry flag is set:
mov al, 0xFEadd 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
affectsEAX
, and writing toAL
orAH
affectsAX
andEAX
. - 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
andOF
, for subsequent logic.
Practice Challenges
Test your understanding with these challenges, ranging from easy to advanced.
Easy Challenges (chal 6)
-
Add Two 8-bit Values:
- Set
AL
= 0x10 andBL
= 0x22. - Perform
add al, bl
. - What is the result in
AL
? What flags are affected?
- Set
-
High-byte Addition:
- Set
AH
= 0xF0 andBL
= 0x10. - Perform
add ah, bl
. - What are the final values of
AH
andCF
?
- Set
-
16-bit Addition with Overflow:
- Set
AX
= 0xFFFF. - Perform
add ax, 1
. - What is the value of
AX
? Which flags are set?
- Set
Intermediate Challenges (chal 7)
-
8-bit Addition with Carry Check: Write a sequence that:
- Sets
AL
= 0xFE andBL
= 0x05. - Performs
add al, bl
and stores the result inCL
. - Checks if a carry occurred and stores 1 in
DL
ifCF
= 1, otherwise 0.
- Sets
-
High-byte Addition with Wrap Detection: Write a sequence that:
- Sets
AH
= 0xF0 andBH
= 0x20. - Adds
AH
andBH
, storing the result inDL
. - If the result wraps (i.e.,
CF
= 1), setsDH
= 1; otherwise, setsDH
= 0.
- Sets
Advanced Challenges (chal 8)
-
8-bit Addition with Overflow Detection: Write a sequence that:
- Sets
AL
= 0x7F andBL
= 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, setCL
= 0.
- Sets
-
Triple 8-bit Addition: Write a sequence that:
- Sets
AL
= 0x30,BL
= 0x20, andCL
= 0x10. - Computes
AL + BL + CL
, storing the result inAL
. - Detects signed overflow using
JO
and setsDL
= 1 if overflow occurs, otherwise 0.
- Sets
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, 0xFFadd al, 0x01 ; AL = 0x00, CF = 1