
















Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An in-depth exploration of arrays, multi-level arrays, alignment, and byte ordering in c programming. Topics include array declaration, memory allocation, accessing elements, nested arrays, and handling different data types. It also covers the concept of alignment for efficient memory access and the importance of understanding byte ordering when exchanging binary data between systems.
Typology: Study notes
1 / 24
This page cannot be seen from the preview
Don't miss anything!

















2
3
Topics
Arrays
Structs
Unions
4
Basic Data Types
Integral
Intel GAS Bytes C byte b 1 [ unsigned ] char word w 2 [ unsigned ] short double word l 4 [ unsigned ] int
Floating Point
Intel GAS Bytes C Single s 4 float Double l 8 double Extended t 10/12 long double
7
Array Example
Notes
Not guaranteed to happen in general
typedef int zip_dig[5];
zip_dig cmu = { 1, 5, 2, 1, 3 }; zip_dig mit = { 0, 2, 1, 3, 9 }; zip_dig ucb = { 9, 4, 7, 2, 0 };
zip_dig cmu; 1 5 2 1 3
16 20 24 28 32 36 zip_dig mit; (^0 2 1 3 )
36 40 44 48 52 56 zip_dig ucb; (^9 4 7 2 )
56 60 64 68 72 76
8
Array Accessing Example
Memory Reference Code
int get_digit (zip_dig z, int dig) { return z[dig]; }
movl (%edx,%eax,4),%eax # z[dig]
Computation
9
Referencing Examples
Code Does Not Do Any Bounds Checking!
Reference Address Value Guaranteed?
No guaranteed relative allocation of different arrays
zip_dig cmu; 1 5 2 1 3
16 20 24 28 32 36 zip_dig mit; (^0 2 1 3 )
36 40 44 48 52 56 zip_dig ucb; (^9 4 7 2 )
56 60 64 68 72 76
10
int zd2int(zip_dig z) { int i; int zi = 0; for (i = 0; i < 5; i++) { zi = 10 * zi + z[i]; } return zi; }
Array Loop Example
Original Source
int zd2int(zip_dig z) { int zi = 0; int *zend = z + 4; do { zi = 10 * zi + *z; z++; } while(z <= zend); return zi; }
Transformed Version
No need to test at entrance
13
Nested Array Allocation
Declaration
Array Size
Arrangement
int A[R][C];
4RC Bytes
14
Nested Array Row Access
Row Vectors
[i] [0]
[i] [C-1]
A[i]
A [R-1] [0]
int A[R][C];
A+iC4 A+(R-1)C
15
Nested Array Row Access Code
Row Vector
Code
int *get_pgh_zip(int index) { return pgh[index]; }
leal (%eax,%eax,4),%eax # 5 * index leal pgh(,%eax,4),%eax # pgh + (20 * index)
16
Nested Array Element Access
Array Elements
[i] [j]
[i] [j]
A[i]
A [R-1] [0]
int A[R][C];
A+iC4 A+(R-1)C A+(iC+j)
19
Multi-Level Array Example
4 bytes
zip_dig cmu = { 1, 5, 2, 1, 3 }; zip_dig mit = { 0, 2, 1, 3, 9 }; zip_dig ucb = { 9, 4, 7, 2, 0 };
#define UCOUNT 3 int *univ[UCOUNT] = {mit, cmu, ucb};
univ
cmu 1 5 2 1 3
16 20 24 28 32 36 mit 0 2 1 3 9
ucb^36 40 44 48 52 9 4 7 2 0
56 60 64 68 72 76
20
Element Access in Multi-Level Array
Computation
First get pointer to row array Then access element within array
leal 0(,%ecx,4),%edx # 4index movl univ(%edx),%edx # Mem[univ+4index] movl (%edx,%eax,4),%eax # Mem[...+4*dig]
int get_univ_digit (int index, int dig) { return univ[index][dig]; }
21
Array Element Accesses
Similar C references
Element at Mem[pgh+20index+4dig]
Different address computation
Element at Mem[Mem[univ+4index]+4dig]
int get_pgh_digit (int index, int dig) { return pgh[index][dig]; }
int get_univ_digit (int index, int dig) { return univ[index][dig]; }
(^16036) 16 56
164 168
univ
cmu 1 5 2 1 3 mit 16 20 24 28 32 36 0 2 1 3 9 ucb^36 40 44 48 52 9 4 7 2 0 56 60 64 68 72 76
(^16036) 16 56
164 168
univ (^16036) 16 56
164 168
univ
cmu 1 5 2 1 3 16 20 24 28 32 36
11 55 22 11 33 mit 16 20 24 28 32 36 0 2 1 3 9 36 40 44 48 52 56
00 22 11 33 99 ucb^36 40 44 48 52 9 4 7 2 0 56 60 64 68 72 76
99 44 77 22 00 56 60 64 68 72 76
76 96 116 136 156
1 5 2 0 6 1 5 2 1 3 1 5 2 1 7 1 5 2 2 1 76 96 116 136 156
111 555 222 000 666 111 555 222 111 333 111 555 222 111 777 111 555 222 222 111
22
Strange Referencing Examples
Reference Address Value Guaranteed? univ[2][3] 56+43 = 68 2 univ[1][5] 16+45 = 36 0 univ[2][-1] 56+4-1 = 52 9 univ[3][-1] ?? ?? univ[1][12] 16+412 = 64 7 Code does not do any bounds checking Ordering of elements in different arrays not guaranteed
univ
cmu 1 5 2 1 3
16 20 24 28 32 36 mit 0 2 1 3 9
ucb^36 40 44 48 52 9 4 7 2 0
56 60 64 68 72 76
Yes No No No No
25
Dynamic Array Multiplication
Without Optimizations
2 for subscripts 1 for data
4 for array indexing 1 for loop index 1 for data
/* Compute element i,k of variable matrix product */ int var_prod_ele (int a, int b, int i, int k, int n) { int j; int result = 0; for (j = 0; j < n; j++) result += a[in+j] * b[jn+k]; return result; }
(i,*) B
(*,k)
Column-wise
Row-wise
26
Optimizing Dynamic Array Mult.
Optimizations
Code Motion
Strength Reduction
Performance
int j; int result = 0; for (j = 0; j < n; j++) result += a[in+j] * b[jn+k]; return result; } { int j; int result = 0; int iTn = i*n; int jTnPk = k; for (j = 0; j < n; j++) { result += a[iTn+j] * b[jTnPk]; jTnPk += n; } return result; }
27
struct rec { int i; int a[3]; int *p; };
Assembly
movl %eax,(%edx) # Mem[r] = val
void set_i(struct rec *r, int val) { r->i = val; }
Structures
Concept
Accessing Structure Member
Memory Layout
i a p 0 4 16 20
28
struct rec { int i; int a[3]; int *p; };
leal 0(,%ecx,4),%eax # 4idx leal 4(%eax,%edx),%eax # r+4idx+
int * find_a (struct rec *r, int idx) { return &r->a[idx]; }
Generating Pointer to Struct. Member
Generating Pointer to Array Element
i a p 0 4 16 r + 4 + 4*idx
r
31
Specific Cases of Alignment
Size of Primitive Data Type:
no restrictions on address
lowest 1 bit of address must be 0 2
lowest 2 bits of address must be 00 2
Windows (and most other OS’s & instruction sets): » lowest 3 bits of address must be 000 2 Linux: » lowest 2 bits of address must be 00 2 » i.e., treated the same as a 4-byte primitive data type
Linux: » lowest 2 bits of address must be 00 2 » i.e., treated the same as a 4-byte primitive data type
32
struct S1 { char c; int i[2]; double v; } *p;
Satisfying Alignment with Structures
Offsets Within Structure
Overall Structure Placement
Largest alignment of any element
Example (under Windows):
c i[0] i[1] v p+0 p+4 p+8 p+16 p+
Multiple of 4 Multiple of 8
Multiple of 8 Multiple of 8
33
Linux vs. Windows
Windows (including Cygwin):
Linux:
struct S1 { char c; int i[2]; double v; } *p;
c i[0] i[1] v p+0 p+4 p+8 p+16 p+
Multiple of 4 Multiple of 8 Multiple of 8 Multiple of 8
c i[0] i[1] p+0 p+4 p+
Multiple of 4 Multiple of 4 Multiple of 4
v p+12 p+
Multiple of 4
34
Overall Alignment Requirement
struct S2 { double x; int i[2]; char c; } *p;
struct S3 { float x[2]; int i[2]; char c; } *p;
p+0 p+8 p+12 p+16 (^) Windows : p+ Linux : p+
x i[0] i[1] c
i[0] i[1] c p+0 p+8 p+12 p+16 p+
x[0] x[1] p+
37
Accessing Element within Array
Compute 12* i as 4(* i +2 i )
Offset by 8 Assembler gives displacement as a + 8 » Linker must set actual value
a[0] a+
a[i] a+12i
short get_j(int idx) { return a[idx].j; }
leal (%eax,%eax,2),%eax # 3*idx movswl a+8(,%eax,4),%eax
a+12i a+12i+
struct S6 { short i; float v; short j; } a[10];
a[i].i a[i].v a[i].j
38
Satisfying Alignment within Structure
Achieving Alignment
a must be multiple of 4
v ’s offset of 4 is a multiple of 4
Structure padded with unused space to be 12 bytes
struct S6 { short i; float v; short j; } a[10];
a[0] a+
a[i] a+12i
a+12i a+12i+
a[1].i a[1].v a[1].j
Multiple of 4
Multiple of 4
39
Union Allocation
Principles
union U1 { char c; int i[2]; double v; } *up;
c i[0] i[1] v
struct S1 { up+0^ up+4^ up+ char c; int i[2]; double v; } *sp;
c i[0] i[1] v sp+0 sp+4 sp+8 sp+16 sp+
(Windows alignment)
40
typedef union { float f; unsigned u; } bit_float_t;
float bit2float(unsigned u) { bit_float_t arg; arg.u = u; return arg.f; u } f 0 4 unsigned float2bit(float f) { bit_float_t arg; arg.f = f; return arg.u; }
Using Union to Access Bit Patterns
NOT the same as (float) u
NOT the same as (unsigned) f