8 - Arrays and Structures
8 - Arrays and Structures
1
Readings and Exercises
• P & H: Section 2.14
2
Objectives
At the end of this section, You will be able to:
1. Define and work with one-dimensional arrays
2. Define and work with multi-dimensional arrays
3. Define and work with structures
4. Define and work with nested structures
3
ARRAYS
4
One-Dimensional Arrays
• Store consecutive array elements of the same type
in a contiguous block of memory
▪ Block size = number of elements × element size
▪ Address of element i is:
• Base address + (i × element size)
▪ Eg: int ia[5]; ia + 0 ia[0]
ia + 4 ia[1]
ia + 8 ia[2] 20 bytes
ia + 12 ia[3]
ia + 16 ia[4]
5
One-Dimensional Arrays (cont’d)
• Like other local variables, an array is allocated in
the function’s stack frame
▪ Eg: C code
int main()
{
int a, b, ia[5];
. . .
}
6
One-Dimensional Arrays (cont’d)
• Assembly code:
a_size = 4
b_size = 4
ia_size = 5 * 4
alloc = -(16 + a_size + b_size + ia_size) & -16
dealloc = -alloc
a_s = 16
b_s = 20
ia_s = 24
. . .
main: stp x29, x30, [sp, alloc]!
mov x29, sp
. . .
ldp x29, x30, [sp], dealloc
ret
7
One-Dimensional Arrays (cont’d)
• Memory is used as follows:
free
memory
SP FP
Frame record
fp + a_s a
fp + b_s b
fp + ia_s + 0 ia[0]
Stack frame for main
fp + ia_s + 4 ia[1]
fp + ia_s + 8 ia[2]
fp + ia_s + 12 ia[3]
fp + ia_s + 16 ia[4]
pad bytes
8
One-Dimensional Arrays (cont’d)
▪ Array elements are accessed using load and store
instructions
• Eg: ia[2] = 13;
define(ia_base_r, x19)
define(index_r, x20)
define(offset_r, x21)
. . .
add ia_base_r, x29, ia_s // Calculate array base address
mov index_r, 2 // Set index to 2
lsl offset_r, index_r, 2 // offset = i * element size
mov w22, 13
str w22, [ia_base_r, offset_r] // ia[2] = 13
9
One-Dimensional Arrays (cont’d)
• Can be optimized by doing the LSL in the STR instruction:
. . .
mov index_r, 2 // Set index to 2
mov w22, 13
str w22, [ia_base_r, index_r, LSL 2] // ia[2] = 13
. . .
10
11
Two-Dimentional Arrays
• Two-dimensional arrays must be mapped onto 1D
memory
▪ Can use row-major ordering
• Store each element of row 0, then row 1, etc.
• Used in most high-level languages, including C, C++
▪ Or column-major ordering
• Store each element of column 0, then column 1, etc.
• Used by FORTRAN
11
12
Example
• Logical arrangement:
10 20 30
40 50 60
12
13
Indexing 2D Arrays
▪ The indices for a multidimensional array must be
converted into an offset
• Added to array starting address
13
14
Indexing 2D Arrays
• Example C Code declaration of
char array[2][3]
array[1][2] maps to an offset of
(3 * 1 + 2) * 1 = 5
((m * i) + j) Esize
Indexing 2D Arrays
• Example Java Code declaration of
char[2][3] array
array[1][2] maps to an offset of
(3 * 1 + 2) * 2 = 10
((m * i) + j) Esize
Effective Addresses
• A 1D array cell is accessed by:
• base + offset
• base is the starting address of the array
• offset = (cell number) * (cell size in bytes)
16
17
Examples
int myArray[5] = {10, 20, 30, 40, 50}
17
18
Examples
long myArray[5] = {10, 20, 30, 40, 50}
18
Multidimensional Arrays
• Use 2 or more indices to access individual array
elements
• Eg: int ia[2][3];
Address Memory
ia + 0 ia[0][0]
ia + 4 ia[0][1]
ia + 8 ia[0][2] 24 byte block
ia + 12 ia[1][0]
ia + 16 ia[1][1]
ia + 20 ia[1][2]
19
Multidimensional Arrays (cont’d)
• The block size for an n-dimensional array is:
n
Õdim r ´ elementsize
r=1
20
Multidimensional Arrays (cont’d)
• The offset for a given element is:
n-1 n
(å[indexr ´ Õdim r ] + indexn )´ elementsize
r=1 r+1
21
Multidimensional Arrays (cont’d)
▪ Eg: a 3-dimensional array would be declared with:
type array[dim1][dim2][dim3];
• Its offset for element array[index1][index2][index3] is:
[[index1 × dim2 × dim3] + [index2 × dim3] + index3] × element size
22
Multidimensional Arrays (cont’d)
• Eg: C code
int main()
{
int ia[2][3];
register int i, j;
. . .
ia[i][j] = 13;
. . .
}
23
Multidimensional Arrays (cont’d)
▪ Assembly code: int ia[2][3];
define(ia_base_r, x19)
define(offset_r, w20)
define(i_r, w21)
define(j_r, w22)
dim1 = 2
dim2 = 3
ia_size = dim1 * dim2 * 4
alloc = -(16 + ia_size) & -16
dealloc = -alloc
ia_s = 16
. . .
main: stp x29, x30, [sp, alloc]!
mov x29, sp
. . .
24
Multidimensional Arrays (cont’d)
. . .
add ia_base_r, x29, ia_s // Calculate array base address
mov w24, 13
str w24, [ia_base_r, offset_r, SXTW] // ia[i][j] = 13
. . .
25
STRUCTURES
26
Structures
• Contain fields, which may be of different types
• Are allocated in a single block of memory on the
stack
▪ Fields are accessed using offsets
• Eg: struct rec {
int a;
char b;
short c;
};
27
Structures (cont’d)
Memory Offset
a rec_a = 0
b rec_b = 4
c rec_c = 5
28
Structures (cont’d)
• Eg: C code:
struct rec {
int a;
char b; defines a custom data type
short c;
};
int main()
{
struct rec s1; allocates memory
. . .
s1.a = 42;
s1.b = 23;
s1.c = 13;
. . .
}
29
Structures (cont’d)
▪ Assembly code:
define(s1_base_r, x19)
rec_a = 0
rec_b = 4
rec_c = 5
s1_size = 7
alloc = -(16 + s1_size) & -16
dealloc = -alloc
s1_s = 16
. . .
main: stp x29, x30, [sp, alloc]!
mov x29, sp
. . .
30
Structures (cont’d)
. . .
add s1_base_r, x29, s1_s // Calculate struct base address
mov w20, 42
str w20, [s1_base_r, rec_a] // s1.a = 42
mov w20, 23
strb w20, [s1_base_r, rec_b] // s1.b = 23
mov w20, 13
strh w20, [s1_base_r, rec_c] // s1.c = 13
. . .
31
Nested Structures
• A structure may contain a field whose type is
another structure
▪ The field’s subfields are accessed using a 2nd set of
offsets
• Eg: C code
struct date {
unsigned char day, month;
unsigned short year;
};
struct employee {
int id;
struct date start; nested struct
};
32
Nested Structures (cont’d)
int main()
{
struct employee joe;
. . .
joe.id = 4001;
joe.start.day = 1;
joe.start.month = 6;
joe.start.year = 1999;
. . .
}
33
Nested Structures (cont’d)
▪ Assembly code:
define(joe_base_r, x19)
date_day = 0
date_month = 1
date_year = 2
employee_id = 0
employee_start = 4
joe_size = 8
alloc = -(16 + joe_size) & -16
dealloc = -alloc
joe_s = 16
. . .
main: stp x29, x30, [sp, alloc]!
mov x29, sp
. . .
34
Nested Structures (cont’d)
. . .
add joe_base_r, x29, joe_s // Calculate struct base address
mov w20, 1
strb w20, [joe_base_r, employee_start + date_day] // joe.start.day = 1
mov w20, 6
strb w20, [joe_base_r, employee_start + date_month] // joe.start.month = 6
. . .
35