0% found this document useful (0 votes)
17 views35 pages

8 - Arrays and Structures

Uploaded by

ranbir singh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views35 pages

8 - Arrays and Structures

Uploaded by

ranbir singh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 35

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

• If index is a w register, one must sign extend first:


define(index_r, w20)

. . .

str w22, [ia_base_r, index_r, SXTW 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

• Mapping in row-major order:


10 20 30 40 50 60

• Mapping in column-major order:


10 40 20 50 30 60

12
13

Indexing 2D Arrays
▪ The indices for a multidimensional array must be
converted into an offset
• Added to array starting address

▪ For a 2D array list[1..n][1..m], row-major order,


list[i][j] is:
((m * i) + j)  Esize
▪ Esize is the element (cell) size in bytes

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

0,0 0,1 0,2 0 1 2


1,0 1,1 1,2 3 4 5

Logical view Physical view


14
15

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

0,0 0,1 0,2 0 2 4


1,0 1,1 1,2 6 8 10

Logical view Physical view


15
16

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}

• Cell containing 10 has address


▪ myArray + 0*4
• Cell containing 20 has address
▪ myArray + 1*4
• Cell containing 30 has address
▪ myArray + 2*4

17
18

Examples
long myArray[5] = {10, 20, 30, 40, 50}

• Cell containing 10 has address


▪ myArray + 0*8
• Cell containing 20 has address
▪ myArray + 1*8
• Cell containing 30 has address
▪ myArray + 2*8

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

where dimr is the number of elements in dimension r


▪ Eg: int ia[2][3][3];
block size = (2 × 3 × 3) × 4 = 72 bytes

20
Multidimensional Arrays (cont’d)
• The offset for a given element is:
n-1 n
(å[indexr ´ Õdim r ] + indexn )´ elementsize
r=1 r+1

where indexr is the index for the element in


dimension r

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

• If the array is declared as:


int ia[2][3][4];
its offset for ia[i][j][k] would be:
[[i × 3 × 4] + [j × 4] + k] × 4

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 w23, dim2


mul offset_r, i_r, w23 // offset = i * dim2
add offset_r, offset_r, j_r // offset = (i * dim2) + j
lsl offset_r, offset_r, 2 // offset = ((i * dim2) + j) * 4

mov w24, 13
str w24, [ia_base_r, offset_r, SXTW] // ia[i][j] = 13
. . .

Note: can be optimized by doing LSL in STR instruction

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

▪ If the base address is in x19, then fields are accessed


with:
ldr w20, [x19, rec_a]
ldrsb w21, [x19, rec_b]
ldrsh w22, [x19, rec_c]

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;
. . .
}

Offset Nested Offset Memory


0 4001 joe.id
4 0 1 joe.start.day
1 6 joe.start.month nested struct
2 1999 joe.start.year

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, 4001


str w20, [joe_base_r, employee_id] // joe.id = 4001

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

mov w20, 1999


strh w20, [joe_base_r, employee_start + date_year] // joe.start.year = 1999

. . .

assembler evaluates the expression,


producing a constant

35

You might also like