Computer Organization and Assembly Language: Lecture-8-Machine Level Programming-Array Allocation and Access
Computer Organization and Assembly Language: Lecture-8-Machine Level Programming-Array Allocation and Access
Computer Organization and Assembly Language: Lecture-8-Machine Level Programming-Array Allocation and Access
ORGANIZATION AND
ASSEMBLY LANGUAGE
LECTURE-8-MACHINE LEVEL
PROGRAMMING-ARRAY ALLOCATION
AND ACCESS
MUHAMMAD HAFEEZ
DEPARTMENT OF COMPUTER SCIENCE
GC UNIVERSITY LAHORE
Arrays
Arrays in C are one means of aggregating scalar
data into larger data types. C uses a particularly
simple implementation of arrays, and hence the
translation into machine code is fairly
straightforward. One unusual feature of C is that
we can generate pointers to elements within
arrays and perform arithmetic with these
pointers. These are translated into address
computations in machine code.
Optimizing compilers are particularly good at
simplifying the address computations used by
array indexing. This can make the correspondence
between the C code and its translation into
machine code somewhat difficult to decipher.
Arrays
For data type T and integer constant N, the
declaration
T A[N];
has two effects.
First, it allocates a contiguous region of L.N bytes
in memory, where L is the size (in bytes) of data
type T. Let us denote the starting location as xA
Second, it introduces an identifier A that can be
used as a pointer to the beginning of the array.
The value of this pointer will be xA
Arrays
The array elements can be accessed using an
integer index ranging between 0 and N−1.
Array element i will be stored at address
xA+L.i
Arrays
char A[12];
char *B[8];
double C[6];
double *D[5];
Array
Array A consists of 12 single-byte (char)
elements.
Array C consists of six double-precision floating-
point values, each requiring 8 bytes.
B and D are both arrays of pointers, and
hence the array elements are 4 bytes each.
Array
The memory referencing instructions of IA32 are
designed to simplify array access.
For example, suppose E is an array of int’s, and
we wish to evaluate E[i], where the address of E
is stored in register %edx and i is stored in
register %ecx.
Then the instruction movl (%edx,%ecx,4),%eax
will perform the address computation xE+4i, read
that memory location, and copy the result to
register %eax.
The allowed scaling factors of 1, 2, 4, and 8 cover
the sizes of the common primitive data types.
Pointer Arithmetic
C allows arithmetic on pointers, where the
computed value is scaled according to the size of
the data type referenced by the pointer.
That is, if p is a pointer to data of type T, and the
value of p is xp, then the expression p+i has
value xp+L.i, where L is the size of data type T.
Pointer Arithmetic
The unary operators & and * allow the generation
and dereferencing of pointers.
That is, for an expression Expr denoting some
object, &Expr is a pointer giving the address of
the object.
For an expression Aexpr denoting an
address,*Aexpr gives the value at that address.
The expressions Expr and *&Expr are therefore
equivalent.
The array subscripting operation can be applied to
both arrays and pointers. The array reference
A[i] is identical to the expression*(A+i). It
computes the address of the ith array element
and then accesses this memory location.
Pointer Arithmetic
The unary operators & and * allow the generation
and dereferencing of pointers.
That is, for an expression Expr denoting some
object, &Expr is a pointer giving the address of
the object.
For an expression Aexpr denoting an
address,*Aexpr gives the value at that address.
The expressions Expr and *&Exprare therefore
equivalent.
The array subscripting operation can be applied to
both arrays and pointers. The array reference A[i]
is identical to the expression*(A+i). It computes
the address of the ith array element and then
accesses this memory location.
Pointer Arithmetic
A(28/12/20)
Suppose the starting address of integer array E
and integer index i are stored in registers %edx
and %ecx, respectively.
Pointer Arithmetic
In these examples, the leal instruction is used to
generate an address, while movl is used to
reference memory (except in the first and last
cases, where the former copies an address and
the latter copies the index).
The final example shows that one can compute
the difference of two pointers within the same
data structure, with the result divided by the size
of the data type.
Nested Arrays-Section C-
Continue (24/12/20)
The general principles of array allocation and
referencing hold even when we create arrays of
arrays.
For example, the declaration
int A[5][3];
is equivalent to the declaration
typedef int row3_t[3];
row3_t A[5];
Data type row3_t is defined to be an array of
three integers. Array A contains five such
elements, each requiring 12 bytes to store the
three integers. The total array size is then
4.5.3=60 bytes.
Nested Arrays
Array A can also be viewed as a two-dimensional
array with five rows and three columns,
referenced as A[0][0] through A[4][2].
The array elements are ordered in memory in
“row major” order, meaning all elements of row 0,
which can be written A[0], followed by all
elements of row 1 (A[1]), and so on.
Nested Arrays
This ordering is a consequence of our nested
declaration. Viewing A as an array of five
elements, each of which is an array of three int’s,
we first haveA[0], followed byA[1], and so on.
Nested Arrays
To access elements of multidimensional arrays,
the compiler generates code to compute the offset
of the desired element and then uses one of the
mov instructions with the start of the array as the
base address and the (possibly scaled) offset as
an index. In general, for an array declared as
T D[R][C];
Nested Arrays
Array element D[i][j] is at memory address
&D[i][j]=xD+L (C.i+j)
??????????????????????????