The number of elements in an array equals the number of rows, R, times the number of columns, C. In C, arrays begin with an index of 0, thus the declaration:
char A_2D[R,C];
creates an array containing R*C elements. The index of the last row is R-1 and the index of the last column is C-1.
If the row and column indices do not begin at zero, as in the Pascal declaration:
A_2D: array[first_row .. last_row, first_col .. last_col] of char;
then the number of elements in the array is given by:
number_of_elements = ( last_row - first_row + 1) (last_col - first_col + 1).
A two-dimensional array in SAL is declared as:
A_2D: <type> initial_value:number_of_elements
where <type> is either .byte or .word. If the size of the array elements is not a byte or a word, then the array size is:
array_size = ( number_of_elements ) ( size_of_element ),
where size_of_element is 1 for a byte array and 4 for an integer array. An equivalent SAL declaration for the array is:
A_2D: .space <array_size>
In this declaration, <array_size> must be an integer constant.
The memory arrays m[] and M[] are one-dimensional. A two-dimensional array is an array of one-dimensional arrays. In row-major order, a two-dimensional array is stored as an array of rows in the memory array. The ordering of the elements for a 3 x 4 array is shown below:
In the Pascal and C programming languages, arrays are stored in row-major order. In FORTRAN, arrays are stored in column-major order as an array of columns. The ordering of the elements for the same 3 x 4 array in column-major order is shown below:
Whether an array is stored in row-major or column-major order depends on the implementation chosen by the compiler or the assembly language programmer.
The address of an element in a 2D array stored in row-major (column-major) order is computed by skipping entire rows (columns) to reach the address of the desired row (column) and then computing the address of the desired element in the row (column).
For a byte array in row-major order, element A_2D[r,c] is given by
Consider the 3 x 4 C array declared as:
char A_2D[3,4];
The number of elements in the array is:
number_of_elements = (2 - 0 + 1) (3 - 0 + 1) = 12
A SAL declaration for the array is:
A_2D: .byte 0:12
or
A_2D: .space 12
The address of element [1,3] is calculated using row-major ordering:
In a row-major array with elements of size size_of_element, element A_2D[r,c] is given by:
For column-major order, the row and column terms in the formula are reversed:
Consider a 10 x 10 integer array declared in C as:
int A_2D[10,10];
A SAL declaration for this array is:
A_2D: .word 0:100 # 100 element integer array
or
A_2D: .space 400 # 100 element integer array
The first declaration initializes all the array elements to 0, as shown below:
The following code changes the elements in the third column to 1's, as shown below:
# # SAL code to initialize a 10 x 10 integer array to 0, # except the third column, which is set to 1's. # Array is stored in row-major order. # .data A_2D: .word 0:100 # 100 element integer array C: .word # column index R: .word # row index Base: .word # base address of array I: .word # address of element [R,C] NRows: .word 10 # number of elements in a column NCols: .word 10 # number of elements in a row Size: .word 4 # size of the elements .text __start: move R, 0 # initialize row index move C, 2 # initialize column index la Base, A_2D # load base address of array Loop: beq R, NRows, Next # if R > NRows, done mul I, R, NCols # skip R rows add I, I, C # skip C columns mul I, I, Size # multiply by element size add I, I, Base # add base address to element address move M[I], 1 # A_2D[R,C] := 1 add R, R, 1 # increment row index b Loop Next: # more code goes here
Note that the difference between the addresses of elements [r+1,c] and [r,c] is given by:
When performing array operations down a column (row), a more efficient address computation is to simply increment the array index by the number of elements in a row (column) times the size of the elements.