0% found this document useful (0 votes)
7 views33 pages

Assembly Language Complete Guide

The document is a comprehensive guide to 8086 assembly language programming, covering foundational concepts, processor architecture, and practical programming techniques. It includes detailed explanations of registers, memory segmentation, and various assembly instructions, along with examples and templates for writing assembly programs. The guide aims to equip readers with the knowledge needed to become proficient in 8086 assembly language and prepare for exams.

Uploaded by

fizaan.mughal.01
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views33 pages

Assembly Language Complete Guide

The document is a comprehensive guide to 8086 assembly language programming, covering foundational concepts, processor architecture, and practical programming techniques. It includes detailed explanations of registers, memory segmentation, and various assembly instructions, along with examples and templates for writing assembly programs. The guide aims to equip readers with the knowledge needed to become proficient in 8086 assembly language and prepare for exams.

Uploaded by

fizaan.mughal.01
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

� Complete Guide to 8086 Assembly Language

Programming
From Zero to Exam-Ready

Table of Contents
1. Chapter 1: The Foundation — Understanding the 8086 Processor
2. Chapter 2: Registers — The Heart of 8086
3. Chapter 3: Memory Segmentation & Addressing
4. Chapter 4: Your First Assembly Program
5. Chapter 5: Data Movement — MOV and Friends
6. Chapter 6: Arithmetic Operations
7. Chapter 7: Logical & Bitwise Operations
8. Chapter 8: Flags Register Deep Dive
9. Chapter 9: Branching & Conditional Jumps
10. Chapter 10: Loops
11. Chapter 11: The Stack & Procedures
12. Chapter 12: String Operations
13. Chapter 13: Addressing Modes — Complete Guide
14. Chapter 14: Interrupts & DOS Services (INT 21h)
15. Chapter 15: Shift & Rotate Operations
16. Chapter 16: Complete Programs & Exam Practice
17. Quick Reference Card

Chapter 1: The Foundation — Understanding


the 8086 Processor
What is Assembly Language?
Assembly language is the lowest-level human-readable programming lan-
guage. It maps almost 1:1 to the machine code that the processor actually
executes.
High Level: result = a + b (C, Python, Java)
Assembly: ADD AX, BX (Human-readable processor instructions)
Machine Code: 01 D8 (Binary/Hex the CPU actually runs)

1
Why 8086?
The Intel 8086 is a 16-bit processor. This means: - It processes 16 bits (2
bytes) of data at a time - Its general-purpose registers are 16 bits wide - It
can address up to 1 MB of memory (20-bit address bus) - It has a 16-bit
data bus

Key Specs of the 8086 at a Glance

Feature Value
Data Bus Width 16 bits
Address Bus Width 20 bits
Max Memory 1 MB (2²�)
Number of Registers 14
Instruction Queue 6 bytes
Clock Speed 5-10 MHz

Chapter 2: Registers — The Heart of 8086


Registers are tiny, ultra-fast storage locations inside the CPU. The 8086
has 14 registers, divided into 4 categories.

2.1 General Purpose Registers (4 registers, each 16-bit)


Each can be split into two 8-bit halves:
AX (Accumulator) = AH (high 8 bits) + AL (low 8 bits)
BX (Base) = BH (high 8 bits) + BL (low 8 bits)
CX (Counter) = CH (high 8 bits) + CL (low 8 bits)
DX (Data) = DH (high 8 bits) + DL (low 8 bits)

Visual Breakdown of AX:


AX (16 bits)
�����������������������
� AH (8) � AL (8) �
� Bit15-8 � Bit7-0 �
�����������������������

What Each Register is Primarily Used For:

2
Register Name Primary Use
AX Accumulator Arithmetic, I/O operations, MUL/DIV default
BX Base Base address for memory access, lookup tables
CX Counter Loop counter (LOOP, REP), shift/rotate counts
DX Data I/O port addressing, extends AX in MUL/DIV
(32-bit)

Important: You CAN use any general-purpose register for general


arithmetic, but certain instructions require specific registers (e.g.,
MUL always uses AX).

2.2 Segment Registers (4 registers, each 16-bit)


These define the start of memory segments (we’ll cover segmentation in
Chapter 3):

Register Name Points To


CS Code Segment Where your instructions live
DS Data Segment Where your variables live
SS Stack Segment Where the stack lives
ES Extra Segment Extra data segment (strings)

Rule: You cannot MOV an immediate value directly into a segment


register.
MOV DS, 1234h ; � ILLEGAL
MOV AX, 1234h ; � First load into a GP register
MOV DS, AX ; � Then move to segment register

2.3 Pointer and Index Registers (5 registers, each 16-bit)

Register Name Purpose


SP Stack Pointer Points to the top of the stack
BP Base Pointer Used to access parameters on the stack
SI Source Index Source pointer for string operations
DI Destination Index Destination pointer for string operations
IP Instruction Pointer Points to the NEXT instruction to execute

IP is read-only — you cannot directly modify it with MOV. It


changes via JMP, CALL, RET, and interrupts.

3
2.4 Flags Register (1 register, 16-bit)
The FLAGS register contains individual bits that are set/cleared by operations:
Bit: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- - - - OF DF IF TF SF ZF - AF - PF - CF
The 6 STATUS flags (set automatically by arithmetic/logical operations):

Flag Name Set When (= 1)


CF Carry Unsigned overflow (carry out of MSB)
ZF Zero Result is zero
SF Sign Result is negative (MSB = 1)
OF Overflow Signed overflow occurred
PF Parity Low byte has even number of 1-bits
AF Aux Carry Carry from bit 3 to bit 4 (used in BCD)

The 3 CONTROL flags (set by the programmer):

Flag Name Purpose


DF Direction String operations direction (0=forward, 1=backward)
IF Interrupt Enable/disable hardware interrupts
TF Trap Single-step debugging mode

Chapter 3: Memory Segmentation & Addressing


3.1 The Problem
The 8086 registers are 16-bit, so they can only hold values up to FFFFh (65,535).
But the address bus is 20-bit, meaning it can access up to FFFFFh (1,048,575
= 1 MB).
How do you create a 20-bit address from 16-bit registers?

3.2 The Segment:Offset Solution


The 8086 uses two 16-bit values to compute a 20-bit Physical Address:
Physical Address = (Segment × 16) + Offset
= (Segment × 10h) + Offset
= Segment shifted left 4 bits + Offset

4
Example:
Segment = 1234h
Offset = 0005h

Physical Address = 1234h × 10h + 0005h


= 12340h + 0005h
= 12345h ← This is the 20-bit physical address

Visual:
Segment: 1 2 3 4 0 (shifted left by one hex digit = 4 bits)
+ Offset: 0 0 0 5
= Physical: 1 2 3 4 5

3.3 Default Segment Associations

Operation Default Segment:Offset


Fetching instructions CS:IP
Stack operations (PUSH/POP) SS:SP
General data access DS:BX, DS:SI, DS:DI
String destination ES:DI
BP-based access SS:BP

3.4 Real Mode Memory Map (1 MB)


FFFFFh �������������������������
� BIOS ROM � Top of memory
F0000h ������������������������
� Reserved �
A0000h ������������������������
� Video Memory �
������������������������
� �
� User Programs �
� (Free RAM) �
� �
00500h ������������������������
� BIOS Data Area �
00400h ������������������������
� Interrupt Vector �
� Table (IVT) �
00000h ������������������������

5
Chapter 4: Your First Assembly Program
4.1 Program Structure (Template)
Every 8086 assembly program (for DOS, using MASM/TASM) follows this struc-
ture:
; ============================================
; Program: Description of what this program does
; ============================================

.MODEL SMALL ; Memory model: 1 code segment, 1 data segment


.STACK 100h ; Reserve 256 bytes for the stack

.DATA ; Data segment — declare your variables here


; variables go here

.CODE ; Code segment — your instructions go here


MAIN PROC
; Initialize Data Segment
MOV AX, @DATA ; Load address of data segment into AX
MOV DS, AX ; Set DS to point to our data segment

; =============================
; Your program logic goes here
; =============================

; Terminate program (return to DOS)


MOV AH, 4Ch ; DOS function: terminate program
INT 21h ; Call DOS interrupt

MAIN ENDP ; End of MAIN procedure


END MAIN ; Entry point of the program

4.2 Understanding Each Line

Line What It Does


.MODEL SMALL One code segment + one data segment (good for small
programs)
.STACK 100h Reserves 256 bytes for the stack
.DATA Start of data segment (variables declared here)
.CODE Start of code segment (instructions go here)
MOV AX, @DATA @DATA is the address of the data segment
MOV DS, AX Now DS points to our variables
MOV AH, 4Ch DOS function 4Ch = terminate program

6
Line What It Does
INT 21h Calls DOS to execute function in AH
MAIN ENDP Marks end of MAIN procedure
END MAIN Tells assembler where the program starts

4.3 Declaring Variables in .DATA


DB — Define Byte (1 byte = 8 bits)
.DATA
myChar DB 'A' ; Single character (ASCII 65)
myNum DB 25 ; Decimal number (stored as 19h)
myHex DB 0FFh ; Hex number (prefix 0 if starts with letter)
myMsg DB 'Hello$' ; String ($ terminates for DOS print)
myArray DB 10, 20, 30 ; Array of bytes
buffer DB 50 DUP(0) ; 50 bytes, all initialized to 0
unInit DB ? ; 1 byte, uninitialized

DW — Define Word (2 bytes = 16 bits)


myWord DW 1234h ; 16-bit value
wordArr DW 100, 200, 300; Array of words
bigBuf DW 20 DUP(?) ; 20 words, uninitialized

Important: DUP Directive


DB 10 DUP(0) ; Creates 10 bytes, each = 0
DB 5 DUP('A') ; Creates: 'A', 'A', 'A', 'A', 'A'
DW 10 DUP(?) ; Creates 10 words, uninitialized

4.4 Program — Hello World!


; ============================================
; Program: Print "Hello, World!" to the screen
; ============================================
.MODEL SMALL
.STACK 100h

.DATA
msg DB 'Hello, World!$' ; $ marks end of string for INT 21h/09h

.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX

7
; Print string
LEA DX, msg ; Load Effective Address of msg into DX
MOV AH, 09h ; DOS function 09h = print string
INT 21h ; Call DOS

; Exit
MOV AH, 4Ch
INT 21h
MAIN ENDP
END MAIN
Output:
Hello, World!

Chapter 5: Data Movement — MOV and Friends


5.1 MOV — The Most Used Instruction
Syntax: MOV destination, source
Think of it as: destination ← source (source is copied, NOT moved)

� Valid MOV Combinations:


MOV AX, BX ; Register ← Register
MOV AX, 1234h ; Register ← Immediate (constant)
MOV AX, [myVar] ; Register ← Memory
MOV [myVar], AX ; Memory ← Register
MOV [myVar], 5 ; Memory ← Immediate

� INVALID MOV Operations:


MOV [var1], [var2] ; � Memory ← Memory (NEVER ALLOWED)
MOV CS, AX ; � Cannot MOV into CS
MOV DS, 1234h ; � Cannot MOV immediate into segment register
MOV AH, BX ; � Size mismatch (8-bit ← 16-bit)

Fix for Memory-to-Memory:


; To copy one memory variable to another:
MOV AX, [var1] ; Load var1 into AX
MOV [var2], AX ; Store AX into var2

8
5.2 XCHG — Exchange Values
XCHG AX, BX ; Swap AX and BX (no temp needed!)
XCHG AL, BL ; Swap AL and BL
XCHG AX, [myVar] ; Swap AX with memory variable

5.3 LEA — Load Effective Address


Loads the address of a variable, NOT its value:
LEA BX, myVar ; BX = address of myVar
; Equivalent to:
MOV BX, OFFSET myVar ; Same result

5.4 PUSH and POP


PUSH AX ; Push AX onto stack (SP decreases by 2)
POP BX ; Pop top of stack into BX (SP increases by 2)
Stack is LIFO (Last In, First Out) and grows downward in memory:
; Example:
PUSH AX ; Stack: [AX value]
PUSH BX ; Stack: [AX value] [BX value] ← SP points here
POP CX ; CX = BX value, Stack: [AX value]
POP DX ; DX = AX value, Stack: (empty)

5.5 CBW and CWD — Sign Extension


; CBW: Convert Byte to Word (extends AL into AX)
MOV AL, -5 ; AL = FBh (signed -5)
CBW ; AX = FFFBh (sign-extended to 16 bits)

; CWD: Convert Word to Double-word (extends AX into DX:AX)


MOV AX, -100 ; AX = FF9Ch
CWD ; DX:AX = FFFF:FF9Ch (32-bit signed)

Chapter 6: Arithmetic Operations


6.1 ADD and SUB
ADD AX, BX ; AX = AX + BX
ADD AX, 5 ; AX = AX + 5
ADD AL, [myVar] ; AL = AL + value at myVar

9
SUB AX, BX ; AX = AX - BX
SUB AX, 10 ; AX = AX - 10

Example: Add Two Numbers


.MODEL SMALL
.STACK 100h
.DATA
num1 DB 25
num2 DB 30
result DB ?

.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX

MOV AL, num1 ; AL = 25


ADD AL, num2 ; AL = 25 + 30 = 55
MOV result, AL ; Store result

MOV AH, 4Ch


INT 21h
MAIN ENDP
END MAIN

6.2 ADC and SBB — With Carry/Borrow


Used for multi-precision arithmetic (numbers larger than 16 bits):
; Adding two 32-bit numbers: DX:AX + CX:BX
ADD AX, BX ; Add low 16 bits (may set CF)
ADC DX, CX ; Add high 16 bits + Carry Flag

; Subtracting: DX:AX - CX:BX


SUB AX, BX ; Subtract low 16 bits (may set CF for borrow)
SBB DX, CX ; Subtract high 16 bits - Borrow (CF)

6.3 INC and DEC


INC AX ; AX = AX + 1
INC [myVar] ; myVar = myVar + 1
DEC CX ; CX = CX - 1
Note: INC and DEC do NOT affect the Carry Flag (CF). All other
arithmetic flags are affected.

10
6.4 MUL — Unsigned Multiplication
MUL always uses AX (or AL) as one operand implicitly.
; 8-bit multiplication: AX = AL × operand
MOV AL, 10
MOV BL, 25
MUL BL ; AX = AL × BL = 10 × 25 = 250

; 16-bit multiplication: DX:AX = AX × operand


MOV AX, 1000
MOV BX, 500
MUL BX ; DX:AX = AX × BX = 1000 × 500 = 500000
; Result is 32-bit, stored across DX (high) and AX (low)

MUL Summary Table:

Operand Size Operation Result Stored In


8-bit AL × operand AX
16-bit AX × operand DX:AX

6.5 IMUL — Signed Multiplication


Same as MUL but treats operands as signed numbers:
MOV AL, -5 ; AL = FBh (signed -5)
MOV BL, 3
IMUL BL ; AX = -5 × 3 = -15 (FFF1h)

6.6 DIV — Unsigned Division


DIV also uses AX (or DX:AX) implicitly.
; 8-bit division: AL = AX ÷ operand, AH = remainder
MOV AX, 25
MOV BL, 7
DIV BL ; AL = 25 ÷ 7 = 3 (quotient)
; AH = 25 mod 7 = 4 (remainder)

; 16-bit division: AX = DX:AX ÷ operand, DX = remainder


MOV DX, 0 ; Clear DX (important for 16-bit DIV!)
MOV AX, 1000
MOV BX, 7
DIV BX ; AX = 1000 ÷ 7 = 142 (quotient)
; DX = 1000 mod 7 = 6 (remainder)

11
DIV Summary Table:

Operand Size Dividend Quotient Remainder


8-bit AX AL AH
16-bit DX:AX AX DX

� Common Error: Forgetting to clear DX before 16-bit DIV →


garbage result!

6.7 IDIV — Signed Division


Same as DIV but for signed numbers. Use CWD before IDIV to sign-extend
AX into DX:AX:
MOV AX, -100
CWD ; Sign-extend AX into DX:AX
MOV BX, 7
IDIV BX ; AX = -100 ÷ 7 = -14, DX = -100 mod 7 = -2

6.8 NEG — Negate (Two’s Complement)


MOV AX, 5
NEG AX ; AX = -5 (FFFBh) — flips the sign

6.9 Complete Arithmetic Example — Simple Calculator


; ============================================
; Program: Calculate (A + B) × C - D
; Where A=10, B=20, C=3, D=5
; Expected result: (10 + 20) × 3 - 5 = 85
; ============================================
.MODEL SMALL
.STACK 100h

.DATA
A DW 10
B DW 20
C DW 3
D DW 5
result DW ?

.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX

12
MOV AX, A ; AX = 10
ADD AX, B ; AX = 10 + 20 = 30
MUL C ; DX:AX = 30 × 3 = 90 (DX=0, AX=90)
SUB AX, D ; AX = 90 - 5 = 85
MOV result, AX ; Store result = 85

MOV AH, 4Ch


INT 21h
MAIN ENDP
END MAIN

Chapter 7: Logical & Bitwise Operations


7.1 AND — Bitwise AND
Both bits must be 1 to produce 1:
MOV AL, 0Fh ; AL = 00001111b
AND AL, 3Ch ; AND 00111100b
; = 00001100b = 0Ch
Common Use: Masking (extracting) specific bits, clearing bits.
AND AL, 0Fh ; Keep only the lower 4 bits (lower nibble)
AND AL, 0F0h ; Keep only the upper 4 bits (upper nibble)

7.2 OR ��� Bitwise OR


Either bit being 1 produces 1:
MOV AL, 0Fh ; AL = 00001111b
OR AL, 30h ; OR 00110000b
; = 00111111b = 3Fh
Common Use: Setting specific bits.
OR AL, 01h ; Set bit 0 (make number odd)
OR AL, 20h ; Convert uppercase to lowercase ('A' OR 20h = 'a')

7.3 XOR — Bitwise Exclusive OR


Bits must differ to produce 1:
MOV AL, 0FFh ; AL = 11111111b
XOR AL, 0Fh ; XOR 00001111b
; = 11110000b = F0h
Common Uses:

13
XOR AX, AX ; AX = 0 (fastest way to zero a register!)
XOR AL, 20h ; Toggle case: 'A' � 'a'

7.4 NOT — Bitwise Complement


Flips every bit:
MOV AL, 0Fh ; AL = 00001111b
NOT AL ; AL = 11110000b = F0h
Note: NOT does not affect any flags. AND, OR, XOR do affect
flags (CF=0, OF=0, ZF/SF/PF updated).

7.5 TEST — Non-Destructive AND


Works like AND but doesn’t store the result — only sets flags:
TEST AL, 01h ; Is bit 0 set? (is AL odd?)
JNZ its_odd ; Jump if ZF=0 (bit was set)

TEST AL, 80h ; Is bit 7 set? (is AL negative in signed?)


JNZ its_negative

7.6 CMP — Compare (Non-Destructive SUB)


Works like SUB but doesn’t store the result — only sets flags:
CMP AX, BX ; Compute AX - BX, set flags, discard result
JE equal ; Jump if AX == BX (ZF=1)
JG ax_greater ; Jump if AX > BX (signed)
JA ax_above ; Jump if AX > BX (unsigned)

Chapter 8: Flags Register Deep Dive


Understanding which flags are set and when is critical for exam questions.

8.1 Example — Trace Through Flags


MOV AL, 0FFh ; AL = 255 (unsigned) or -1 (signed)
ADD AL, 01h ; AL = 00h (wraps around)
After this ADD:

Flag Value Why


CF 1 Carry out of bit 7 (255+1 overflows 8 bits)
ZF 1 Result is zero

14
Flag Value Why
SF 0 Bit 7 of result is 0
OF 0 No signed overflow (-1 + 1 = 0, valid)
PF 1 Zero 1-bits in low byte = even count
AF 1 Carry from bit 3 to bit 4

8.2 Another Example


MOV AL, 7Fh ; AL = 127 (max positive signed byte)
ADD AL, 01h ; AL = 80h = 128 unsigned, -128 signed

Flag Value Why


CF 0 No carry out of bit 7 (127+1=128 fits in 8 bits unsigned)
ZF 0 Result � 0
SF 1 Bit 7 = 1
OF 1 Signed overflow! (127+1 = -128 is wrong for signed)
PF 0 Only one 1-bit in low byte (odd count)

Chapter 9: Branching & Conditional Jumps


9.1 Unconditional Jump
JMP label ; Always jump to label

Example:
MOV AX, 5
JMP skip_this
MOV AX, 99 ; This line is NEVER executed
skip_this:
; AX is still 5

9.2 Conditional Jumps (Used After CMP or Arithmetic)


For UNSIGNED comparisons (after CMP A, B):

Instruction Meaning Condition


JE / JZ Jump if Equal / Zero ZF = 1
JNE / JNZ Jump if Not Equal ZF = 0
JA / JNBE Jump if Above CF=0 AND ZF=0
JAE / JNB Jump if Above or Equal CF = 0

15
Instruction Meaning Condition
JB / JNAE Jump if Below CF = 1
JBE / JNA Jump if Below or Equal CF=1 OR ZF=1

For SIGNED comparisons (after CMP A, B):

Instruction Meaning Condition


JE / JZ Jump if Equal ZF = 1
JNE / JNZ Jump if Not Equal ZF = 0
JG / JNLE Jump if Greater ZF=0 AND SF=OF
JGE / JNL Jump if Greater or Equal SF = OF
JL / JNGE Jump if Less SF � OF
JLE / JNG Jump if Less or Equal ZF=1 OR SF�OF

Individual flag checks:

Instruction Meaning Condition


JC Jump if Carry CF = 1
JNC Jump if No Carry CF = 0
JO Jump if Overflow OF = 1
JNO Jump if No Overflow OF = 0
JS Jump if Sign (negative) SF = 1
JNS Jump if No Sign (positive) SF = 0
JP / JPE Jump if Parity Even PF = 1
JNP / JPO Jump if Parity Odd PF = 0

Memory Trick: - Above / Below = Unsigned - Greater / Less =


Signed

9.3 If-Else Structure in Assembly


C Equivalent:
if (ax == bx)
cx = 1;
else
cx = 0;
Assembly:
CMP AX, BX
JE is_equal ; If AX == BX, jump to is_equal
MOV CX, 0 ; ELSE: CX = 0

16
JMP done
is_equal:
MOV CX, 1 ; THEN: CX = 1
done:

9.4 Finding Maximum of Two Numbers


; ============================================
; Program: Find the larger of two numbers
; ============================================
.MODEL SMALL
.STACK 100h
.DATA
num1 DW 45
num2 DW 72
max DW ?

.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX

MOV AX, num1 ; AX = 45


CMP AX, num2 ; Compare 45 with 72
JGE ax_is_max ; If AX >= num2 (signed), AX is max
MOV AX, num2 ; Otherwise, load num2 as max
ax_is_max:
MOV max, AX ; Store the maximum

MOV AH, 4Ch


INT 21h
MAIN ENDP
END MAIN

Chapter 10: Loops


10.1 LOOP Instruction
LOOP automatically uses CX as a counter: 1. Decrements CX by 1 2. If CX � 0,
jumps to the label 3. If CX = 0, falls through
MOV CX, 5 ; Loop 5 times
repeat:
; body of loop (executes 5 times)

17
LOOP repeat ; CX-- ; if CX � 0, goto repeat

Example: Sum Numbers 1 to 10


.MODEL SMALL
.STACK 100h
.DATA
sum DW ?

.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX

MOV AX, 0 ; AX = running sum


MOV CX, 10 ; Loop counter = 10

add_loop:
ADD AX, CX ; Add CX (10, 9, 8, ..., 1) to sum
LOOP add_loop ; CX--, jump if CX � 0

MOV sum, AX ; Store result (sum = 55)

MOV AH, 4Ch


INT 21h
MAIN ENDP
END MAIN
Trace:

Iteration CX (before ADD) AX (after ADD)


1 10 10
2 9 19
3 8 27
4 7 34
5 6 40
6 5 45
7 4 49
8 3 52
9 2 54
10 1 55

10.2 Manual Loops with CMP and JMP


When you need more control (or need CX for something else):

18
; Print 'A' through 'E'
MOV DL, 'A' ; Starting character

print_loop:
MOV AH, 02h ; DOS: print character in DL
INT 21h
INC DL ; Next character
CMP DL, 'F' ; Past 'E'?
JB print_loop ; If DL < 'F', keep going

10.3 Nested Loops


Since LOOP uses CX, you must save CX for outer loops:
MOV CX, 3 ; Outer loop: 3 times
outer:
PUSH CX ; Save outer counter!
MOV CX, 5 ; Inner loop: 5 times
inner:
; inner body
LOOP inner ; Inner CX--, loop
POP CX ; Restore outer counter
LOOP outer ; Outer CX--, loop

10.4 While Loop Pattern


C:
while (ax > 0) {
ax = ax - 3;
}
Assembly:
while_start:
CMP AX, 0
JLE while_end ; If AX <= 0, exit loop
SUB AX, 3
JMP while_start
while_end:

10.5 Do-While Loop Pattern


C:
do {
ax = ax - 3;
} while (ax > 0);

19
Assembly:
do_loop:
SUB AX, 3
CMP AX, 0
JG do_loop ; If AX > 0, repeat

Chapter 11: The Stack & Procedures


11.1 How the Stack Works
The stack grows downward in memory (from high addresses to low):
Memory Address
SS:0100h ������������
� (empty) �
SS:00FEh ������������
� (empty) �
SS:00FCh ������������ ← SP (Stack Pointer) after 2 PUSHes
� Value2 �
SS:00FEh ������������
� Value1 �
SS:0100h ������������ ← SP starts here (bottom of stack)
; PUSH decreases SP by 2, then stores value
PUSH AX ; SP = SP - 2; [SS:SP] = AX

; POP reads value, then increases SP by 2


POP BX ; BX = [SS:SP]; SP = SP + 2

11.2 Procedures (Subroutines/Functions)


Defining and Calling:
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX

CALL myProcedure ; Call the procedure


; Execution continues here after RET

MOV AH, 4Ch


INT 21h
MAIN ENDP

20
; ---- Procedure Definition ----
myProcedure PROC
; Do something here
MOV AX, 5
ADD AX, 3
RET ; Return to caller
myProcedure ENDP
END MAIN

How CALL and RET Work:


CALL myProc:
1. PUSH IP (return address onto stack)
2. IP = address of myProc

RET:
1. POP IP (jump back to instruction after CALL)

11.3 Passing Parameters via Registers


; ============================================
; Program: Procedure to add two numbers
; Parameters passed in AX and BX
; Result returned in AX
; ============================================
.MODEL SMALL
.STACK 100h
.DATA
result DW ?

.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX

MOV AX, 15 ; First parameter


MOV BX, 25 ; Second parameter
CALL AddNums ; Call procedure

MOV result, AX ; AX = 40 (returned by procedure)

MOV AH, 4Ch


INT 21h
MAIN ENDP

AddNums PROC

21
ADD AX, BX ; AX = AX + BX
RET
AddNums ENDP

END MAIN

11.4 Passing Parameters via the Stack


This is the more “formal” way, commonly asked in exams:
; ============================================
; Procedure to add two numbers using stack
; ============================================
.MODEL SMALL
.STACK 100h
.DATA
result DW ?

.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX

; Push parameters (right to left by convention)


PUSH 25 ; Second parameter
PUSH 15 ; First parameter
CALL AddNums ; Pushes return address, then jumps
ADD SP, 4 ; Clean up stack (2 parameters × 2 bytes)
MOV result, AX

MOV AH, 4Ch


INT 21h
MAIN ENDP

AddNums PROC
PUSH BP ; Save old BP
MOV BP, SP ; BP = current stack pointer

; Stack layout at this point:


; [BP+0] = Old BP
; [BP+2] = Return Address
; [BP+4] = First parameter (15)
; [BP+6] = Second parameter (25)

MOV AX, [BP+4] ; AX = first parameter (15)


ADD AX, [BP+6] ; AX = 15 + 25 = 40

22
POP BP ; Restore old BP
RET
AddNums ENDP

END MAIN

Stack Frame Diagram:


High Memory
������������������
� 25 � [BP+6] Second parameter
������������������
� 15 � [BP+4] First parameter
������������������
� Return Address � [BP+2] Pushed by CALL
������������������
� Old BP � [BP+0] Pushed by PUSH BP ← BP points here
������������������ ← SP points here
Low Memory

11.5 Preserving Registers


Convention: If your procedure modifies registers, save and restore them:
MyProc PROC
PUSH AX ; Save registers you will modify
PUSH BX
PUSH CX

; ... procedure body ...

POP CX ; Restore in REVERSE order!


POP BX
POP AX
RET
MyProc ENDP

Chapter 12: String Operations


String operations work on arrays of bytes or words. They use SI (source) and
DI (destination) and auto-increment/decrement based on the Direction Flag
(DF).

23
12.1 Setup Requirements
; Source: DS:SI
; Destination: ES:DI
; Direction: DF=0 (CLD → forward), DF=1 (STD → backward)
; Count: CX (for REP prefix)

CLD ; Clear Direction Flag → process forward (SI++, DI++)


STD ; Set Direction Flag → process backward (SI--, DI--)

12.2 String Instructions

Instruction Operation Size


MOVSB Move byte: [ES:DI] ← [DS:SI], advance SI & DI Byte
MOVSW Move word: [ES:DI] ← [DS:SI], advance SI & DI Word
LODSB Load byte: AL ← [DS:SI], advance SI Byte
LODSW Load word: AX ← [DS:SI], advance SI Word
STOSB Store byte: [ES:DI] ← AL, advance DI Byte
STOSW Store word: [ES:DI] ← AX, advance DI Word
CMPSB Compare byte: [DS:SI] vs [ES:DI], set flags Byte
SCASB Scan byte: AL vs [ES:DI], set flags Byte

12.3 REP Prefix


Repeats the string instruction CX times:

Prefix Meaning
REP Repeat CX times
REPE/REPZ Repeat while equal (ZF=1), max CX
REPNE/REPNZ Repeat while not equal (ZF=0)

Example: Copy a String


.MODEL SMALL
.STACK 100h
.DATA
source DB 'Hello, World!', 0
dest DB 14 DUP(0)

.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV ES, AX ; ES = DS (same segment)

24
CLD ; Forward direction
LEA SI, source ; SI → source string
LEA DI, dest ; DI → destination
MOV CX, 14 ; 14 bytes to copy (13 chars + null)
REP MOVSB ; Copy CX bytes from DS:SI to ES:DI

MOV AH, 4Ch


INT 21h
MAIN ENDP
END MAIN

Example: Fill Array with a Value


CLD
LEA DI, buffer ; DI → destination buffer
MOV AL, 0 ; Value to fill
MOV CX, 100 ; Fill 100 bytes
REP STOSB ; [ES:DI] ← AL, CX times

Chapter 13: Addressing Modes — Complete


Guide
Addressing modes define HOW the operand of an instruction is specified.

13.1 All Addressing Modes


1. Immediate Addressing
The operand is a constant value in the instruction itself:
MOV AX, 1234h ; 1234h is the immediate operand
ADD BL, 05h
MOV CL, 'A'

2. Register Addressing
The operand is a register:
MOV AX, BX ; Both operands are registers
ADD AL, BL
INC CX

3. Direct Addressing
The operand is at a fixed memory address:

25
MOV AX, [1234h] ; Load from memory address DS:1234h
MOV AX, myVar ; Load from the address of myVar
MOV [myVar], BX ; Store BX at the address of myVar

4. Register Indirect Addressing


The address is in a register (BX, SI, DI, or BP):
MOV BX, OFFSET myVar ; BX = address of myVar
MOV AX, [BX] ; AX = value at address in BX
MOV [SI], CX ; Store CX at address in SI

5. Based Addressing (Register + Displacement)


Base register (BX or BP) + constant offset:
MOV AX, [BX+4] ; AX = value at DS:(BX+4)
MOV AX, [BP+6] ; AX = value at SS:(BP+6) ← Note: BP uses SS!

6. Indexed Addressing (Index Register + Displacement)


Index register (SI or DI) + constant offset:
MOV AX, [SI+2] ; AX = value at DS:(SI+2)
MOV AX, [DI+4] ; AX = value at DS:(DI+4)

7. Based Indexed Addressing (Base + Index)


Combines a base register with an index register:
MOV AX, [BX+SI] ; AX = value at DS:(BX+SI)
MOV AX, [BX+DI] ; AX = value at DS:(BX+DI)
MOV AX, [BP+SI] ; AX = value at SS:(BP+SI)

8. Based Indexed with Displacement


Base + Index + Constant:
MOV AX, [BX+SI+2] ; AX = value at DS:(BX+SI+2)
MOV AX, [BP+DI+4] ; AX = value at SS:(BP+DI+4)

13.2 Valid Base and Index Combinations


Only these register combinations are valid for memory addressing:

Base Register Index Register Default Segment


BX SI DS
BX DI DS
BP SI SS

26
Base Register Index Register Default Segment
BP DI SS
BX (none) DS
BP (none) SS
(none) SI DS
(none) DI DS

� You CANNOT use AX, CX, DX, SP as base/index registers for


addressing!
MOV AX, [CX] ; � INVALID
MOV AX, [AX+BX] ; � INVALID
MOV AX, [SP+2] ; � INVALID

13.3 Addressing Mode Quick Reference Diagram


Addressing Mode Example Effective Address
�������������������������������������������������������������������������
Immediate MOV AX, 5 (value is 5)
Register MOV AX, BX (value is in BX)
Direct MOV AX, [1234h] DS:1234h
Register Indirect MOV AX, [BX] DS:BX
Based MOV AX, [BX+4] DS:(BX+4)
Indexed MOV AX, [SI+4] DS:(SI+4)
Based Indexed MOV AX, [BX+SI] DS:(BX+SI)
Based Indexed + Displacement MOV AX, [BX+SI+4] DS:(BX+SI+4)

Chapter 14: Interrupts & DOS Services (INT


21h)
14.1 What is an Interrupt?
An interrupt is a signal that pauses the CPU’s current work to execute a
special routine called an Interrupt Service Routine (ISR). INT is a software
interrupt.
INT 21h ; Call DOS interrupt (function number in AH)
INT 10h ; Call BIOS video interrupt

27
14.2 Essential INT 21h Functions
Display a Single Character (AH = 02h)
MOV AH, 02h
MOV DL, 'A' ; Character to display
INT 21h ; Output: A

Display a String (AH = 09h)


.DATA
msg DB 'Hello, World!$' ; Must end with '$'

.CODE
LEA DX, msg ; DX → address of string
MOV AH, 09h
INT 21h ; Output: Hello, World!

Read a Single Character with Echo (AH = 01h)


MOV AH, 01h
INT 21h ; Wait for key press
; AL = ASCII code of key pressed (character is also echoed to screen)

Read a Single Character without Echo (AH = 08h)


MOV AH, 08h
INT 21h ; Wait for key press (no echo)
; AL = ASCII code of key pressed

Read a String (Buffered Input) (AH = 0Ah)


.DATA
buffer DB 50 ; Max characters to read (including Enter)
DB ? ; Actual characters read (filled by DOS)
DB 50 DUP('$') ; Buffer space

.CODE
LEA DX, buffer
MOV AH, 0Ah
INT 21h ; Reads a line of input
; buffer+1 = number of characters typed
; buffer+2 onward = the actual characters

Terminate Program (AH = 4Ch)


MOV AH, 4Ch
MOV AL, 00h ; Return code (0 = success)

28
INT 21h

14.3 Printing a New Line


; Newline = Carriage Return (0Dh) + Line Feed (0Ah)
MOV AH, 02h
MOV DL, 0Dh ; Carriage Return
INT 21h
MOV DL, 0Ah ; Line Feed
INT 21h
Or define it in data:
.DATA
newline DB 0Dh, 0Ah, '$'

.CODE
LEA DX, newline
MOV AH, 09h
INT 21h

14.4 ASCII Table Reference (Most Common)

Char ASCII (Hex) ASCII (Dec)


‘0’ 30h 48
‘9’ 39h 57
‘A’ 41h 65
‘Z’ 5Ah 90
‘a’ 61h 97
‘z’ 7Ah 122
Space 20h 32
Enter 0Dh 13
Newline 0Ah 10

Key relationships:
'A' to 'a' difference = 20h (32 decimal)
'0' to integer: subtract 30h (48 decimal)
integer to '0': add 30h

29
Chapter 15: Shift & Rotate Operations
15.1 Shift Operations
SHL / SAL — Shift Left (Logical / Arithmetic — same operation)
Before: 1 0 1 1 0 1 1 0
SHL 1: 0 1 1 0 1 1 0 0 ← 0 fills from right, MSB goes to CF
SHL AX, 1 ; Shift AX left by 1 (multiply by 2)
MOV CL, 3
SHL AX, CL ; Shift AX left by 3 (multiply by 8)
SHL by 1 = × 2, SHL by N = × 2�

SHR — Shift Right (Logical — unsigned)


Before: 1 0 1 1 0 1 1 0
SHR 1: 0 1 0 1 1 0 1 1 ← 0 fills from left, LSB goes to CF
SHR AX, 1 ; Unsigned divide by 2
MOV CL, 2
SHR AX, CL ; Unsigned divide by 4

SAR — Shift Right (Arithmetic — signed, preserves sign bit)


Before: 1 0 1 1 0 1 1 0 (negative number, MSB=1)
SAR 1: 1 1 0 1 1 0 1 1 ← Sign bit (1) fills from left
SAR AX, 1 ; Signed divide by 2 (preserves sign)

15.2 Rotate Operations


ROL — Rotate Left
Before: 1 0 1 1 0 1 1 0
ROL 1: 0 1 1 0 1 1 0 1 ← MSB wraps around to LSB and CF
CF = 1
ROL AX, 1 ; Rotate left by 1

ROR — Rotate Right


Before: 1 0 1 1 0 1 1 0
ROR 1: 0 1 0 1 1 0 1 1 ← LSB wraps around to MSB and CF
CF = 0

RCL — Rotate Left through Carry


Includes CF as part of the rotation:

30
CF=0, AL = 1 0 1 1 0 1 1 0
RCL 1:
CF=1, AL = 0 1 1 0 1 1 0 0 ← MSB→CF, old CF→LSB

RCR — Rotate Right through Carry


CF=0, AL = 1 0 1 1 0 1 1 0
RCR 1:
CF=0, AL = 0 1 0 1 1 0 1 1 ← LSB→CF, old CF→MSB

15.3 Shift/Rotate Summary Table

Instruction Direction Fill Bit Use Case


SHL/SAL Left 0 Multiply by 2�
SHR Right 0 Unsigned divide by 2�
SAR Right Sign bit Signed divide by 2�
ROL Left Wraps MSB Bit manipulation
ROR Right Wraps LSB Bit manipulation
RCL Left CF→LSB Multi-word shifts
RCR Right CF→MSB Multi-word shifts

8086 Rule: You can only shift/rotate by 1 or by CL. You cannot


use an immediate value greater than 1.
SHL AX, 1 ; � OK
MOV CL, 4
SHL AX, CL ; � OK
SHL AX, 4 ; � ILLEGAL on 8086 (works on 80186+)

Chapter 16: Complete Programs & Exam Prac-


tice
Program 1: Read a Character and Display It
; Read a character and display it back with a message
.MODEL SMALL
.STACK 100h
.DATA
prompt DB 'Enter a character: $'
msg1 DB 0Dh, 0Ah, 'You entered: $'

.CODE
MAIN PROC

31
MOV AX, @DATA
MOV DS, AX

; Print prompt
LEA DX, prompt
MOV AH, 09h
INT 21h

; Read character
MOV AH, 01h
INT 21h ; AL = character entered
MOV BL, AL ; Save character in BL

; Print message
LEA DX, msg1
MOV AH, 09h
INT 21h

; Display the character


MOV DL, BL
MOV AH, 02h
INT 21h

; Exit
MOV AH, 4Ch
INT 21h
MAIN ENDP
END MAIN

Program 2: Check if a Character is Uppercase or Lowercase


.MODEL SMALL
.STACK 100h
.DATA
prompt DB 'Enter a letter: $'
upper DB 0Dh, 0Ah, 'It is UPPERCASE$'
lower DB 0Dh, 0Ah, 'It is lowercase$'
invalid DB 0Dh, 0Ah, 'Not a letter!$'

.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX

LEA DX, prompt


MOV AH, 09h

32
INT 21h

MOV AH, 01h


INT 21h ; AL = input character

; Check if uppercase (A-Z: 41h to 5Ah)


CMP AL, 'A'
JB not_letter
CMP AL, 'Z'
JBE is_upper

; Check if lowercase (a-z: 61h to 7Ah)


CMP AL, 'a'
JB not_letter
CMP AL, 'z'
JBE is_lower

JMP not_letter

is_upper:
LEA DX, upper
JMP print_result

is_lower:
LEA DX, lower
JMP print_result

not_letter:
LEA DX, invalid

print_result:
MOV AH, 09h
INT 21h

MOV AH, 4Ch


INT 21h
MAIN ENDP
END MAIN

Program 3: Convert Lowercase to Uppercase


“‘asm .MODEL SMALL .STACK 100h .DATA prompt DB ‘Enter a lowercase
letter: $’ result DB 0Dh, 0Ah, ‘Uppercase: $’
.CODE MAIN PROC MOV AX, @DATA MOV DS, AX
LEA D

33

You might also like