DIM name AS typeDIM name(subscripts) AS typeDIM name(subscripts) AS type AT address
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.
| Parameter | Description |
|---|---|
name | The identifier name of the variable or array. |
AS type | The data type. Supports all standard types and user-defined TYPEs. |
subscripts | Optional. Array dimensions using the format (lower TO upper, ...). If parenthesized but empty (), declares a dynamic array that can be sized later with REDIM. |
AT address | Optional. 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. |
' 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
; 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
; 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)
; 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
DIM declared at module level (outside all procedures) creates a variable with global visibility.DIM declared inside a procedure creates a variable with local scope, equivalent to LOCAL.AT clause is an advanced feature. Incorrect addresses can cause access violations, data corruption, or system instability. Always validate addresses before use.DIM name() must be sized with REDIM before any element access.LOCAL for procedure-level variables, GLOBAL for module-level variables, and reserve DIM for arrays and AT-addressed memory.#REGISTER directive. Register variable assignment is handled automatically by the optimizer.