15 213 The course that gives CMU its

  • Slides: 45
Download presentation
15 -213 “The course that gives CMU its Zip!” Machine-Level Programming IV: Structured Data

15 -213 “The course that gives CMU its Zip!” Machine-Level Programming IV: Structured Data Sept. 18, 2003 Topics n Arrays n Structs Unions n class 08. ppt

Basic Data Types Integral n Stored & operated on in general registers n Signed

Basic Data Types Integral n Stored & operated on in general registers n Signed vs. unsigned depends on instructions used Intel GAS byte b word w double word Bytes 1 2 l C [unsigned] char [unsigned] short 4 [unsigned] int Floating Point n Stored & operated on in floating point registers Intel Single Double Extended – 2– GAS s l t Bytes 4 8 10/12 C float double long double 15 -213, F’ 03

Array Allocation Basic Principle T A[L]; n n Array of data type T and

Array Allocation Basic Principle T A[L]; n n Array of data type T and length L Contiguously allocated region of L * sizeof(T) bytes char string[12]; x x + 12 int val[5]; x double a[4]; x x+4 x+8 x + 16 x + 12 x + 16 x + 24 x + 20 x + 32 char *p[3]; x – 3– x+4 x+8 15 -213, F’ 03

Array Access Basic Principle T A[L]; Array of data type T and length L

Array Access Basic Principle T A[L]; Array of data type T and length L n Identifier A can be used as a pointer to array element 0 n int val[5]; 1 x Reference – 4– val[4] val int * val+1 &val[2] val[5] *(val+1) val + i 5 x+4 2 x+8 1 3 x + 12 x + 16 x + 20 Type Value int 3 x int * x + 4 int * x + 8 int ? ? int 5 int * x + 4 i 15 -213, F’ 03

Array Example typedef int zip_dig[5]; zip_dig cmu = { 1, 5, 2, 1, 3

Array Example 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 16 zip_dig mit; 5 20 0 36 zip_dig ucb; 24 2 40 9 56 2 28 1 44 4 60 1 32 3 48 7 64 3 9 52 2 68 36 56 0 72 76 Notes – 5– n Declaration “zip_dig cmu” equivalent to “int cmu[5]” n Example arrays were allocated in successive 20 byte blocks l Not guaranteed to happen in general 15 -213, F’ 03

Array Accessing Example Computation n n Register %edx contains starting address of array Register

Array Accessing Example Computation n n Register %edx contains starting address of array Register %eax contains array index Desired digit at 4*%eax + %edx int get_digit (zip_dig z, int dig) { return z[dig]; } Use memory reference (%edx, %eax, 4) Memory Reference Code # %edx = z # %eax = dig movl (%edx, %eax, 4), %eax # z[dig] – 6– 15 -213, F’ 03

Referencing Examples zip_dig cmu; 1 5 16 zip_dig mit; 20 0 24 2 36

Referencing Examples zip_dig cmu; 1 5 16 zip_dig mit; 20 0 24 2 36 zip_dig ucb; 2 40 9 60 28 1 44 4 56 1 32 3 48 7 64 3 36 9 52 2 68 56 0 72 76 Code Does Not Do Any Bounds Checking! Reference Address mit[3] mit[5] mit[-1] cmu[15] n – 7– 36 36 36 16 + + 4* 3 4* 5 4*-1 4*15 Value Guaranteed? = = 48 56 32 76 3 9 3 ? ? Yes No No No Out of range behavior implementation-dependent l No guaranteed relative allocation of different arrays 15 -213, F’ 03

Array Loop Example Original Source Transformed Version As generated by GCC n Eliminate loop

Array Loop Example Original Source Transformed Version As generated by GCC n Eliminate loop variable i n Convert array code to pointer code n Express in do-while form n l No need to test at entrance – 8– int zd 2 int(zip_dig z) { int i; int zi = 0; for (i = 0; i < 5; i++) { zi = 10 * zi + z[i]; } return zi; } int zd 2 int(zip_dig z) { int zi = 0; int *zend = z + 4; do { zi = 10 * zi + *z; z++; } while(z <= zend); return zi; } 15 -213, F’ 03

Array Loop Implementation Registers %ecx %eax %ebx z zi zend Computations 10*zi + *z

Array Loop Implementation Registers %ecx %eax %ebx z zi zend Computations 10*zi + *z implemented as *z + 2*(zi+4*zi) n z++ increments by 4 n – 9– # %ecx = z xorl %eax, %eax leal 16(%ecx), %ebx. L 59: leal (%eax, 4), %edx movl (%ecx), %eax addl $4, %ecx leal (%eax, %edx, 2), %eax cmpl %ebx, %ecx jle. L 59 int zd 2 int(zip_dig z) { int zi = 0; int *zend = z + 4; do { zi = 10 * zi + *z; z++; } while(z <= zend); return zi; } # zi = 0 # zend = z+4 # # # 5*zi *z z++ zi = *z + 2*(5*zi) z : zend if <= goto loop 15 -213, F’ 03

Nested Array Example #define PCOUNT 4 zip_dig pgh[PCOUNT] = {{1, 5, 2, 0, 6},

Nested Array Example #define PCOUNT 4 zip_dig pgh[PCOUNT] = {{1, 5, 2, 0, 6}, {1, 5, 2, 1, 3 }, {1, 5, 2, 1, 7 }, {1, 5, 2, 2, 1 }}; zip_dig pgh[4]; 1 5 2 0 6 1 5 2 1 3 1 5 2 1 7 1 5 2 2 1 76 n 96 116 136 156 Declaration “zip_dig pgh[4]” equivalent to “int pgh[4][5]” l Variable pgh denotes array of 4 elements » Allocated contiguously l Each element is an array of 5 int’s » Allocated contiguously n – 10 – “Row-Major” ordering of all elements guaranteed 15 -213, F’ 03

Nested Array Allocation Declaration T A[R][C]; n n n A[0][0] Array of data type

Nested Array Allocation Declaration T A[R][C]; n n n A[0][0] Array of data type T R rows, C columns Type T element requires K bytes • • • A[0][C-1] • • • A[R-1][0] • • • A[R-1][C-1] Array Size n R * C * K bytes Arrangement n Row-Major Ordering int A[R][C]; A A [0] • • • [0] [1] • • • [1] [0] [C-1] • • • A A [R-1] • • • [R-1] [0] [C-1] 4*R*C Bytes – 11 – 15 -213, F’ 03

Nested Array Row Access Row Vectors n n n A[i] is array of C

Nested Array Row Access Row Vectors n n n A[i] is array of C elements Each element of type T Starting address A + i * C * K int A[R][C]; A[0] A – 12 – • • • A[i] A [0] • • • [C-1] A [i] [0] • • • A+i*C*4 A[R-1] A A [i] • • • [R-1] [C-1] [0] • • • A [R-1] [C-1] A+(R-1)*C*4 15 -213, F’ 03

Nested Array Row Access Code int *get_pgh_zip(int index) { return pgh[index]; } Row Vector

Nested Array Row Access Code int *get_pgh_zip(int index) { return pgh[index]; } Row Vector n n pgh[index] is array of 5 int’s Starting address pgh+20*index Code n n Computes and returns address Compute as pgh + 4*(index+4*index) # %eax = index leal (%eax, 4), %eax # 5 * index leal pgh(, %eax, 4), %eax # pgh + (20 * index) – 13 – 15 -213, F’ 03

Nested Array Element Access Array Elements n n A [i] [j] A[i][j] is element

Nested Array Element Access Array Elements n n A [i] [j] A[i][j] is element of type T Address A + (i * C + j) * K int A[R][C]; A[0] A • • • A[R-1] A[i] A [0] • • • [C-1] • • • A [i] [j] • • • A+i*C*4 A • • • [R-1] [0] • • • A [R-1] [C-1] A+(R-1)*C*4 A+(i*C+j)*4 – 15 -213, F’ 03

Nested Array Element Access Code Array Elements pgh[index][dig] is int n n Address: pgh

Nested Array Element Access Code Array Elements pgh[index][dig] is int n n Address: pgh + 20*index + 4*dig Code n int get_pgh_digit (int index, int dig) { return pgh[index][dig]; } Computes address pgh + 4*dig + 4*(index+4*index) n movl performs memory reference # %ecx = dig # %eax = index leal 0(, %ecx, 4), %edx leal (%eax, 4), %eax movl pgh(%edx, %eax, 4), %eax – 15 – # 4*dig # 5*index # *(pgh + 4*dig + 20*index) 15 -213, F’ 03

Strange Referencing Examples zip_dig pgh[4]; 1 5 2 0 6 1 5 2 1

Strange Referencing Examples zip_dig pgh[4]; 1 5 2 0 6 1 5 2 1 3 1 5 2 1 7 1 5 2 2 1 76 Reference Address 96 116 136 156 Value Guaranteed? pgh[3][3] 76+20*3+4*3 = 148 2 pgh[2][5] 76+20*2+4*5 = 136 1 pgh[2][-1] 76+20*2+4*-1 = pgh[4][-1] 76+20*4+4*-1 = pgh[0][19] 76+20*0+4*19 = pgh[0][-1] 76+20*0+4*-1 = Yes 112 152 72 ? ? 3 Yes 1 Yes No Code does not do any bounds checking n Ordering of elements within array guaranteed n – 16 – 15 -213, F’ 03

Multi-Level Array Example n n Variable univ denotes array of 3 elements Each element

Multi-Level Array Example n n Variable univ denotes array of 3 elements Each element is a pointer l 4 bytes n 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}; Each pointer points to array of int’s cmu univ 160 36 164 16 168 56 mit 1 16 20 0 ucb 36 56 – 17 – 5 2 24 2 40 9 28 1 44 4 60 1 32 3 48 7 64 3 9 52 2 68 36 56 0 72 76 15 -213, F’ 03

Element Access in Multi-Level Array Computation int get_univ_digit (int index, int dig) { return

Element Access in Multi-Level Array Computation int get_univ_digit (int index, int dig) { return univ[index][dig]; } n Element access Mem[univ+4*index]+4*dig] n Must do two memory reads l First get pointer to row array l Then access element within array # %ecx = index # %eax = dig leal 0(, %ecx, 4), %edx # 4*index movl univ(%edx), %edx # Mem[univ+4*index] movl (%edx, %eax, 4), %eax # Mem[. . . +4*dig] – 18 – 15 -213, F’ 03

Array Element Accesses n Similar C references Nested Array int get_pgh_digit (int index, int

Array Element Accesses n Similar C references Nested Array int get_pgh_digit (int index, int dig) { return pgh[index][dig]; } Element at Mem[pgh+20*index+4*dig] n – 19 – n Different address computation Multi-Level Array int get_univ_digit (int index, int dig) { return univ[index][dig]; } Element at Mem[univ+4*index]+4*dig] n 15 -213, F’ 03

Strange Referencing Examples cmu univ 160 36 164 16 168 56 mit 1 16

Strange Referencing Examples cmu univ 160 36 164 16 168 56 mit 1 16 20 0 ucb 36 56 Reference Address 5 2 24 2 40 9 28 1 44 4 60 1 32 3 48 7 64 n – 20 – 36 9 52 2 68 56 0 72 76 Value Guaranteed? univ[2][3] 56+4*3 = 68 2 univ[1][5] 16+4*5 = 36 0 univ[2][-1] 56+4*-1 = 52 9 univ[3][-1] ? ? univ[1][12] 16+4*12 = 64 7 n 3 Yes No No Code does not do any bounds checking Ordering of elements in different arrays not guaranteed 15 -213, F’ 03

Using Nested Arrays #define N 16 typedef int fix_matrix[N][N]; Strengths n n C compiler

Using Nested Arrays #define N 16 typedef int fix_matrix[N][N]; Strengths n n C compiler handles doubly subscripted arrays Generates very efficient code l Avoids multiply in index computation Limitation n Only works if have fixed array size (*, k) /* Compute element i, k of fixed matrix product */ int fix_prod_ele (fix_matrix a, fix_matrix b, int i, int k) { int j; int result = 0; for (j = 0; j < N; j++) result += a[i][j]*b[j][k]; return result; } (i, *) Row-wise A B Column-wise – 21 – 15 -213, F’ 03

Dynamic Nested Arrays Strength n Can create matrix of arbitrary size Programming n Must

Dynamic Nested Arrays Strength n Can create matrix of arbitrary size Programming n Must do index computation int var_ele explicitly Performance n n Accessingle element costly Must do multiplication movl 12(%ebp), %eax movl 8(%ebp), %edx imull 20(%ebp), %eax addl 16(%ebp), %eax movl (%edx, %eax, 4), %eax – 22 – int * new_var_matrix(int n) { return (int *) calloc(sizeof(int), n*n); } (int *a, int i, int j, int n) { return a[i*n+j]; } # # # i a n*i+j Mem[a+4*(i*n+j)] 15 -213, F’ 03

Dynamic Array Multiplication Without Optimizations n Multiplies l 2 for subscripts l 1 for

Dynamic Array Multiplication Without Optimizations n Multiplies l 2 for subscripts l 1 for data n Adds l 4 for array indexing l 1 for loop index l 1 for data (*, k) /* 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[i*n+j] * b[j*n+k]; return result; } (i, *) Row-wise A B Column-wise – 23 – 15 -213, F’ 03

Optimizing Dynamic Array Mult. { Optimizations n int j; int result = 0; for

Optimizing Dynamic Array Mult. { Optimizations n int j; int result = 0; for (j = 0; j < n; j++) result += a[i*n+j] * b[j*n+k]; return result; Performed when set optimization level to -O 2 Code Motion n Expression i*n can be computed outside loop } { int j; int result = 0; int i. Tn = i*n; int j. Tn. Pk = k; for (j = 0; j < n; j++) { result += a[i. Tn+j] * b[j. Tn. Pk]; j. Tn. Pk += n; } return result; Strength Reduction n Incrementing j has effect of incrementing j*n+k by n Performance n – 24 – Compiler can optimize regular access patterns } 15 -213, F’ 03

Structures Concept n Contiguously-allocated region of memory n Refer to members within structure by

Structures Concept n Contiguously-allocated region of memory n Refer to members within structure by names Members may be of different types n struct rec { int i; int a[3]; int *p; }; Memory Layout i 0 a 4 p 16 20 Accessing Structure Member void set_i(struct rec *r, int val) { r->i = val; } – 25 – Assembly # %eax = val # %edx = r movl %eax, (%edx) # Mem[r] = val 15 -213, F’ 03

Generating Pointer to Struct. Member r struct rec { int i; int a[3]; int

Generating Pointer to Struct. Member r struct rec { int i; int a[3]; int *p; }; Generating Pointer to Array Element n Offset of each structure member determined at compile time i 0 a p 4 16 r + 4*idx int * find_a (struct rec *r, int idx) { return &r->a[idx]; } # %ecx = idx # %edx = r leal 0(, %ecx, 4), %eax # 4*idx leal 4(%eax, %edx), %eax # r+4*idx+4 – 26 – 15 -213, F’ 03

Structure Referencing (Cont. ) C Code struct rec { int i; int a[3]; int

Structure Referencing (Cont. ) C Code struct rec { int i; int a[3]; int *p; }; void set_p(struct rec *r) { r->p = &r->a[r->i]; } – 27 – i 0 a 4 i 0 p 16 a 4 16 Element i # %edx = r movl (%edx), %ecx leal 0(, %ecx, 4), %eax leal 4(%edx, %eax), %eax movl %eax, 16(%edx) # # r->i 4*(r->i) r+4+4*(r->i) Update r->p 15 -213, F’ 03

Alignment Aligned Data n Primitive data type requires K bytes n Address must be

Alignment Aligned Data n Primitive data type requires K bytes n Address must be multiple of K Required on some machines; advised on IA 32 n l treated differently by Linux and Windows! Motivation for Aligning Data n Memory accessed by (aligned) double or quad-words l Inefficient to load or store datum that spans quad word boundaries l Virtual memory very tricky when datum spans 2 pages Compiler n – 28 – Inserts gaps in structure to ensure correct alignment of fields 15 -213, F’ 03

Specific Cases of Alignment Size of Primitive Data Type: n 1 byte (e. g.

Specific Cases of Alignment Size of Primitive Data Type: n 1 byte (e. g. , char) l no restrictions on address n 2 bytes (e. g. , short) l lowest 1 bit of address must be 02 n 4 bytes (e. g. , int, float, char *, etc. ) l lowest 2 bits of address must be 002 n 8 bytes (e. g. , double) l Windows (and most other OS’s & instruction sets): » lowest 3 bits of address must be 0002 l Linux: » lowest 2 bits of address must be 002 » i. e. , treated the same as a 4 -byte primitive data type n 12 bytes (long double) l Linux: » lowest 2 bits of address must be 002 » i. e. , treated the same as a 4 -byte primitive data type – 29 – 15 -213, F’ 03

Satisfying Alignment with Structures Offsets Within Structure n Must satisfy element’s alignment requirement Overall

Satisfying Alignment with Structures Offsets Within Structure n Must satisfy element’s alignment requirement Overall Structure Placement n Each structure has alignment requirement K l Largest alignment of any element n struct S 1 { char c; int i[2]; double v; } *p; Initial address & structure length must be multiples of K Example (under Windows): n K = 8, due to double element c p+0 i[0] p+4 Multiple of 8 – 30 – i[1] p+8 v p+16 p+24 Multiple of 8 15 -213, F’ 03

Linux vs. Windows struct S 1 { char c; int i[2]; double v; }

Linux vs. Windows struct S 1 { char c; int i[2]; double v; } *p; Windows (including Cygwin): n K = 8, due to double element c p+0 i[0] p+4 i[1] v p+8 p+16 Multiple of 4 Multiple of 8 p+24 Multiple of 8 Linux: n K = 4; double treated like a 4 -byte data type c p+0 – 31 – i[0] p+4 Multiple of 4 i[1] p+8 v p+12 Multiple of 4 p+20 Multiple of 4 15 -213, F’ 03

Overall Alignment Requirement struct S 2 { double x; int i[2]; char c; }

Overall Alignment Requirement struct S 2 { double x; int i[2]; char c; } *p; p must be multiple of: 8 for Windows 4 for Linux x i[0] p+0 p+8 struct S 3 { float x[2]; int i[2]; char c; } *p; x[0] p+0 – 32 – p+12 c p+16 Windows: p+24 Linux: p+20 p must be multiple of 4 (in either OS) x[1] p+4 i[1] i[0] p+8 i[1] p+12 c p+16 p+20 15 -213, F’ 03

Ordering Elements Within Structure struct S 4 { char c 1; double v; char

Ordering Elements Within Structure struct S 4 { char c 1; double v; char c 2; int i; } *p; 10 bytes wasted space in Windows c 1 v p+0 p+8 struct S 5 { double v; char c 1; char c 2; int i; } *p; v p+0 – 33 – c 2 p+16 i p+20 p+24 2 bytes wasted space c 1 c 2 p+8 i p+12 p+16 15 -213, F’ 03

Arrays of Structures Principle n n Allocated by repeating allocation for array type In

Arrays of Structures Principle n n Allocated by repeating allocation for array type In general, may nest arrays & structures to arbitrary depth a[1]. i a[1]. v a+12 a+16 a[0] a+0 – 34 – a[1]. j a+20 a[1] a+12 struct S 6 { short i; float v; short j; } a[10]; a+24 • • • a[2] a+24 a+36 15 -213, F’ 03

Accessing Element within Array n Compute offset to start of structure l Compute 12*i

Accessing Element within Array n Compute offset to start of structure l Compute 12*i as 4*(i+2 i) n struct S 6 { short i; float v; short j; } a[10]; Access element according to its offset within structure l Offset by 8 l Assembler gives displacement as a + 8 » Linker must set actual value short get_j(int idx) { return a[idx]. j; } a[0] a+0 a[i]. i a+12 i – 35 – # %eax = idx leal (%eax, 2), %eax # 3*idx movswl a+8(, %eax, 4), %eax • • • a[i] • • • a+12 i a[i]. v a[i]. j a+12 i+8 15 -213, F’ 03

Satisfying Alignment within Structure Achieving Alignment n Starting address of structure array must be

Satisfying Alignment within Structure Achieving Alignment n Starting address of structure array must be multiple of worst-case alignment for any element l a must be multiple of 4 n Offset of element within structure must be multiple of element’s alignment requirement l v’s offset of 4 is a multiple of 4 n Overall size of structure must be multiple of worst-case alignment for any element struct S 6 { short i; float v; short j; } a[10]; l Structure padded with unused space to be 12 bytes a[0] • • • a[i] a+12 i a+0 Multiple of 4 – 36 – a[1]. i a+12 i • • • a[1]. v a[1]. j a+12 i+4 Multiple of 4 15 -213, F’ 03

Union Allocation Principles n Overlay union elements n Allocate according to largest element Can

Union Allocation Principles n Overlay union elements n Allocate according to largest element Can only use one field at a time n struct S 1 { char c; int i[2]; double v; } *sp; c sp+0 – 37 – sp+4 union U 1 { char c; int i[2]; double v; } *up; c i[0] up+0 i[1] v up+4 up+8 (Windows alignment) i[0] sp+8 i[1] v sp+16 sp+24 15 -213, F’ 03

Using Union to Access Bit Patterns typedef union { float f; unsigned u; }

Using Union to Access Bit Patterns typedef union { float f; unsigned u; } bit_float_t; u f 0 n n 4 Get direct access to bit representation of float bit 2 float generates float with given bit pattern float bit 2 float(unsigned u) { bit_float_t arg; arg. u = u; return arg. f; } unsigned float 2 bit(float f) { bit_float_t arg; arg. f = f; return arg. u; } l NOT the same as (float) u n float 2 bit generates bit pattern from float l NOT the same as (unsigned) f – 38 – 15 -213, F’ 03

Byte Ordering Revisited Idea n n n Short/long/quad words stored in memory as 2/4/8

Byte Ordering Revisited Idea n n n Short/long/quad words stored in memory as 2/4/8 consecutive bytes Which is most (least) significant? Can cause problems when exchanging binary data between machines Big Endian n n Most significant byte has lowest address Power. PC, Sparc Little Endian n n – 39 – Least significant byte has lowest address Intel x 86, Alpha 15 -213, F’ 03

Byte Ordering Example union { unsigned } dw; char c[8]; short s[4]; int i[2];

Byte Ordering Example union { unsigned } dw; char c[8]; short s[4]; int i[2]; long l[1]; c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] s[0] s[1] s[2] s[3] i[0] i[1] l[0] – 40 – 15 -213, F’ 03

Byte Ordering Example (Cont). int j; for (j = 0; j < 8; j++)

Byte Ordering Example (Cont). int j; for (j = 0; j < 8; j++) dw. c[j] = 0 xf 0 + j; printf("Characters 0 -7 == [0 x%x, 0 x%x, 0 x%x]n", dw. c[0], dw. c[1], dw. c[2], dw. c[3], dw. c[4], dw. c[5], dw. c[6], dw. c[7]); printf("Shorts 0 -3 == [0 x%x, 0 x%x]n", dw. s[0], dw. s[1], dw. s[2], dw. s[3]); printf("Ints 0 -1 == [0 x%x, 0 x%x]n", dw. i[0], dw. i[1]); printf("Long 0 == [0 x%lx]n", dw. l[0]); – 41 – 15 -213, F’ 03

Byte Ordering on x 86 Little Endian f 0 f 1 f 2 f

Byte Ordering on x 86 Little Endian f 0 f 1 f 2 f 3 f 4 f 5 f 6 f 7 c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] LSB MSB LSB s[0] MSB LSB s[1] LSB s[2] MSB s[3] LSB i[0] LSB MSB i[1] MSB l[0] Print Output on Pentium: Characters Shorts Ints Long – 42 – 0 -7 0 -3 0 -1 0 == == [0 xf 0, 0 xf 1, 0 xf 2, 0 xf 3, 0 xf 4, 0 xf 5, 0 xf 6, 0 xf 7] [0 xf 1 f 0, 0 xf 3 f 2, 0 xf 5 f 4, 0 xf 7 f 6] [0 xf 3 f 2 f 1 f 0, 0 xf 7 f 6 f 5 f 4] [0 xf 3 f 2 f 1 f 0] 15 -213, F’ 03

Byte Ordering on Sun Big Endian f 0 f 1 f 2 f 3

Byte Ordering on Sun Big Endian f 0 f 1 f 2 f 3 f 4 f 5 f 6 f 7 c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] MSB LSB MSB s[0] LSB MSB s[1] MSB s[2] LSB s[3] MSB i[0] MSB LSB i[1] LSB l[0] Print Output on Sun: Characters Shorts Ints Long – 43 – 0 -7 0 -3 0 -1 0 == == [0 xf 0, 0 xf 1, 0 xf 2, 0 xf 3, 0 xf 4, 0 xf 5, 0 xf 6, 0 xf 7] [0 xf 0 f 1, 0 xf 2 f 3, 0 xf 4 f 5, 0 xf 6 f 7] [0 xf 0 f 1 f 2 f 3, 0 xf 4 f 5 f 6 f 7] [0 xf 0 f 1 f 2 f 3] 15 -213, F’ 03

Byte Ordering on Alpha Little Endian f 0 f 1 f 2 f 3

Byte Ordering on Alpha Little Endian f 0 f 1 f 2 f 3 f 4 f 5 f 6 f 7 c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] LSB MSB LSB s[0] MSB LSB s[1] LSB MSB LSB s[2] MSB s[3] LSB i[0] MSB i[1] LSB MSB l[0] Print Output on Alpha: Characters Shorts Ints Long – 44 – 0 -7 0 -3 0 -1 0 == == [0 xf 0, 0 xf 1, 0 xf 2, 0 xf 3, 0 xf 4, 0 xf 5, 0 xf 6, 0 xf 7] [0 xf 1 f 0, 0 xf 3 f 2, 0 xf 5 f 4, 0 xf 7 f 6] [0 xf 3 f 2 f 1 f 0, 0 xf 7 f 6 f 5 f 4] [0 xf 7 f 6 f 5 f 4 f 3 f 2 f 1 f 0] 15 -213, F’ 03

Summary Arrays in C n Contiguous allocation of memory n Pointer to first element

Summary Arrays in C n Contiguous allocation of memory n Pointer to first element No bounds checking n Compiler Optimizations n Compiler often turns array code into pointer code (zd 2 int) n Uses addressing modes to scale array indices Lots of tricks to improve array indexing in loops n Structures n n Allocate bytes in order declared Pad in middle and at end to satisfy alignment Unions n – 45 – n Overlay declarations Way to circumvent type system 15 -213, F’ 03