Download presentation
Presentation is loading. Please wait.
1
Machine Level Representation of Programs (IV)
2
Heterogeneous data structure Understanding pointer Buffer overflow
Outline Heterogeneous data structure Understanding pointer Buffer overflow X86-64(optional) Suggested readings Chap 3.9, 3.10, 3.12, 3.13
3
Heterogeneous Data Structures & Alignment
4
Outline Struct Union Alignment
5
Group objects into a single object
Structures Group objects into a single object struct rect { int llx; /* X coordinate of lower-left corner */ int lly; /* Y coordinate of lower-left corner */ int color; /* Coding of color */ int width; /* Width (in pixels) */ int height; /* Height (in pixels) */ };
6
Structure Each object is referenced by name struct rect r; r.llx = r.lly = 0; r.color = 0xFF00FF; r.width = 10; r.height = 20;
7
Structure int area (struct rect *rp) {
return (*rp).width * (*rp).height; } void rotate_left (struct rect *rp) /* Exchange width and height */ int t = rp->height; rp->height = rp->width; rp->width = t;
8
Structures Memory layout
All the components are stored in a contiguous region of memory A pointer to a structure is the address of its first byte
9
Structure struct rec { int i; int j; int a[3]; int *p; } *r; Offset 4
4 8 20 Contents i j a[0] a[1] a[2] p
10
References to structure elements Using offsets as displacements
r->j = r->i (Copy element r->i to element r->j) r is in register %edx. 1 movl (%edx), %eax Get r->i 2 movl %eax, 4(%edx) Store in r->j Offset 4 8 20 Contents i j a[0] a[1] a[2] p
11
Structure &(r->a[i]) r in %eax, i in %edx: Offset 4 8 20 Contents i
1 leal 8(%eax,%edx,4),%ecx Generate &r->a[i] Offset 4 8 20 Contents i j a[0] a[1] a[2] p
12
r->p = &r->a[r->i + r->j];
Structure r->p = &r->a[r->i + r->j]; r in register %edx: 1 movl 4(%edx), %eax Get r->j 2 addl (%edx), %eax Add r->i 3 leal 8(%edx,%eax,4),%eax Compute &r->a[r->i + r->j] 4 movl %eax, 20(%edx) Store in r->p Offset 4 8 20 Contents i j a[0] a[1] a[2] p
13
Unions A single object can be referenced by using different data types The syntax of a union declaration is identical to that for structures, but its semantics are very different Rather than having the different fields reference different blocks of memory, they all reference the same block
14
Unions struct S3 { char c; int i[2]; double v; }; union U3 {
The offsets of the fields, as well as the total size of data types S3 and U3, are: Type c i v size S3 4 12 20 U3 8
15
Unions struct NODE { struct NODE *left; struct NODE *right;
double data; }; union NODE { struct { union NODE *left; union NODE *right; } internal;
16
Unions struct NODE { int is_leaf; union { struct { struct NODE *left;
struct NODE *right; } internal; double data; } info; };
17
Unions 1 unsigned float2bit(float f) 2 { 3 union { 4 float f;
5 unsigned u; 6 } temp; 7 temp.f = f; 8 return temp.u; 9 } 1 movl 8(%ebp), %eax
18
Unions 1 unsigned copy (unsigned u) 2 { 3 return u; 4 }
1 movl 8(%ebp), %eax
19
Alignment restrictions
The address for some type of object must be a multiple of some value k (typically 2, 4, or 8) Simplify the hardware design of the interface between the processor and the memory system
20
Alignment In IA32 hardware will work correctly regardless of the alignment of data Aligned data can improve memory system performance
21
Linux alignment restriction
1-byte data types are able to have any address 2-byte data types must have an address that is multiple of 2 Any larger data types must have an address that is multiple of 4
22
Alignment is enforced by
Making sure that every data type is organized and allocated in such a way that every object within the type satisfies its alignment restrictions. malloc() Returns a generic pointer that is void * Its alignment requirement is 4
23
Alignment Structure data type
may need to insert gaps in the field allocation may need to add padding to the end of the structure
24
Simple Example struct xxx { int i; char c; double d; };
struct xxx x[2]; 0x00 0x04 0x08 0x0C 0x10 0x14 &x[0].i &x[0].c &x[0].d &x[1].i
25
Complex Example 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C &x[0].s struct xxx { short s; char c0; int i; long l; char c1; char a[2]; double d; char c2; }; struct xxx x[2]; &x[0].c0 &x[0].i &x[0].l &x[0].c1 &x[0].a[0] &x[0].a[1] &x[0].d &x[0].c2 &x[1].s
26
Array struct ccc { char c1; char a[3]; char c2; }; struct ccc c[2];
0x00 &c[0].c1 &c[0].a[0] 0x04 &c[0].c2 &c[1].c1 &c[1].a[0] 0x08 &c[1].c2 0x0C 0x10 0x14
27
Array struct ccc { char c1; short a[3]; char c2; }; struct sss s[2];
0x00 &s[0].c1 &s[0].a[0] 0x04 0x08 &s[0].c2 &s[1].c1 0x0C &s[1].a[0] 0x10 &s[1].c2 0x14
28
Array struct iii { char c1; int a[3]; char c2; }; struct iii i[2];
0x00 0x04 0x08 0x0C 0x10 0x14 &s[0].c1 &x[0].i &s[0].c2 &s[1].c1
29
Understanding Pointers Buffer Overflow
30
Outline Understanding Pointers Buffer Overflow
31
Every pointer has a type
Pointers Every pointer has a type If the object has type T A pointer to this object has type T * Special void * type Represents a generic pointer malloc returns a generic pointer Every pointer has a value
32
Pointers are created with the & operator
Applied to lvalue expression Lvalue expression can appear on the left side of assignment Pointers are dereferenced with the operator * The result is a value having the type associated with the pointer Arrays and pointers are closed related The name of array can be viewed as a pointer constant ip[0] is equivalent to *ip
33
Addition and subtraction
Pointer Arithmetic Addition and subtraction p+i , p-i (result is a pointer) p-q (result is a int) Referencing & dereferencing *p, &E Subscription A[i], *(A+i)
34
Pointers can point to functions
void (*f)(int *) f is a pointer to function The function taken int * as argument The return type of the function is void Assignment makes f point to func f = func Notice the precedence of the operators void *f(int *) declares f is a function (void *) f(int *)
35
Pointer Declaration char **argv ; int (*daytab)[13] int (*comp)()
char (*(*x())[])() Function returning pointer to array[ ] of pointer to function returning char char (*(*x[3])())[5] Array[3] of pointer to function returning pointer to array[5] of char
36
C operators Operators Associativity () [] -> . ++ -- left to right
! ~ * & (type) sizeof right to left * / % left to right left to right << >> left to right < <= > >= left to right == != left to right & left to right ^ left to right | left to right && left to right || left to right ?: right to left = += -= *= /= %= &= ^= != <<= >>= right to left , left to right Note: Unary +, -, and * have higher precedence than binary forms
37
Parameter Passing Call by value f(xp) Call by reference f(&xp)
38
Out-of-Bounds Memory References
1 /* Implementation of library function gets() */ 2 char *gets(char *s) 3 { 4 int c; 5 char *dest = s; 6 int got_char = 0 ; /Has at least one character been read? */ 7 while ((c = getchar()) != ’\n’ && c != EOF) { 8 *dest++ = c; /* No bounds checking */ 9 gotchar = 1; 10 }
39
Out-of-Bounds Memory References
11 *dest++ = ’\0’; /* Terminate String */ 12 if (c == EOF && !gotchar) 13 return NULL; /* End of file or error */ 14 return s; 15 } 16 Type ctrl-d at keyboard means EOF
40
Out-of-Bounds Memory References
14 /* Read input line and write it back */ 15 void echo() 16 { 17 char buf[8]; /* Way too small ! */ 18 gets(buf); 19 puts(buf); 20 }
41
Out-of-Bounds Memory References
1 echo: 2 pushl %ebp Save %ebp on stack 3 movl %esp, %ebp 4 pushl %ebx Save %ebx 5 subl $20, %esp Allocate 20 bytes on stack 6 leal -12(%ebp), %ebx Compute buf as %ebp-12 7 movl %ebx, (%esp) Store buf at top of stack 8 call gets Call gets 9 movl %ebx, (%esp) Store buf at top of stack 10 call puts Call puts 11 addl $20, %esp Deallocate stack space 12 popl %ebx Restore %ebx 13 popl %ebp Restore %ebp 14 ret Return
42
Out-of-Bounds Memory References
Return address Saved %ebp Saved %ebx [7] [6] [5] [4] [3] [2] [1] [0] Stack frame for caller %ebp Stack frame for echo buf
43
Out-of-Bounds Memory References
Return address Saved %ebp [11] [10] [9] [8] [7] [6] [5] [4] [3] [2] [1] [0] Stack frame for caller %ebp Stack frame for echo buf
44
Out-of-Bounds Memory References
Return address [15] 1[4] [13] [12] [11] [10] [9] [8] [7] [6] [5] [4] [3] [2] [1] [0] Stack frame for caller %ebp Stack frame for echo buf
45
Out-of-Bounds Memory References
[19] [18] [17] [16] [15] 1[4] [13] [12] [11] [10] [9] [8] [7] [6] [5] [4] [3] [2] [1] [0] Stack frame for caller %ebp Stack frame for echo buf
46
Out-of-Bounds Memory References
1 /* This is very low-quality code. It is intended to illustrate bad programming practices. See Problem */ 4 char *getline() 5 { 6 char buf[8]; 7 char *result; 8 gets(buf); 9 result = malloc(strlen(buf)); 10 strcpy(result, buf); 11 return result; 12 }
47
Out-of-Bounds Memory References
c0 <getline>: c0: push %ebp c1: 89 e5 mov %esp,%ebp c3: 83 ec 28 sub $0x28,%esp c6: 89 5d f4 mov %ebx,-0xc(%ebp) c9: f8 mov %esi,-0x8(%ebp) cc: 89 7d fc mov %edi,-0x4(%ebp) Diagram stack at this point cf: 8d 75 ec lea x14(%ebp),%esi d2: mov %esi,(%esp) 80485d5: e8 a3 ff ff ff call d <gets> Modify diagram to show stack contents at this point
48
Out-of-Bounds Memory References
2 push %ebp 3 mov %esp,%ebp 4 sub $0x28,%esp 5 mov %ebx,-0xc(%ebp) 6 mov %esi,-0x8(%ebp) 7 mov %edi,-0x4(%ebp) Diagram stack at this point 8 lea x14(%ebp),%esi 9 mov %esi,(%esp) call d <gets> Return address bf ff fc 94 %ebp 0x01 %ebx 0x02 %edi 0x03 %esi
49
Out-of-Bounds Memory References
%ebp 2 push %ebp 3 mov %esp,%ebp 4 sub $0x28,%esp 5 mov %ebx,-0xc(%ebp) 6 mov %esi,-0x8(%ebp) 7 mov %edi,-0x4(%ebp) Diagram stack at this point 8 lea x14(%ebp),%esi 9 mov %esi,(%esp) call d <gets> bf ff fc 94 02 03 01 Return address Saved %ebp Saved %edi Saved %esi Saved %ebx bf ff fc 94 %ebp 0x01 %ebx 0x02 %edi 0x03 %esi
50
Out-of-Bounds Memory References
%ebp 2 push %ebp 3 mov %esp,%ebp 4 sub $0x28,%esp 5 mov %ebx,-0xc(%ebp) 6 mov %esi,-0x8(%ebp) 7 mov %edi,-0x4(%ebp) 8 lea x14(%ebp),%esi 9 mov %esi,(%esp) call d <gets> Modify diagram to show stack contents at this point Return address Saved %ebp Saved %edi Saved %esi Saved %ebx bf ff fc 94 %ebp 0x01 %ebx 0x02 %edi 0x03 %esi “ ”
51
Malicious Use of Buffer Overflow
Stack after call to gets() B foo stack frame bar stack frame exploit code pad data written by gets() void bar() { char buf[64]; gets(buf); ... } void foo(){ bar(); return address A
52
Malicious Use of Buffer Overflow
Input string contains byte representation of executable code Overwrite return address with address of buffer When bar() executes ret, will jump to exploit code
53
The Famous Internet Worm of November 1988
To gain access to many of the computers across the Internet 4 different ways One was a buffer overflow attack on the fingerd Hundreds of machines were effectively paralyzed The author of the worm was caught and prosecuted. He was sentenced to 3 years probation 400 hours of community service and a $10,500 fine
54
The Famous Internet Worm of November 1988
Steps invoked finger with an appropriate string Made a process at a remote site have a buffer overflow executed code that gave the worm access to the remote system The worm replicated itself and consumed virtually all of the machine’s computing resources
55
Making a vulnerability to have a stack overflow
Stack Randomization Making a vulnerability to have a stack overflow Try the right string on your own computer The string contains The exploit code and The address of this code Put the string to the remote computer Stack randomization makes it hard to determine the address of the exploit code
56
3 printf("local at %p\n", &local); 4 return 0; 5 }
Stack Randomization 1 int main() { 2 int local; 3 printf("local at %p\n", &local); 4 return 0; 5 } Running the code 10,000 times on a Linux (maybe ) machine in 32-bit mode the addresses ranged from 0xff7fa7e0 to 0xffffd7e0 A range of around 223
57
Running in 64-bit mode on the newer machine The addresses ranged from
Stack Randomization Running in 64-bit mode on the newer machine The addresses ranged from 0x7fff to 0x7ffffff98664 A range of nearly 232 Address-space layout randomization (ASLR) each time a program is run different parts of the program are loaded into different regions of memory code, data, heap data, library code, stack
58
Include a “nop sled” before the actual exploit code
Stack Randomization Nop sled a program “slides” through a long sequence of “nop” Nop no operation instruction Include a “nop sled” before the actual exploit code If insert 256-byte nop sled Need to guess 215 starting addresses (no too much) for 32-bit machine Still have too many 224 guesses
59
Stack Corruption Detection
Return address Saved %ebp Saved %ebx Canary [7] [6] [5] [4] [3] [2] [1] [0] Stack frame for caller %ebp Stack frame for echo buf
60
Stack Corruption Detection
1 echo: 2 pushl %ebp 3 movl %esp, %ebp 4 pushl %ebx 5 subl $20, %esp 6 movl %gs:20, %eax Retrieve canary 7 movl %eax, -8(%ebp) Store on stack 8 xorl %eax, %eax Zero out register 9 leal -16(%ebp), %ebx Compute buf as %ebp-16 10 movl %ebx, (%esp) Store buf at top of stack 11 call gets Call gets 12 movl %ebx, (%esp) Store buf at top of stack 13 call puts Call puts
61
Stack Corruption Detection
14 movl -8(%ebp), %eax Retrieve canary 15 xorl %gs:20, %eax Compare to stored value 16 je .L19 If =, goto ok 17 call __stack_chk_fail Stack corrupted! 18 .L19: ok: 19 addl $20, %esp Normal return ... 20 popl %ebx 21 popl %ebp 22 ret %gs:20 Segmented addressing which appeared in and seldom used today It is marked as read only
62
Limiting Executable Code Regions
Page 4k bytes As a protected unit by OS Should be marked as “readable”, “writable” and “executable” 3 bits are required Originally Intel merged the “readable” and “executable” into one The exploit code in the stack can be executed AMD introduced “NX” in X86-64 Now there 3 bits How about “JIT”?
63
Return-oriented Programming
Code Reuse Attack Return-oriented Programming Find code gadgets in existed code base (e.g. libc) Push address of gadgets on the stack Leverage ‘ret’ to connect code gadgets No code injection Solutions Return-less kernels Heuristic means New Attacks: Jump-oriented Use gadget as dispatcher Address C Address B Address A return addr saved ebp A B C
64
Motivation: Code Reuse Attack
65
X86-64 Representation
66
Outline Procedures and Stack Alignment Byte Ordering
67
Example: swap() IA32 swap: swap(int *xp, int *yp) pushl %ebp
movl %esp,%ebp pushl %ebx movl 12(%ebp),%ecx movl 8(%ebp),%edx movl (%ecx),%eax movl (%edx),%ebx movl %eax,(%edx) movl %ebx,(%ecx) movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret IA32 void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } Setup Body Finish
68
Example: swap() x86-64 swap: swap(int *xp, int *yp) movl (%rdi), %edx
movl (%rsi), %eax movl %eax, (%rdi) movl %edx, (%rsi) retq x86-64 void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; }
69
Operands passed in registers
Example: swap() swap: movl (%rdi), %edx movl (%rsi), %eax movl %eax, (%rdi) movl %edx, (%rsi) retq Operands passed in registers First (xp) in %rdi Second (yp) in %rsi 64-bit pointers No stack operation required 32-bit data Data held in register %eax and %edx movl operation
70
Example: swap() Swap long int in 64-bit swap: swap(long int *xp,
movq (%rdi), %rdx movq (%rsi), %rax movq %rax, (%rdi) movq %rdx, (%rsi) retq Swap long int in 64-bit void swap(long int *xp, long int *yp) { long int t0 = *xp; long int t1 = *yp; *xp = t1; *yp = t0; } 64-bit data Data held in registers %rax and %rdx movq operation “q” stands for quar-word
71
Procedures - Stack IA32/Linux Stack Frame Caller Stack Frame
Arguments for this call Return Address (pushed by “call”) Callee Stack Frame Old %ebp (saved by “push %ebp”) Saved registers Local variable s Arguments for next call Arguments Ret Addr Old %ebp %ebp frame pointer Saved registers Local variables Arguments %esp stack pointer
72
IA32/Linux Register Usage
Procedures - Register IA32/Linux Register Usage %eax, %edx, %ecx Caller saves prior the call if values are used by later %eax Return integer value %ebx, %esi, %edi Callee saves if want to used them %esp, %ebp special Caller-Save %eax %edx %ecx Callee-Save %ebx %esi %edi Special %esp %ebp
73
X86-64/Linux Register Usage
Procedures - Register X86-64/Linux Register Usage Caller-Save %rax %rcx %rdx %rsi %rdi %r8 %r9 Callee-Save %rbx %rbp %r10 %r12 %r13 %r14 %r15 Special %rsp, %r11 %rax %rax %r8 %r8 %rbx %rbx %r9 %r9 %rcx %rcx %r10 %r10 %rdx %rdx %r11 %r11 %rsi %rsi %r12 %r12 %rdi %rdi %r13 %r13 %rsp %rsp %r14 %r14 %rbp %rbp %r15 %r15
74
X86-64/Linux Register Usage
Procedures - Register X86-64/Linux Register Usage Arguments passed via regs %rcx %rdx %rsi %rdi %r8 %r9 If more than 6 integer parameters, then pass rest on stack Return value by %rax No frame pointer Special %rsp stack pointer %r11 used for linking %rax ret %rax %r8 %r8 arg#5 %rbx %r9 arg#6 %r9 %rcx arg#4 %rcx %r10 %rdx arg#3 %rdx %r11 %r11 link %rsi %rsi arg#2 %r12 %rdi %rdi arg#1 %r13 %rsp stack %rsp %r14 %rbp %r15
75
Procedures - Stack x86-64/Linux Stack Frame Caller Stack Frame
Arguments passed via registers Return Address (pushed by “call”) Callee Stack Frame Saved registers Local variables Ret Addr Saved registers Local variables %rsp stack pointer
76
Operands passed in registers No stack operations required (except ret)
X86-64 Swap void swap(long *xp, long *yp) { long t0 = *xp; long t1 = *yp; *xp = t1; *yp = t0; } swap: movq (%rdi), %rdx movq (%rsi), %rax movq %rax, (%rdi) movq %rdx, (%rsi) ret Operands passed in registers First (xp) in %rdi, second (yp) in %rsi No stack operations required (except ret) Avoid stack Can hold all local information in registers
77
Local Variables in Stack
void swap_a(long *xp, long *yp) { volatile long loc[2]; loc[0] = *xp; loc[1] = *yp; *xp = loc[1]; *yp = loc[0]; } swap_a: movq (%rdi), %rax movq %rax, -24(%rsp) movq (%rsi), %rax movq %rax, -16(%rsp) movq -16(%rsp), %rax movq %rax, (%rdi) movq -24(%rsp), %rax movq %rax, (%rsi) ret ret ptr %rsp -8 unused Avoid Stack Pointer change Can hold all information within small windows beyond stack pointer -16 loc[1] -24 loc[0]
78
Without Stack Frame No value held while swap being invoked
long scount = 0 void swap_b(long a[], int i) { swap(&a[i], &a[i+1]); scount++ } No value held while swap being invoked No callee save registers needed swap_b: movslq %esi,%rsi # sign extend leaq (%rdi,%rsi,8), %rdi # &a[i] leaq 8(%rdi,%rsi,8),%rsi # &a[i+1] call swap # swap() incq scount(%rip) # scount++; ret . . . ret ptr1 ret ptr2 %rsp execute in swap
79
Call using Jump Directly return from swap
long scount = 0 void swap_c(long a[], int i) { swap(&a[i], &a[i+1]); } Directly return from swap Possible since swap is a “tail call “ swap_c: movslq %esi,%rsi # Sign extend leaq (%rdi,%rsi,8), %rdi # &a[i] leaq 8(%rdi, rsi,8), %rsi# &a[i+1] jmp swap # swap() . . . ret ptr1 %rsp execute in swap
80
Stack Frame Example swap_d:
movq %rbx, -16(%rsp) movslq %esi,%rbx movq %r12, -8(%rsp) movq %rdi, %r12 leaq (%rdi,%rbx,8), %rdi subq $16, %rsp leaq 8(%rdi), %rsi call swap movq (%r12,%rbx,8), %rax addq %rax, sum(%rip) movq (%rsp), %rbx movq 8(%rsp), %r12 addq $16, %rsp ret long sum = 0 void swap_d(long a[], int i) { swap(a[i], a[i+1]); sum += a[i]; } Keep values of a and i in callee save registers Must set up stack frame to save these registers
81
Understanding x86-64 Stack Frame
swap_d: movq %rbx, -16(%rsp) movslq %esi,%rbx movq %r12, -8(%rsp) movq %rdi, %r12 leaq (%rdi,%rbx,8), %rdi subq $16, %rsp leaq 8(%rdi), %rsi . . . addq %rax, sum(%rip) movq (%rsp), %rbx movq 8(%rsp), %r12 addq $16, %rsp ret ret ptr %rsp # save %rbx %r12 -8 # save %r12 %rbx -16
82
Understanding x86-64 Stack Frame
swap_d: movq %rbx, -16(%rsp) movslq %esi,%rbx movq %r12, -8(%rsp) movq %rdi, %r12 leaq (%rdi,%rbx,8), %rdi subq $16, %rsp leaq 8(%rdi), %rsi . . . addq %rax, sum(%rip) movq (%rsp), %rbx movq 8(%rsp), %r12 addq $16, %rsp ret ret ptr # save %rbx %r12 +8 # save %r12 %rbx %rsp # move stack frame # restore %rbx # restore %r12
83
Understanding x86-64 Stack Frame
swap_d: movq %rbx, -16(%rsp) movslq %esi,%rbx movq %r12, -8(%rsp) movq %rdi, %r12 leaq (%rdi,%rbx,8), %rdi subq $16, %rsp leaq 8(%rdi), %rsi . . . addq %rax, sum(%rip) movq (%rsp), %rbx movq 8(%rsp), %r12 addq $16, %rsp ret ret ptr %rsp # save %rbx %r12 -8 # save %r12 %rbx -16 # move stack frame # restore %rbx # restore %r12 # move stack frame
84
Features of Stack Frame
Allocate entire frame at once All stack accesses can be relative to %rsp Do by decrementing stack pointer Can delay allocation Simple deallocation Increment stack pointer No base/frame pointer needed
85
Alignment IA32 x86-64 Bytes Type Alignment char No short 02
1 char No 2 short 02 4 int, float, pointer 002 int, float 8 double 0002(Win) 002(Lin) double, pointer 0002 12/16 long double 00002
86
Example X86-64 or IA32 Windows: IA32 Linux
struct s1 { char c; int i[2]; double d; } *p; X86-64 or IA32 Windows: K = 8; due to double element C 3bytes i[0] i[1] 4bytes d p+0 p+4 p+8 p+16 p+24 IA32 Linux K = 4; double treated like a 4-byte data type C 3bytes i[0] i[1] d p+0 p+4 p+8 p+12 p+20
87
Byte Ordering IA32 (Little Endian) Output on IA32
0xf0 0xf1 0xf2 0xf3 0xf4 0xf5 0xf6 0xf7 C[0] C[1] C[2] C[3] C[4] C[5] C[6] C[7] S[0] S[1] S[2] S[3] LSB MSB LSB MSB I[0] I[1] LSB MSB L[0] Output on IA32 Characters 0-7 = [0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7] Shorts = [0xf1f0,0xf3f2,0xf5f4,0xf7f6] Ints = [0xf3f2f1f0,0xf7f6f5f4] Long = [0xf3f2f1f0]
88
Byte Ordering X86-64 (Little Endian) Output on x86-64
0xf0 0xf1 0xf2 0xf3 0xf4 0xf5 0xf6 0xf7 C[0] C[1] C[2] C[3] C[4] C[5] C[6] C[7] S[0] S[1] S[2] S[3] LSB MSB LSB MSB I[0] I[1] LSB MSB L[0] Output on x86-64 Characters 0-7 = [0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7] Shorts = [0xf1f0,0xf3f2,0xf5f4,0xf7f6] Ints = [0xf3f2f1f0,0xf7f6f5f4] Long = [0xf7f6f5f4f3f2f1f0]
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.