An array is a run of bytes or words in memory, one after another. To reach element i, the CPU adds an offset to the array's start. The ways an operand can be named are the addressing modes:
| Mode | Example | The operand is |
|---|---|---|
| immediate | MOV AL, 5 | the number itself |
| register | MOV AL, BL | a register |
| direct | MOV AL, LIST | the memory at LIST |
| register indirect | MOV AL, [BX] | the memory at the address in BX (or SI, DI) |
| based | MOV AL, [BX + 2] | at BX + 2 |
| indexed | MOV AL, LIST[SI] | at LIST + SI |
| based-indexed | MOV AL, [BX + SI] | at BX + SI (plus a number, if given) |
Inside the brackets the 8086 accepts only BX or BP (a base) and SI or DI (an index), added together with a number. [AX], [CX] and [BX + BP] are not allowed, and StepVioz says so. BP is special: [BP] reads the stack segment, as lesson 12 uses.
Walking an array
To visit every element, keep its index in SI (or its address in BX) and count with CX:
; Add up a byte array and print the sum.
.MODEL SMALL
.STACK 100H
.DATA
LIST DB 12, 7, 30, 5, 21
N EQU 5
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV AL, 0 ; the sum
MOV SI, 0 ; the index
MOV CX, N
ADDUP:
ADD AL, LIST[SI] ; indexed: LIST + SI
INC SI
LOOP ADDUP
AAM ; 75 -> AH = 7, AL = 5
MOV BX, AX
MOV DL, BH
ADD DL, '0'
MOV AH, 2
INT 21H
MOV DL, BL
ADD DL, '0'
INT 21H
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAINThe sum here is below 100, so AAM can print it in two digits.
Word arrays
A word is 2 bytes, so element i of a DW array is at offset 2 × i: add 2 to SI each time, not 1.
; Find the largest value in a word array and print it.
.MODEL SMALL
.STACK 100H
.DATA
NUMS DW 320, 1450, 98, 1203
N EQU 4
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV AX, NUMS ; the largest so far: the first element
MOV SI, 2 ; words: the next element is 2 bytes on
MOV CX, N - 1
FIND:
CMP AX, NUMS[SI]
JAE KEEP ; unsigned: AX is already as large
MOV AX, NUMS[SI]
KEEP:
ADD SI, 2
LOOP FIND
MOV BX, 10 ; print AX in decimal
MOV CX, 0
DIGITS:
MOV DX, 0
DIV BX
PUSH DX
INC CX
CMP AX, 0
JNE DIGITS
SHOWIT:
POP DX
ADD DL, '0'
MOV AH, 2
INT 21H
LOOP SHOWIT
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAINMOV AX, NUMS reads the first element; CMP AX, NUMS[SI] compares with element SI ÷ 2. The answer, the largest value, is printed with the divide-by-10 method from lesson 8.
Common mistakes
- Stepping through a word array by 1: element i is at 2 × i.
- Using
[AX]or[CX]: only BX, BP, SI and DI can point into memory. - Reading one element too many: with n elements and CX = n, start at index 0, not 1.
- Using
MOV SI, LIST(the first element's value) when you meantLEA SI, LIST(its address).
Quick check
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.