Addition is one of the most fundamental operations in assembly language. In x86 architecture, the add
instruction performs arithmetic addition on registers, memory, or immediate values.
This guide covers:
- Syntax and behavior
- 32-bit and 64-bit examples
- Overflow and flags (CF, OF, ZF, SF)
- Common pitfalls and best practices
- Practice challenges (easy and hard)
Syntax of add
The add
instruction performs arithmetic addition:
add destination, source
- Operation:
destination = destination + source
- Rules:
- Operands must be the same size (e.g., both 32-bit or both 64-bit).
- Source can be a register, immediate value, or memory operand.
- Destination can be a register or memory operand.
- Memory-to-memory addition (e.g.,
add [mem1], [mem2]
) is not allowed.
Register Overview
x86 architecture provides registers of varying sizes. This guide focuses on full registers (32-bit and 64-bit):
64-bit | 32-bit | 16-bit | 8-bit High | 8-bit Low |
---|---|---|---|---|
RAX | EAX | AX | AH | AL |
RBX | EBX | BX | BH | BL |
RCX | ECX | CX | CH | CL |
RDX | EDX | DX | DH | DL |
Basic Addition Examples
Register-to-Register Addition
32-bit Example:
mov eax, 10mov ebx, 20add eax, ebx ; eax = 10 + 20 = 30
- Result:
EAX = 30
,EBX = 20
(unchanged)
64-bit Example:
mov rax, 100mov rbx, 200add rax, rbx ; rax = 100 + 200 = 300
- Result:
RAX = 300
,RBX = 200
(unchanged)
Immediate Value Addition
Add a constant to a register:
mov eax, 50add eax, 25 ; eax = 50 + 25 = 75
- Result:
EAX = 75
Memory and Register Addition
Add a value from memory to a register:
mov eax, [myVar] ; Load value from memoryadd eax, 5 ; eax = [myVar] + 5
Add a register value to memory:
add [myVar], eax ; [myVar] = [myVar] + eax
Note: Direct memory-to-memory addition is not supported.
Status Flags
The add
instruction updates the FLAGS register:
Flag | Description | Set When |
---|---|---|
CF | Carry Flag | Unsigned overflow (carry out) |
OF | Overflow Flag | Signed overflow |
ZF | Zero Flag | Result is zero |
SF | Sign Flag | Result is negative |
Example (unsigned overflow):
mov eax, 0xFFFFFFFF ; Largest 32-bit unsigned numberadd eax, 1 ; Wraps around
- Result:
EAX = 0
,CF = 1
,ZF = 1
,OF = 0
Signed vs. Unsigned Addition
Assembly treats signed and unsigned values the same; only the flags and interpretation differ.
Example (signed overflow):
mov eax, 0x7FFFFFFF ; Largest 32-bit signed int (2147483647)add eax, 1 ; Causes signed overflow
- Result:
EAX = 0x80000000
(-2147483648),OF = 1
Chained Addition
Add multiple values sequentially:
Single Register:
mov eax, 5add eax, 10add eax, 15 ; eax = 5 + 10 + 15 = 30
Multiple Registers:
mov eax, 10mov ebx, 20mov ecx, 30add eax, ebxadd eax, ecx ; eax = 10 + 20 + 30 = 60
Common Pitfalls
-
Mismatched Operand Sizes:
add ax, eax ; Invalid: 16-bit vs. 32-bit -
Memory-to-Memory Operations:
add [mem1], [mem2] ; Invalid: not allowed -
Unintended Overwrites:
add eax, ebx ; Modifies EAX, not EBX
Optimization with lea
The lea
(Load Effective Address) instruction can perform addition without affecting flags:
lea eax, [ebx + ecx * 2] ; eax = ebx + 2 * ecx
- Advantage: Faster for complex expressions and preserves flags.
- Use Case: Optimizing arithmetic in performance-critical code.
Instruction Summary
Instruction | Description |
---|---|
add eax, ebx | Adds EBX to EAX |
add eax, 5 | Adds immediate value 5 to EAX |
add eax, [mem] | Adds memory value to EAX |
add [mem], eax | Adds EAX to memory |
add rax, rbx | 64-bit register addition |
Practice Challenges
Easy Challenges (chal 4)
- Add 10 and 25 using
EAX
andEBX
. Store the result inEAX
. - Add
0xFFFFFFFF
and 1 inEAX
. Identify which flags are set. - Add
AL = 0xFF
andBL = 0x02
. What is the result inAL
? What areCF
andOF
?
Hard Challenges (chal 5)
- Add three 64-bit numbers in
RAX
,RBX
, andRCX
. Store the result inRAX
. - Detect signed overflow:
mov eax, 0x7FFFFFFFadd eax, 1; Check OF flag (e.g., using JO instruction)
- Add two large numbers from memory (
[a]
and[b]
) and store the result in a register usingmov
andadd
.