Arrays, Tables, and Block Operations
Organize data into arrays and tables, then process them efficiently with index registers
Open interactive version (quiz + challenge)Real-world analogy
What is it?
Arrays in 8086 assembly are contiguous blocks of memory defined with DB or DW, accessed via index registers (SI, DI) and base+offset addressing. Lookup tables provide O(1) precomputed results using XLAT or indexed access. Block operations copy, search, or transform arrays element by element. These data structures and operations are the assembly-level foundation of every high-level array, list, and table.
Real-world relevance
Arrays and lookup tables are everywhere in embedded systems. A keyboard controller uses a lookup table to convert scan codes to ASCII characters. Display drivers store font bitmaps as 2D arrays. Sensor systems accumulate readings into arrays and compute averages. Sorting arrays of measurements enables finding medians for noise rejection.
Key points
- Defining Arrays with DB and DW — Arrays are simply consecutive memory locations defined with DB (byte array) or DW (word array). The label marks the starting address. Element spacing is 1 byte for DB or 2 bytes for DW. Access the Nth element at label + N*element_size.
- Traversing Arrays with SI — Use SI (Source Index) to walk through an array. Load the array's offset into SI with LEA, access the current element with [SI], then increment SI by the element size (1 for bytes, 2 for words) to move to the next.
- Word Array Traversal — For word arrays, each element is 2 bytes. Increment SI by 2 to move between elements. You can also use ADD SI, 2 or INC SI twice. When accessing with MOV AX, [SI], the processor reads 2 bytes.
- Indexed Addressing for Arrays — Use base+index addressing: [BX+SI], [BX+DI], or direct offset [array+SI]. This is how you access array[i] — the base address plus the index. BX often holds the base, SI or DI holds the index.
- Lookup Tables — A lookup table stores precomputed results. Instead of calculating f(x), you access table[x] directly. This trades memory for speed — one memory read replaces a complex computation. Perfect for character conversions, trigonometry approximations, and display encoding.
- XLAT — Table Lookup Instruction — XLAT replaces AL with the byte at DS:[BX+AL]. Set BX to the table base address and AL to the index, then XLAT does the lookup in a single instruction. Only works for byte tables with indices 0-255.
- Block Copy with Index Registers — To copy one array to another, use SI for the source and DI for the destination. Increment both after each copy. This is the manual version of REP MOVSB, useful when you need to transform data during the copy.
- Finding Min/Max in an Array — Initialize the result with the first element. Loop through the rest, comparing each element with the current min/max. Update when a smaller/larger value is found. This is a fundamental algorithm implemented at the lowest level.
- 2D Arrays (Matrices) — A 2D array is stored as consecutive rows in memory. To access element [row][col] in a matrix with C columns, calculate offset = row * C + col. Multiply the row index by the number of columns, then add the column index.
- Sorting an Array — Bubble Sort — Bubble sort repeatedly walks through the array, swapping adjacent elements if they are out of order. The outer loop repeats until no swaps occur. Simple to implement in assembly: compare, conditional jump, XCHG or manual swap.
Code example
; Program: Reverse an array and find its maximum element
.MODEL SMALL
.STACK 100h
.DATA
arr DB 34, 12, 78, 45, 23, 67, 89, 11, 56
arr_len EQU 9
rev_arr DB arr_len DUP(?)
max_val DB ?
msg1 DB 'Max value: $'
msg2 DB 0Dh, 0Ah, 'Reversed: $'
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
; --- Find maximum ---
LEA SI, arr
MOV AL, [SI] ; max = first element
MOV CX, arr_len - 1
INC SI
find_max:
CMP AL, [SI]
JAE not_bigger
MOV AL, [SI] ; update max
not_bigger:
INC SI
LOOP find_max
MOV [max_val], AL ; store max (89)
; --- Reverse array ---
LEA SI, arr ; SI = start of source
LEA DI, rev_arr
ADD DI, arr_len - 1 ; DI = end of reversed
MOV CX, arr_len
reverse_loop:
MOV AL, [SI]
MOV [DI], AL
INC SI
DEC DI
LOOP reverse_loop
; --- Display max ---
MOV AH, 09h
LEA DX, msg1
INT 21h
MOV AL, [max_val]
CALL print_num
; --- Display reversed array ---
MOV AH, 09h
LEA DX, msg2
INT 21h
LEA SI, rev_arr
MOV CX, arr_len
show_loop:
MOV AL, [SI]
CALL print_num
MOV DL, ' '
MOV AH, 02h
INT 21h ; space separator
INC SI
LOOP show_loop
MOV AH, 4Ch
INT 21h
MAIN ENDP
; Print AL as decimal number (0-255)
print_num PROC NEAR
XOR AH, AH
MOV BL, 100
DIV BL ; AL = hundreds, AH = remainder
CMP AL, 0
JE skip_hundreds
ADD AL, 30h
MOV DL, AL
PUSH AX
MOV AH, 02h
INT 21h
POP AX
skip_hundreds:
MOV AL, AH ; remainder
XOR AH, AH
MOV BL, 10
DIV BL ; AL = tens, AH = ones
CMP AL, 0
JE skip_tens
ADD AL, 30h
MOV DL, AL
PUSH AX
MOV AH, 02h
INT 21h
POP AX
skip_tens:
MOV AL, AH
ADD AL, 30h
MOV DL, AL
MOV AH, 02h
INT 21h
RET
print_num ENDP
END MAINLine-by-line walkthrough
- 1. arr DB 34, 12, 78, ... — define 9 bytes in consecutive memory. The label 'arr' marks the starting offset
- 2. arr_len EQU 9 — constant for array length, used everywhere to avoid magic numbers
- 3. Find max loop: initialize AL with the first element, then compare with each remaining element using JAE to skip if current max is already >= element
- 4. Reverse loop: SI starts at the beginning of arr, DI starts at the end of rev_arr. Copy [SI] to [DI], then SI moves forward while DI moves backward
- 5. ADD DI, arr_len - 1 — positions DI at the last byte of rev_arr (offset 8 from start for a 9-element array)
- 6. print_num divides by 100 to get the hundreds digit, then by 10 to get the tens digit, and the ones are what remains
- 7. Each digit is converted to ASCII by adding 30h and printed with DOS function 02h
- 8. skip_hundreds / skip_tens — suppress leading zeros by checking if the digit is 0 before printing
Spot the bug
LEA SI, word_arr
MOV CX, 5
XOR AX, AX
add_loop:
ADD AX, [SI]
INC SI
LOOP add_loopNeed a hint?
Show answer
Explain like I'm 5
Fun fact
Hands-on challenge
More resources
- Arrays in 8086 Assembly (GeeksforGeeks)
- XLAT Instruction (x86 Reference)
- Array Operations in Assembly (YouTube)
- Bubble Sort in 8086 Assembly (GeeksforGeeks)