DIM Declaration

Syntax:
DIM name AS type
DIM name(subscripts) AS type
DIM name(subscripts) AS type AT address

Description

The DIM statement declares variables and arrays with flexible scope and storage options. Unlike LOCAL, STATIC, and GLOBAL, the DIM statement can appear both inside procedures (where it behaves like LOCAL) and at module level (where it behaves like GLOBAL).

The primary distinguishing feature of DIM is its ability to allocate arrays at fixed absolute memory addresses using the AT clause. This is essential for memory-mapped I/O, direct hardware access, and interfacing with external data structures at known addresses.

DIM also supports dynamic array resizing via REDIM, though the initial declaration uses DIM with empty parentheses.

Parameters

ParameterDescription
nameThe identifier name of the variable or array.
AS typeThe data type. Supports all standard types and user-defined TYPEs.
subscriptsOptional. Array dimensions using the format (lower TO upper, ...). If parenthesized but empty (), declares a dynamic array that can be sized later with REDIM.
AT addressOptional. Specifies an absolute memory address where the variable or array is mapped. The address must be a numeric expression evaluating to a valid memory address. Use with extreme caution.

Example

' Module-level DIM (acts like GLOBAL)
DIM g_SharedBuffer(0 TO 255) AS BYTE

' Procedure-level DIM (acts like LOCAL)
FUNCTION ProcessData() AS LONG
    DIM tempArray(1 TO 100) AS DOUBLE
    DIM dynamicArray() AS STRING   ' Dynamic, sized later

    ' Fill and resize
    REDIM dynamicArray(1 TO 50) AS STRING
    dynamicArray(1) = "First entry"

    tempArray(1) = 3.14159
    g_SharedBuffer(0) = &HFF

    FUNCTION = 0
END FUNCTION

' Absolute addressing (advanced)
' DIM videoMem(0 TO 3999) AS BYTE AT &HB8000

Generated Assembly

Stack Local Array Allocation

; Allocate space on the stack (e.g., 100 * 8 bytes for DOUBLE)
; Space is reserved in the function prologue:
sub    rsp, frame_size                ; includes array space

; Zero-initialize array (optional, depending on compiler flags)
mov    rcx, 800                       ; byte count
xor    rdx, rdx
lea    r8, [rbp - array_offset]
mov    [rsp + 32], 0                  ; shadow space
call   [__imp_RtlZeroMemory]          ; or memset

Array Element Access

; Calculate address of element i:
mov    rax, [rbp - i_offset]          ; load index i
sub    rax, 1                         ; adjust for 1-based index
imul   rax, 8                         ; multiply by element size (8 for DOUBLE)
lea    r10, [rbp - array_offset + rax] ; r10 = address of array(i)

; Read element:
movsd  xmm0, [r10]                    ; load DOUBLE into XMM0

; Write element:
movsd  [r10], xmm0                    ; store XMM0 into array(i)

AT Address (Fixed Memory Mapping)

; No stack allocation is performed.
; Access uses the absolute address directly:
lea    r10, [&H100000 + rax]          ; r10 = address of mapped array(i)
mov    [r10], rdx                     ; store value at fixed address

Notes