Assembly Language - Arrays

An array is a collection of data of the same type stored contiguously. In assembly, an array is a contiguous block of memory, and each element is accessed using a base address plus an offset.


One-Dimensional Array Definition

Example

; Ways to define an array

section .data
    ; Method 1: List elements one by one
    arr1 dd 10, 20, 30, 40, 50  ; An array of 5 doubleword elements

    ; Method 2: Initialize with dup
    arr2 dd 10 dup(0)            ; 10 doublewords, all 0

    ; Method 3: Byte array
    bytes db 1, 2, 3, 4, 5, 6   ; 6 bytes

    ; Method 4: Character array (string)
    chars db 'example', 0         ; 7 bytes

    ; Array length calculation (at compile time)
    arr1_len equ ($ - arr1) / 4  ; Number of elements in a doubleword array
    arr2_len equ ($ - arr2) / 4
    bytes_len equ ($ - bytes)    ; Byte array, no division needed

section .bss
    ; Uninitialized array
    buffer resd 100              ; Reserve space for 100 doublewords

Array Element Access

Accessing array elements uses thebase + index × element sizeaddressing mode:

Example

; File path: array_access.asm
; Reading and writing array elements

section .data
    nums dd 100, 200, 300, 400, 500   ; 5 elements
    nums_len equ ($ - nums) / 4

section .text
    global _start

_start:
    ; Access the 0th element (index 0)
    mov eax, [nums]              ; eax = 100

    ; Access the 2nd element (index 2)
    mov eax, [nums + 2 * 4]      ; eax = nums[2] = 300
    ; 2 * 4 = 8, so offset 8 bytes from nums

    ; Use a register as the index
    mov esi, 3                   ; Index = 3
    mov eax, [nums + esi * 4]    ; eax = nums[3] = 400

    ; Modify array elements
    mov dword [nums + 4], 250    ; nums[1] = 250
    ; The array now contains: 100, 250, 300, 400, 500

    ; Use EBX as the base register
    mov ebx, nums                ; ebx = array base address
    mov eax, [ebx + 4 * 4]       ; eax = nums[4] = 500

    mov eax, 1
    mov ebx, 0
    int 0x80

Note:[nums + esi * 4]The multiplication by 4 is because each element is 4 bytes (doubleword). For a byte array (db), write it directly as[arr + esi]; for a word array (dw), write it as[arr + esi * 2]。


Array Traversal

Example

; File path: array_traverse.asm
; Traverse the array and calculate the sum

section .data
    numbers dd 5, 10, 15, 20, 25, 30, 35, 40, 45, 50
    count equ ($ - numbers) / 4   ; Number of elements

section .text
    global _start

_start:
    mov ecx, count                ; Loop count
    mov esi, 0                    ; Index (starting from 0)
    mov eax, 0                    ; Accumulated sum

sum_loop:
    add eax, [numbers + esi * 4]  ; Accumulate array elements
    inc esi                       ; Index + 1
    loop sum_loop
    ; eax = 5+10+15+...+50 = 275

    ; Another traversal method: using a pointer
    mov ecx, count
    mov ebx, numbers              ; ebx points to the start of the array
    mov eax, 0                    ; Accumulated sum

sum_loop2:
    add eax, [ebx]                ; Accumulate the current element
    add ebx, 4                    ; Move the pointer to the next element
    loop sum_loop2
    ; eax = 275

    mov ebx, eax                  ; Exit code = accumulated sum
    mov eax, 1
    int 0x80

Array Search

Example

; File path: array_search.asm
; Search for a specified value in the array

section .data
    data dd 12, 45, 67, 23, 89, 34, 56, 78, 90, 11
    data_len equ ($ - data) / 4
    target dd 23                   ; The value to search for
    found_msg db 'Found at index: ', 0
    found_len equ $ - found_msg
    notfound_msg db 'Not found (example)', 0xA
    notfound_len equ $ - notfound_msg
    newline db 0xA

section .text
    global _start

_start:
    mov ecx, data_len             ; Loop count
    mov esi, 0                    ; Current index

search_loop:
    mov eax, [data + esi * 4]     ; Load the current element
    cmp eax, [target]             ; Whether it equals the target value
    je  found                     ; Found

    inc esi                       ; Index + 1
    loop search_loop

    ; Not found
    mov eax, 4
    mov ebx, 1
    mov ecx, notfound_msg
    mov edx, notfound_len
    int 0x80
    jmp exit

found:
    ; Found (esi is the index)
    mov eax, 4
    mov ebx, 1
    mov ecx, found_msg
    mov edx, found_len
    int 0x80

    ; Convert the index to an ASCII character and output it
    add esi, '0'                  ; Convert a single-digit index to a character
    push esi                      ; Push onto the stack for temporary storage
    mov eax, 4
    mov ebx, 1
    mov ecx, esp                  ; Top-of-stack address
    mov edx, 1
    int 0x80
    pop esi

    ; Output a newline
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80

exit:
    mov eax, 1
    mov ebx, 0
    int 0x80

Two-Dimensional Array

A two-dimensional array is expanded row by row into one-dimensional storage in memory. The address formula for accessingarr[i][j]is:

地址 = 基址 + (i*列数 + j) * 元素大小

Example

; File path: 2d_array.asm
= 10 (row 3, column 2)

section .data
   
    matrix dd 1,  2,  3,  4
           dd 5,  6,  7,  8
           dd 9, 10, 11, 12

    rows equ 3
    cols equ 4
    elem_size equ 4              ; DWORD = 4 bytes

section .text
    global _start

_start:
    ; Access matrix
    ; Address = matrix + (1*4 + 2) * 4 = matrix + 24

    mov eax, [matrix + (1 * cols + 2) * elem_size]
    ; eax = 7

    ; Dynamic calculation using registers (assume i=2, j=1)
    ; matrix
    mov esi, 2                   ; Row i = 2
    mov edi, 1                   ; Column j = 1

    mov eax, cols                ; Number of columns
    mul esi                      ; eax = i * cols = 2*4 = 8
    add eax, edi                 ; eax = i*cols + j = 8+1 = 9
    ; eax = eax * elem_size
    ; Note: The result of MUL is in EAX, use it directly here
    mov eax, [matrix + eax * elem_size]
    ; eax = 10

    ; Traverse all elements of a 2D array
    mov ecx, rows * cols         ; Total number of elements = 12
    mov esi, 0                   ; Index
    mov ebx, 0                   ; Accumulated sum

traverse:
    add ebx, [matrix + esi * elem_size]
    inc esi
    loop traverse
    ; ebx = 1+2+3+...+12 = 78

    mov eax, 1
    int 0x80

Complete Bubble Sort Example

Example

; File path: bubble_sort.asm
; Bubble sort algorithm

section .data
    array dd 64, 34, 25, 12, 22, 11, 90, 78
    array_len equ ($ - array) / 4

section .text
    global _start

_start:
    mov ecx, array_len            ; Outer loop: n times
    dec ecx                       ; Outer loop only needs n-1 times

outer_loop:
    push ecx                      ; Save outer loop counter

    mov esi, 0                    ; Inner loop index starts from 0
    mov ecx, array_len - 1        ; Number of inner loop iterations

inner_loop:
    mov eax, [array + esi * 4]    ; a[j]
    mov ebx, [array + esi * 4 + 4]  ; a[j+1]
    cmp eax, ebx                  ; a[j] > a[j+1] ?
    jle no_swap                   ; No, do not swap

    ; Swap a[j] and a[j+1]
    mov [array + esi * 4], ebx
    mov [array + esi * 4 + 4], eax

no_swap:
    inc esi
    loop inner_loop

    pop ecx
    loop outer_loop
    ; Array is now sorted: 11, 12, 22, 25, 34, 64, 78, 90

    mov eax, 1
    mov ebx, 0
    int 0x80

Arrays in assembly language have no boundary checking. Accessing an out-of-bounds index will not raise an error; instead it silently reads or writes data in adjacent memory, which can lead to bugs that are hard to debug. Be sure to ensure the index is within valid bounds yourself.

Other extensions