Basic Programming Examples
Example 1: Simple Arithmetic Operations
Problem: Write a program to add two 16-bit numbers and store the result.
.MODEL SMALL
.DATA
NUM1 DW 1234H ; First number
NUM2 DW 5678H ; Second number
RESULT DW ? ; Storage for result
.CODE
MAIN PROC
MOV AX, @DATA ; Initialize data segment
MOV DS, AX
MOV AX, NUM1 ; Load first number
ADD AX, NUM2 ; Add second number
MOV RESULT, AX ; Store result
; Display result (optional)
MOV AH, 4CH ; DOS exit function
INT 21H ; Exit to DOS
MAIN ENDP
END MAIN
; Result: RESULT = 1234H + 5678H = 68ACH
Example 2: Subtraction with Borrow
Problem: Subtract two 16-bit numbers and handle borrow flag.
.MODEL SMALL
.DATA
MINUEND DW 8000H ; Number to subtract from
SUBTRAHEND DW 3000H ; Number to subtract
DIFFERENCE DW ? ; Result storage
BORROW_FLAG DB ? ; Borrow indicator
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV AX, MINUEND ; Load minuend
SUB AX, SUBTRAHEND ; Subtract subtrahend
MOV DIFFERENCE, AX ; Store difference
JNC NO_BORROW ; Jump if no borrow (CF=0)
MOV BORROW_FLAG, 1 ; Set borrow flag
JMP DONE
NO_BORROW:
MOV BORROW_FLAG, 0 ; Clear borrow flag
DONE:
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result: 8000H - 3000H = 5000H, no borrow
Example 3: Multiplication and Division
Problem: Multiply two 8-bit numbers and divide the result by a third number.
.MODEL SMALL
.DATA
NUM1 DB 15 ; Multiplicand
NUM2 DB 12 ; Multiplier
DIVISOR DB 4 ; Divisor
QUOTIENT DB ? ; Division result
REMAINDER DB ? ; Division remainder
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
; Multiplication: 15 × 12
MOV AL, NUM1 ; Load first number
MUL NUM2 ; Multiply (result in AX)
; Division: (15 × 12) ÷ 4
MOV BL, DIVISOR ; Load divisor
DIV BL ; Divide AX by BL
MOV QUOTIENT, AL ; Store quotient
MOV REMAINDER, AH ; Store remainder
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Calculation: 15 × 12 = 180, 180 ÷ 4 = 45 remainder 0
Array and String Operations
Example 4: Array Sum Calculation
Problem: Calculate the sum of elements in an array.
.MODEL SMALL
.DATA
ARRAY DW 10, 20, 30, 40, 50 ; Array of 5 elements
COUNT EQU 5 ; Number of elements
SUM DW ? ; Storage for sum
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
LEA SI, ARRAY ; Load array address
MOV CX, COUNT ; Load counter
XOR AX, AX ; Clear accumulator
SUM_LOOP:
ADD AX, [SI] ; Add current element
ADD SI, 2 ; Move to next element (word size)
LOOP SUM_LOOP ; Repeat for all elements
MOV SUM, AX ; Store final sum
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result: SUM = 10 + 20 + 30 + 40 + 50 = 150 (96H)
Example 5: String Length Calculation
Problem: Find the length of a null-terminated string.
.MODEL SMALL
.DATA
MESSAGE DB 'Hello World', 0 ; Null-terminated string
LENGTH DB ? ; Storage for length
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
LEA SI, MESSAGE ; Load string address
XOR BX, BX ; Clear length counter
LENGTH_LOOP:
MOV AL, [SI] ; Load current character
CMP AL, 0 ; Check for null terminator
JE DONE ; Exit if null found
INC BX ; Increment counter
INC SI ; Move to next character
JMP LENGTH_LOOP ; Continue loop
DONE:
MOV LENGTH, BL ; Store string length
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result: LENGTH = 11 (length of "Hello World")
Example 6: String Reversal
Problem: Reverse a string in place.
.MODEL SMALL
.DATA
STRING DB 'PROGRAM', 0 ; String to reverse
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
; Find string length first
LEA SI, STRING ; Start pointer
LEA DI, STRING ; End pointer (will be adjusted)
FIND_END:
CMP BYTE PTR [DI], 0 ; Check for null
JE FOUND_END
INC DI
JMP FIND_END
FOUND_END:
DEC DI ; Point to last character
REVERSE_LOOP:
CMP SI, DI ; Check if pointers crossed
JAE DONE ; Exit if start >= end
; Swap characters
MOV AL, [SI] ; Load start character
MOV BL, [DI] ; Load end character
MOV [SI], BL ; Store end at start
MOV [DI], AL ; Store start at end
INC SI ; Move start forward
DEC DI ; Move end backward
JMP REVERSE_LOOP
DONE:
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result: STRING becomes "MARGORP"
Sorting Algorithms
Example 7: Bubble Sort
Problem: Sort an array using bubble sort algorithm.
.MODEL SMALL
.DATA
ARRAY DW 64, 34, 25, 12, 22, 11, 90 ; Unsorted array
COUNT EQU 7 ; Number of elements
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV CX, COUNT ; Outer loop counter
DEC CX ; n-1 passes needed
OUTER_LOOP:
PUSH CX ; Save outer counter
LEA SI, ARRAY ; Reset array pointer
MOV CX, COUNT ; Inner loop counter
DEC CX ; n-1 comparisons
INNER_LOOP:
MOV AX, [SI] ; Load current element
CMP AX, [SI+2] ; Compare with next
JLE NO_SWAP ; Skip if in order
; Swap elements
MOV BX, [SI+2] ; Load next element
MOV [SI], BX ; Store at current
MOV [SI+2], AX ; Store current at next
NO_SWAP:
ADD SI, 2 ; Move to next element
LOOP INNER_LOOP
POP CX ; Restore outer counter
LOOP OUTER_LOOP
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result: Array sorted as [11, 12, 22, 25, 34, 64, 90]
Example 8: Linear Search
Problem: Search for a specific value in an array.
.MODEL SMALL
.DATA
ARRAY DW 10, 25, 30, 45, 50, 65, 80 ; Sorted array
COUNT EQU 7 ; Number of elements
SEARCH_VALUE DW 30 ; Value to find
FOUND_INDEX DW -1 ; Result (-1 = not found)
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
LEA SI, ARRAY ; Load array address
MOV CX, COUNT ; Load counter
MOV AX, SEARCH_VALUE; Load search value
XOR BX, BX ; Clear index counter
SEARCH_LOOP:
CMP AX, [SI] ; Compare with current element
JE FOUND ; Jump if found
ADD SI, 2 ; Move to next element
INC BX ; Increment index
LOOP SEARCH_LOOP ; Continue search
; Not found
MOV FOUND_INDEX, -1
JMP DONE
FOUND:
MOV FOUND_INDEX, BX ; Store found index
DONE:
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result: FOUND_INDEX = 2 (value 30 found at index 2)
Mathematical Functions
Example 9: Factorial Calculation
Problem: Calculate factorial using iterative method.
.MODEL SMALL
.DATA
NUMBER DB 5 ; Calculate 5!
RESULT DW ? ; Storage for result
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV AL, NUMBER ; Load number
CMP AL, 0 ; Check for 0!
JE ZERO_FACTORIAL
CMP AL, 1 ; Check for 1!
JE ONE_FACTORIAL
; Calculate factorial iteratively
MOV BL, AL ; Copy number to BL
DEC AL ; Start from n-1
MOV AH, 0 ; Clear high byte
FACTORIAL_LOOP:
MUL BL ; Multiply AX by BL
DEC BL ; Decrement multiplier
CMP BL, 1 ; Check if done
JNE FACTORIAL_LOOP
MOV RESULT, AX ; Store result
JMP DONE
ZERO_FACTORIAL:
ONE_FACTORIAL:
MOV RESULT, 1 ; 0! = 1! = 1
DONE:
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result: 5! = 5 × 4 × 3 × 2 × 1 = 120 (78H)
Example 10: Prime Number Check
Problem: Check if a number is prime.
.MODEL SMALL
.DATA
NUMBER DW 17 ; Number to check
IS_PRIME DB ? ; Result: 1=prime, 0=not prime
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV AX, NUMBER ; Load number
CMP AX, 2 ; Check if less than 2
JB NOT_PRIME ; Numbers < 2 are not prime
CMP AX, 2 ; Check if equal to 2
JE PRIME ; 2 is prime
; Check for even numbers > 2
TEST AX, 1 ; Check if even
JZ NOT_PRIME ; Even numbers > 2 are not prime
; Check odd divisors from 3 to sqrt(n)
MOV BX, 3 ; Start checking from 3
CHECK_LOOP:
MOV DX, 0 ; Clear high word for division
DIV BX ; Divide NUMBER by BX
CMP DX, 0 ; Check remainder
JE NOT_PRIME ; If remainder = 0, not prime
; Restore AX for next iteration
MOV AX, NUMBER
; Check if BX > sqrt(NUMBER)
MOV CX, BX
MUL CX ; BX² in AX
CMP AX, NUMBER ; Compare BX² with NUMBER
JA PRIME ; If BX² > NUMBER, it's prime
ADD BX, 2 ; Check next odd number
MOV AX, NUMBER ; Restore NUMBER
JMP CHECK_LOOP
PRIME:
MOV IS_PRIME, 1 ; Set prime flag
JMP DONE
NOT_PRIME:
MOV IS_PRIME, 0 ; Clear prime flag
DONE:
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result: IS_PRIME = 1 (17 is prime)
Advanced Programming Examples
Example 11: Matrix Operations
Problem: Add two 3×3 matrices.
.MODEL SMALL
.DATA
MATRIX1 DW 1, 2, 3, 4, 5, 6, 7, 8, 9 ; First 3x3 matrix
MATRIX2 DW 9, 8, 7, 6, 5, 4, 3, 2, 1 ; Second 3x3 matrix
RESULT DW 9 DUP(?) ; Result matrix
ROWS EQU 3 ; Number of rows
COLS EQU 3 ; Number of columns
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
LEA SI, MATRIX1 ; Point to first matrix
LEA DI, MATRIX2 ; Point to second matrix
LEA BX, RESULT ; Point to result matrix
MOV CX, ROWS * COLS ; Total elements
ADD_LOOP:
MOV AX, [SI] ; Load element from matrix1
ADD AX, [DI] ; Add element from matrix2
MOV [BX], AX ; Store in result matrix
ADD SI, 2 ; Move to next element
ADD DI, 2
ADD BX, 2
LOOP ADD_LOOP ; Repeat for all elements
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result matrix: [10, 10, 10, 10, 10, 10, 10, 10, 10]
Example 12: Binary to BCD Conversion
Problem: Convert a binary number to BCD format.
.MODEL SMALL
.DATA
BINARY_NUM DW 1234 ; Binary number to convert
BCD_RESULT DW ? ; BCD result storage
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV AX, BINARY_NUM ; Load binary number
XOR BX, BX ; Clear BCD result
MOV CX, 4 ; Number of BCD digits
CONVERT_LOOP:
XOR DX, DX ; Clear high word
MOV SI, 10 ; Divide by 10
DIV SI ; AX = quotient, DX = remainder
; Shift BCD result left by 4 bits
SHL BX, 4
; Add current digit to BCD result
OR BL, DL ; Add remainder as BCD digit
CMP AX, 0 ; Check if done
JE DONE
LOOP CONVERT_LOOP
DONE:
MOV BCD_RESULT, BX ; Store BCD result
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result: 1234 decimal = 1234H BCD
Example 13: Text Encryption (Caesar Cipher)
Problem: Encrypt text using Caesar cipher with shift of 3.
.MODEL SMALL
.DATA
PLAINTEXT DB 'HELLO WORLD', 0 ; Text to encrypt
CIPHERTEXT DB 20 DUP(?) ; Encrypted text storage
SHIFT EQU 3 ; Caesar cipher shift
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
LEA SI, PLAINTEXT ; Source pointer
LEA DI, CIPHERTEXT ; Destination pointer
ENCRYPT_LOOP:
MOV AL, [SI] ; Load current character
CMP AL, 0 ; Check for null terminator
JE DONE
; Check if it's a letter
CMP AL, 'A'
JB COPY_AS_IS ; Not a letter
CMP AL, 'Z'
JA CHECK_LOWERCASE
; Uppercase letter
SUB AL, 'A' ; Convert to 0-25
ADD AL, SHIFT ; Apply shift
CMP AL, 26 ; Check wraparound
JB NO_WRAP_UPPER
SUB AL, 26 ; Wrap around
NO_WRAP_UPPER:
ADD AL, 'A' ; Convert back to ASCII
JMP STORE_CHAR
CHECK_LOWERCASE:
CMP AL, 'a'
JB COPY_AS_IS
CMP AL, 'z'
JA COPY_AS_IS
; Lowercase letter
SUB AL, 'a' ; Convert to 0-25
ADD AL, SHIFT ; Apply shift
CMP AL, 26 ; Check wraparound
JB NO_WRAP_LOWER
SUB AL, 26 ; Wrap around
NO_WRAP_LOWER:
ADD AL, 'a' ; Convert back to ASCII
JMP STORE_CHAR
COPY_AS_IS:
; Not a letter, copy as is
STORE_CHAR:
MOV [DI], AL ; Store encrypted character
INC SI ; Move to next source
INC DI ; Move to next destination
JMP ENCRYPT_LOOP
DONE:
MOV BYTE PTR [DI], 0 ; Null terminate
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
; Result: "HELLO WORLD" becomes "KHOOR ZRUOG"
I/O and System Programming
Example 14: Simple Calculator
Problem: Create a simple calculator for basic operations.
.MODEL SMALL
.DATA
MSG1 DB 'Enter first number: $'
MSG2 DB 'Enter operator (+,-,*,/): $'
MSG3 DB 'Enter second number: $'
MSG4 DB 'Result: $'
NEWLINE DB 13, 10, '$'
NUM1 DW ?
NUM2 DW ?
OPERATOR DB ?
RESULT DW ?
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
; Get first number
LEA DX, MSG1
MOV AH, 09H
INT 21H
CALL INPUT_NUMBER
MOV NUM1, AX
; Print newline
LEA DX, NEWLINE
MOV AH, 09H
INT 21H
; Get operator
LEA DX, MSG2
MOV AH, 09H
INT 21H
MOV AH, 01H ; Read character
INT 21H
MOV OPERATOR, AL
; Print newline
LEA DX, NEWLINE
MOV AH, 09H
INT 21H
; Get second number
LEA DX, MSG3
MOV AH, 09H
INT 21H
CALL INPUT_NUMBER
MOV NUM2, AX
; Print newline
LEA DX, NEWLINE
MOV AH, 09H
INT 21H
; Perform calculation
MOV AX, NUM1
MOV BX, NUM2
MOV CL, OPERATOR
CMP CL, '+'
JE ADD_OP
CMP CL, '-'
JE SUB_OP
CMP CL, '*'
JE MUL_OP
CMP CL, '/'
JE DIV_OP
JMP DONE
ADD_OP:
ADD AX, BX
JMP STORE_RESULT
SUB_OP:
SUB AX, BX
JMP STORE_RESULT
MUL_OP:
MUL BX
JMP STORE_RESULT
DIV_OP:
XOR DX, DX ; Clear high word
DIV BX
STORE_RESULT:
MOV RESULT, AX
; Display result
LEA DX, MSG4
MOV AH, 09H
INT 21H
MOV AX, RESULT
CALL DISPLAY_NUMBER
DONE:
MOV AH, 4CH
INT 21H
MAIN ENDP
; Procedure to input a number
INPUT_NUMBER PROC
XOR AX, AX ; Clear result
XOR BX, BX ; Clear digit
INPUT_LOOP:
MOV AH, 01H ; Read character
INT 21H
CMP AL, 13 ; Check for Enter
JE INPUT_DONE
SUB AL, '0' ; Convert to digit
MOV BL, AL
MOV CX, 10
MUL CX ; Multiply previous result by 10
ADD AX, BX ; Add new digit
JMP INPUT_LOOP
INPUT_DONE:
RET
INPUT_NUMBER ENDP
; Procedure to display a number
DISPLAY_NUMBER PROC
; Convert number to string and display
; (Implementation details omitted for brevity)
RET
DISPLAY_NUMBER ENDP
END MAIN
Performance Analysis and Optimization
Example 15: Optimized Loop Implementation
Problem: Compare different loop implementations for performance.
; Method 1: Standard LOOP instruction
STANDARD_LOOP PROC
MOV CX, 1000 ; 1000 iterations
LOOP1:
; Process data here
NOP ; Placeholder operation
LOOP LOOP1 ; 17 cycles per iteration
RET
STANDARD_LOOP ENDP
; Method 2: DEC/JNZ implementation
OPTIMIZED_LOOP PROC
MOV CX, 1000 ; 1000 iterations
LOOP2:
; Process data here
NOP ; Placeholder operation
DEC CX ; 2 cycles
JNZ LOOP2 ; 16/4 cycles (taken/not taken)
RET
OPTIMIZED_LOOP ENDP
; Method 3: Unrolled loop
UNROLLED_LOOP PROC
MOV CX, 250 ; 250 iterations (4x unroll)
LOOP3:
; Process 4 items per iteration
NOP ; Item 1
NOP ; Item 2
NOP ; Item 3
NOP ; Item 4
DEC CX
JNZ LOOP3
RET
UNROLLED_LOOP ENDP
; Performance Analysis:
; Standard: 1000 × 17 = 17,000 cycles
; Optimized: 1000 × 18 = 18,000 cycles (slightly slower)
; Unrolled: 250 × 22 = 5,500 cycles (3x faster)
Example 16: Memory Access Optimization
Problem: Optimize array processing for better cache performance.
; Inefficient: Column-major access (poor cache locality)
PROCESS_MATRIX_BAD PROC
MOV SI, 0 ; Column index
COL_LOOP:
MOV DI, 0 ; Row index
ROW_LOOP:
; Calculate address: row*cols + col
MOV AX, DI ; Row
MOV BX, 3 ; Columns per row
MUL BX ; Row * columns
ADD AX, SI ; Add column
SHL AX, 1 ; Word addressing
; Process element at MATRIX[AX]
MOV BX, AX
INC WORD PTR MATRIX[BX]
INC DI
CMP DI, 3 ; 3 rows
JB ROW_LOOP
INC SI
CMP SI, 3 ; 3 columns
JB COL_LOOP
RET
PROCESS_MATRIX_BAD ENDP
; Efficient: Row-major access (good cache locality)
PROCESS_MATRIX_GOOD PROC
MOV DI, 0 ; Row index
ROW_LOOP2:
MOV SI, 0 ; Column index
COL_LOOP2:
; Calculate address: row*cols + col
MOV AX, DI ; Row
MOV BX, 3 ; Columns per row
MUL BX ; Row * columns
ADD AX, SI ; Add column
SHL AX, 1 ; Word addressing
; Process element at MATRIX[AX]
MOV BX, AX
INC WORD PTR MATRIX[BX]
INC SI
CMP SI, 3 ; 3 columns
JB COL_LOOP2
INC DI
CMP DI, 3 ; 3 rows
JB ROW_LOOP2
RET
PROCESS_MATRIX_GOOD ENDP
; Row-major access is more efficient due to spatial locality
Programming Best Practices
1. Code Organization
; Good structure example
.MODEL SMALL
.DATA
; Define all data here
; Group related data together
; Use meaningful names
.CODE
MAIN PROC
; Initialize segments
; Call procedures
; Clean exit
MAIN ENDP
; Procedure definitions
PROCEDURE1 PROC
; Clear purpose
; Proper parameter handling
; Error checking
PROCEDURE1 ENDP
END MAIN
2. Error Handling
SAFE_DIVIDE PROC
; Input: AX = dividend, BX = divisor
; Output: AX = quotient, DX = remainder
; Returns: CF = 1 if error (division by zero)
CMP BX, 0 ; Check for division by zero
JE DIVISION_ERROR
XOR DX, DX ; Clear high word
DIV BX ; Perform division
CLC ; Clear carry (no error)
RET
DIVISION_ERROR:
STC ; Set carry (error)
RET
SAFE_DIVIDE ENDP
3. Documentation Standards
;****************************************************
; Procedure: BUBBLE_SORT
; Purpose: Sort array in ascending order
; Input: SI = array address, CX = array size
; Output: Array sorted in place
; Registers used: AX, BX, CX, DX, SI
; Algorithm: Bubble sort with early termination
;****************************************************
BUBBLE_SORT PROC
; Implementation here
BUBBLE_SORT ENDP
4. Performance Considerations
- Use registers: Faster than memory access
- Minimize jumps: Reduce pipeline stalls
- Optimize loops: Unroll when beneficial
- Choose instructions: Use faster alternatives
- Memory layout: Consider data locality