15 213 The course that gives CMU its

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

15 -213 “The course that gives CMU its Zip!” Machine-Level Programming IV: Data Sept. 16, 2008 Structured Data n Arrays n Structs Unions n class 07. 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 quad word Bytes 1 2 l q C [unsigned] char [unsigned] short 4 [unsigned] int 8 [unsigned] long int (x 86 -64) Floating Point n – 2 – Stored & operated on in floating point registers Intel Single Double Extended GAS s l t Bytes C 4 float 8 double 10/12/16 long double 15 -213, F’ 08

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 IA 32 char *p[3]; x x + 4 x + 8 x + 12 x 86 -64 – 3 – x x + 8 x + 16 15 -213, F’ 08 x + 24

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 l Type T* int val[5]; 1 5 x Reference – 4 – val[4] val int * val+1 &val[2] val[5] *(val+1) val + i x + 4 2 x + 8 1 3 x + 12 x + 16 x + 20 Type Value int x int * int int * 3 x+4 x+8 ? ? 5 x+4 i 15 -213, F’ 08

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’ 08

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) IA 32 Memory Reference Code # %edx = z # %eax = dig movl (%edx, %eax, 4), %eax # z[dig] – 6 – 15 -213, F’ 08

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

Referencing Examples 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 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 – Value Guaranteed? 36 + 4* 3 = 48 36 + 4* 5 = 56 36 + 4*-1 = 32 16 + 4*15 = 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’ 08

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’ 08

Array Loop Implementation (IA 32) Registers %ecx %eax %ebx z zi zend Computations 10*zi

Array Loop Implementation (IA 32) Registers %ecx %eax %ebx z zi zend Computations 10*zi + *z implemented as *z + 2*(zi+4*zi) 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’ 08

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’ 08

Viewing as Multidimensional Array Declaration T A[R][C]; n n n A[0][0] 2 D array

Viewing as Multidimensional Array Declaration T A[R][C]; n n n A[0][0] 2 D 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’ 08

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 requires K bytes 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’ 08

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 IA 32 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’ 08

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 * K) + j * K = 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’ 08

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

Nested Array Element Access Code Array Elements n n pgh[index][dig] is int Address: pgh + 20*index + 4*dig IA 32 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’ 08

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 = 112 pgh[4][-1] 76+20*4+4*-1 = 152 pgh[0][19] 76+20*0+4*19 = 152 pgh[0][-1] 76+20*0+4*-1 = 72 ? ? Yes 3 Yes 1 Yes No Code does not do any bounds checking n Ordering of elements within array guaranteed n – 16 – 15 -213, F’ 08

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’ 08

Element Access in Multi-Level Array Computation (IA 32) int get_univ_digit (int index, int dig)

Element Access in Multi-Level Array Computation (IA 32) 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’ 08

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’ 08

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’ 08

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’ 08

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’ 08

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’ 08

Optimizing Dynamic Array Mult. Optimizations n Performed when set optimization level to -O 2

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

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 – IA 32 Assembly # %eax = val # %edx = r movl %eax, (%edx) # Mem[r] = val 15 -213, F’ 08

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’ 08

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’ 08

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 IA 32 Linux, x 86 -64 Linux, and Windows! Motivation for Aligning Data n Memory accessed by (aligned) chunks of 4 or 8 bytes (system dependent) 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’ 08

Specific Cases of Alignment (IA 32) Size of Primitive Data Type: n 1 byte

Specific Cases of Alignment (IA 32) 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 Windows, 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’ 08

Specific Cases of Alignment (x 86 -64) Size of Primitive Data Type: n 1

Specific Cases of Alignment (x 86 -64) 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) l lowest 2 bits of address must be 002 n 8 bytes (e. g. , double, char *) l Windows & Linux: » lowest 3 bits of address must be 0002 n 16 bytes (long double) l Linux: » lowest 3 bits of address must be 0002 » i. e. , treated the same as a 8 -byte primitive data type – 30 – 15 -213, F’ 08

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 or x 86 -64): n K = 8, due to double element c p+0 i[0] p+4 Multiple of 8 – 31 – i[1] p+8 v p+16 p+24 Multiple of 8 15 -213, F’ 08

Different Alignment Conventions struct S 1 { char c; int i[2]; double v; }

Different Alignment Conventions struct S 1 { char c; int i[2]; double v; } *p; x 86 -64 or IA 32 Windows: 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 IA 32 Linux n K = 4; double treated like a 4 -byte data type c p+0 – 32 – 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’ 08

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 x 86 -64 or IA 32 Windows 4 for IA 32 Linux x i[0] p+0 p+8 struct S 3 { float x[2]; int i[2]; char c; } *p; x[0] p+0 – 33 – p+12 c p+16 Windows: p+24 Linux: p+20 p must be multiple of 4 (all cases) x[1] p+4 i[1] i[0] p+8 i[1] p+12 c p+16 p+20 15 -213, F’ 08

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 or x 86 -64 c 1 v p+0 p+8 struct S 5 { double v; char c 1; char c 2; int i; } *p; v p+0 – 34 – 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’ 08

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 – 35 – 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’ 08

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 – 36 – # %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’ 08

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 – 37 – a[1]. i a+12 i • • • a[1]. v a[1]. j a+12 i+4 Multiple of 4 15 -213, F’ 08

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 – 38 – 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’ 08

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 – 39 – 15 -213, F’ 08

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 – 40 – Least significant byte has lowest address Intel x 86 15 -213, F’ 08

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

Byte Ordering Example union { unsigned char c[8]; unsigned short s[4]; unsigned int i[2]; unsigned long l[1]; } dw; 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] – 41 – 15 -213, F’ 08

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]); – 42 – 15 -213, F’ 08

Byte Ordering on IA 32 Little Endian f 0 f 1 f 2 f

Byte Ordering on IA 32 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 IA 32: Characters 0 -7 == [0 xf 0, 0 xf 1, 0 xf 2, 0 xf 3, 0 xf 4, 0 xf 5, 0 xf 6, 0 xf 7] Shorts 0 -3 == [0 xf 1 f 0, 0 xf 3 f 2, 0 xf 5 f 4, 0 xf 7 f 6] Ints 0 -1 == [0 xf 3 f 2 f 1 f 0, 0 xf 7 f 6 f 5 f 4] Long 0 == [0 xf 3 f 2 f 1 f 0] – 43 – 15 -213, F’ 08

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 0 -7 == [0 xf 0, 0 xf 1, 0 xf 2, 0 xf 3, 0 xf 4, 0 xf 5, 0 xf 6, 0 xf 7] Shorts 0 -3 == [0 xf 0 f 1, 0 xf 2 f 3, 0 xf 4 f 5, 0 xf 6 f 7] Ints 0 -1 == [0 xf 0 f 1 f 2 f 3, 0 xf 4 f 5 f 6 f 7] Long 0 == [0 xf 0 f 1 f 2 f 3] – 44 – 15 -213, F’ 08

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

Byte Ordering on x 86 -64 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 x 86 -64: Characters 0 -7 == [0 xf 0, 0 xf 1, 0 xf 2, 0 xf 3, 0 xf 4, 0 xf 5, 0 xf 6, 0 xf 7] Shorts 0 -3 == [0 xf 1 f 0, 0 xf 3 f 2, 0 xf 5 f 4, 0 xf 7 f 6] Ints 0 -1 == [0 xf 3 f 2 f 1 f 0, 0 xf 7 f 6 f 5 f 4] Long 0 == [0 xf 7 f 6 f 5 f 4 f 3 f 2 f 1 f 0] – 45 – 15 -213, F’ 08

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 Structures n n Allocate bytes in order declared Pad in middle and at end to satisfy alignment Unions n n – 46 – Overlay declarations Way to circumvent type system 15 -213, F’ 08