condition codes: exercise (3 solution) // result = %rbx - %rax rax and rbx not equal not zero // 2**63 - 1 26 cmpq %rax, %rbx movq $0x8000000000000000, %rbx movq $0x7FFFFFFFFFFFFFFF, %rax // 2**63 (unsigned); -2**63 (signed) − 2 64 + 1 1 (overfmow) as signed: − 2 63 − 2 63 − 1 � � ❳❳❳❳❳ ✘ = ✘✘✘✘✘ ❳ as unsigned: 2 63 − 2 63 − 1 � � = 1 ZF = 0 (false)
condition codes: exercise (3 solution) // result = %rbx - %rax rax and rbx not equal not zero // 2**63 - 1 26 cmpq %rax, %rbx movq $0x8000000000000000, %rbx movq $0x7FFFFFFFFFFFFFFF, %rax // 2**63 (unsigned); -2**63 (signed) − 2 64 + 1 1 (overfmow) as signed: − 2 63 − 2 63 − 1 � � ❳❳❳❳❳ ✘ = ✘✘✘✘✘ ❳ as unsigned: 2 63 − 2 63 − 1 � � = 1 ZF = 0 (false)
condition codes: exercise (3 solution) // 2**63 - 1 not negative rax and rbx not equal not zero 26 // result = %rbx - %rax movq $0x8000000000000000, %rbx cmpq %rax, %rbx movq $0x7FFFFFFFFFFFFFFF, %rax // 2**63 (unsigned); -2**63 (signed) − 2 64 + 1 1 (overfmow) as signed: − 2 63 − 2 63 − 1 � � ❳❳❳❳❳ ✘ = ✘✘✘✘✘ ❳ as unsigned: 2 63 − 2 63 − 1 � � = 1 ZF = 0 (false) SF = 0 (false) rax < = rbx (if correct)
condition codes: exercise (3 solution) // 2**63 - 1 incorrect for signed overfmow as signed not negative rax and rbx not equal not zero 26 movq $0x7FFFFFFFFFFFFFFF, %rax // 2**63 (unsigned); -2**63 (signed) movq $0x8000000000000000, %rbx cmpq %rax, %rbx // result = %rbx - %rax − 2 64 + 1 1 (overfmow) as signed: − 2 63 − 2 63 − 1 � � ❳❳❳❳❳ ✘ = ✘✘✘✘✘ ❳ as unsigned: 2 63 − 2 63 − 1 � � = 1 ZF = 0 (false) SF = 0 (false) rax < = rbx (if correct) OF = 1 (true)
condition codes: exercise (3 solution) // 2**63 - 1 correct for unsigned no overfmow as unsigned incorrect for signed overfmow as signed not negative rax and rbx not equal not zero 26 movq $0x7FFFFFFFFFFFFFFF, %rax // 2**63 (unsigned); -2**63 (signed) movq $0x8000000000000000, %rbx cmpq %rax, %rbx // result = %rbx - %rax − 2 64 + 1 1 (overfmow) as signed: − 2 63 − 2 63 − 1 � � ❳❳❳❳❳ ✘ = ✘✘✘✘✘ ❳ as unsigned: 2 63 − 2 63 − 1 � � = 1 ZF = 0 (false) SF = 0 (false) rax < = rbx (if correct) OF = 1 (true) CF = 0 (false)
while-to-assembly (1) while (x >= 0) { foo() x--; } start_loop: if (x < 0) goto end_loop; foo() x--; goto start_loop: end_loop: 27
while-to-assembly (1) while (x >= 0) { foo() x--; } start_loop: if (x < 0) goto end_loop; foo() x--; goto start_loop: end_loop: 27
while-to-assembly (2) start_loop: if (x < 0) goto end_loop; foo() x--; goto start_loop: end_loop: start_loop: cmpq $0, %r12 jl end_loop // jump if r12 - 0 >= 0 call foo subq $1, %r12 jmp start_loop 28
while exercise addq $1, %rbx end_loop: jmp start_loop addq $1, %rbx call foo jge end_loop subq %rbx, %rax movq $10, %rax start_loop: // version C end_loop: jmp start_loop call foo while (b < 10) { foo(); b += 1; } jge end_loop cmpq $10, %rbx start_loop: // version B jl start_loop cmpq $10, %rbx addq $1, %rbx call foo start_loop: // version A translations? 29 Assume b is in callee-saved register %rbx. Which are correct assembly
b += 1; while exercise: translating? while (b < 10) { foo(); b += 1; } start_loop: if (b < 10) goto end_loop; foo(); goto start_loop; end_loop: 30
while exercise: translating? while (b < 10) { foo(); b += 1; } start_loop: if (b < 10) goto end_loop; foo(); goto start_loop; end_loop: 30 b += 1;
while — levels of optimization subq %rbx, %rax ... ... ... cmpq $10, %rbx jge end_loop movq $10, %rax movq %rax, %rbx jne start_loop start_loop: call foo decq %rbx jne start_loop movq $10, %rbx end_loop: end_loop: cmpq $10, %rbx while (b < 10) { foo(); b += 1; } end_loop: start_loop: cmpq $10, %rbx jge end_loop call foo addq $1, %rbx jmp start_loop ... addq $1, %rbx ... ... ... cmpq $10, %rbx jge end_loop start_loop: call foo 31
while — levels of optimization subq %rbx, %rax ... ... ... cmpq $10, %rbx jge end_loop movq $10, %rax movq %rax, %rbx jne start_loop start_loop: call foo decq %rbx jne start_loop movq $10, %rbx end_loop: end_loop: cmpq $10, %rbx while (b < 10) { foo(); b += 1; } end_loop: start_loop: cmpq $10, %rbx jge end_loop call foo addq $1, %rbx jmp start_loop ... addq $1, %rbx ... ... ... cmpq $10, %rbx jge end_loop start_loop: call foo 31
while — levels of optimization subq %rbx, %rax ... ... ... cmpq $10, %rbx jge end_loop movq $10, %rax movq %rax, %rbx jne start_loop start_loop: call foo decq %rbx jne start_loop movq $10, %rbx end_loop: end_loop: cmpq $10, %rbx while (b < 10) { foo(); b += 1; } end_loop: start_loop: cmpq $10, %rbx jge end_loop call foo addq $1, %rbx jmp start_loop ... addq $1, %rbx ... ... ... cmpq $10, %rbx jge end_loop start_loop: call foo 31
compiling switches (1) je code_for_1 jmp code_for_default ... je code_for_3 cmpq $3, %rax je code_for_2 cmpq $2, %rax cmpq $1, %rax switch (a) { // same as if statement? } default : ... ... case 2: ...; break ; case 1: ...; break ; 32
compiling switches (2) jl code_for_less_than_50 ... jl less_than_25_cases cmpq $25, %rax code_for_less_than_50: ... jl code_for_50_to_75 cmpq $75, %rax cmpq $50, %rax switch (a) { // binary search } default : ... case 100: ...; break ; ... case 2: ...; break ; case 1: ...; break ; 33
compiling switches (3) jl code_for_default ... .quad code_for_4 .quad code_for_3 .quad code_for_2 .quad code_for_1 // .quad = 64-bit (4 x 16) constant // not instructions table: cmpq $1, %rax switch (a) { jg code_for_default cmpq $100, %rax // jump table } default : ... case 100: ...; break ; ... case 2: ...; break ; case 1: ...; break ; 34 jmp *table(,%rax,8)
computed jumps cmpq $100, %rax jg code_for_default cmpq $1, %rax jl code_for_default // table of pointers to instructions ... table: .quad code_for_1 .quad code_for_2 .quad code_for_3 ... 35 // jump to memory[table + rax * 8] jmp *table(,%rax,8) // intel: jmp QWORD PTR[rax*8 + table]
C Data Types 8 8 anything * 8 void * 8 double 4 float long Varies between machines(!). For this course: 4 int 2 short 1 char size (bytes) type 36
C Data Types 8 8 anything * 8 void * 8 double 4 float long Varies between machines(!). For this course: 4 int 2 short 1 char size (bytes) type 36
C Data Types 8 8 anything * 8 void * 8 double 4 float long Varies between machines(!). For this course: 4 int 2 short 1 char size (bytes) type 36
x == 4 is an int truth bool 1 if true; 0 if false 37
truth bool 1 if true; 0 if false 37 x == 4 is an int
false values in C 0 including null pointers — 0 cast to a pointer 38
short-circuit ( || ) false zero() one() > 1 one() > 1 OR true 8 false false true true true true } return 0; 1 int main() { #include <stdio.h> 2 int zero() { printf("zero()\n"); return 0; } 3 int one() { printf("one()\n"); return 1; } 4 5 7 printf("> %d\n", zero() || one()); 6 printf("> %d\n", one() || zero()); 39 ␣ ␣
short-circuit ( || ) false zero() one() > 1 one() > 1 OR true 8 false false true true true true } return 0; 1 int main() { #include <stdio.h> 2 int zero() { printf("zero()\n"); return 0; } 3 int one() { printf("one()\n"); return 1; } 4 5 7 printf("> %d\n", zero() || one()); 6 printf("> %d\n", one() || zero()); 39 ␣ ␣
short-circuit ( || ) false zero() one() > 1 one() > 1 OR true 8 false false true true true true } return 0; 1 int main() { #include <stdio.h> 2 int zero() { printf("zero()\n"); return 0; } 3 int one() { printf("one()\n"); return 1; } 4 5 7 printf("> %d\n", zero() || one()); 6 printf("> %d\n", one() || zero()); 39 ␣ ␣
short-circuit ( || ) false zero() one() > 1 one() > 1 OR true 8 false false true true true true } return 0; 1 int main() { #include <stdio.h> 2 int zero() { printf("zero()\n"); return 0; } 3 int one() { printf("one()\n"); return 1; } 4 5 7 printf("> %d\n", zero() || one()); 6 printf("> %d\n", one() || zero()); 39 ␣ ␣
short-circuit ( || ) false zero() one() > 1 one() > 1 OR true 8 false false true true true true } return 0; 1 int main() { #include <stdio.h> 2 int zero() { printf("zero()\n"); return 0; } 3 int one() { printf("one()\n"); return 1; } 4 5 7 printf("> %d\n", zero() || one()); 6 printf("> %d\n", one() || zero()); 39 ␣ ␣
short-circuit ( && ) false zero() > 0 one() zero() > 0 AND true 8 false false false true false true } return 0; 1 int main() { #include <stdio.h> 2 int zero() { printf("zero()\n"); return 0; } 3 int one() { printf("one()\n"); return 1; } 4 5 7 printf("> %d\n", zero() && one()); 6 printf("> %d\n", one() && zero()); 40 ␣ ␣
short-circuit ( && ) false zero() > 0 one() zero() > 0 AND true 8 false false false true false true } return 0; 1 int main() { #include <stdio.h> 2 int zero() { printf("zero()\n"); return 0; } 3 int one() { printf("one()\n"); return 1; } 4 5 7 printf("> %d\n", zero() && one()); 6 printf("> %d\n", one() && zero()); 40 ␣ ␣
short-circuit ( && ) false zero() > 0 one() zero() > 0 AND true 8 false false false true false true } return 0; 1 int main() { #include <stdio.h> 2 int zero() { printf("zero()\n"); return 0; } 3 int one() { printf("one()\n"); return 1; } 4 5 7 printf("> %d\n", zero() && one()); 6 printf("> %d\n", one() && zero()); 40 ␣ ␣
short-circuit ( && ) false zero() > 0 one() zero() > 0 AND true 8 false false false true false true } return 0; 1 int main() { #include <stdio.h> 2 int zero() { printf("zero()\n"); return 0; } 3 int one() { printf("one()\n"); return 1; } 4 5 7 printf("> %d\n", zero() && one()); 6 printf("> %d\n", one() && zero()); 40 ␣ ␣
short-circuit ( && ) false zero() > 0 one() zero() > 0 AND true 8 false false false true false true } return 0; 1 int main() { #include <stdio.h> 2 int zero() { printf("zero()\n"); return 0; } 3 int one() { printf("one()\n"); return 1; } 4 5 7 printf("> %d\n", zero() && one()); 6 printf("> %d\n", one() && zero()); 40 ␣ ␣
strings in C int main() { const char *hello = "Hello World!"; ... } 0x4005C0 hello (on stack/register) read-only data 41 … 'H''e''l''l''o'' ␣ ''W''o''r''l''d''!''\0' …
pointer arithmetic 'W''o''r''l''d''!''\0' … read-only data hello + 0 0x4005C0 hello + 5 0x4005C5 hello[0] is 'H' 42 … 'H''e''l''l''o'' ␣ ' *(hello + 5) is ' ␣ ' *(hello + 0) is 'H' hello[5] is ' ␣ '
pointer arithmetic 'W''o''r''l''d''!''\0' … read-only data hello + 0 0x4005C0 hello + 5 0x4005C5 hello[0] is 'H' 42 … 'H''e''l''l''o'' ␣ ' *(hello + 5) is ' ␣ ' *(hello + 0) is 'H' hello[5] is ' ␣ '
pointer arithmetic 'W''o''r''l''d''!''\0' … read-only data hello + 0 0x4005C0 hello + 5 0x4005C5 hello[0] is 'H' 42 … 'H''e''l''l''o'' ␣ ' *(hello + 5) is ' ␣ ' *(hello + 0) is 'H' hello[5] is ' ␣ '
arrays and pointers *(foo + bar) exactly the same as foo[bar] 43 arrays ‘decay’ into pointers
arrays of non-bytes pointer = pointer + 2; assembly: addq $8, … // numbers is 20, 11, 30, 13 8 // numbers[2] = 30; *pointer = 30; 7 /* adds 8 (2 ints) to address */ 6 5 array[2] and *(array + 2) still the same // numbers[0] = 20; *pointer = 20; 4 3 int *pointer; 2 int numbers[4] = {10, 11, 12, 13}; 1 44 pointer = numbers;
arrays of non-bytes pointer = pointer + 2; assembly: addq $8, … // numbers is 20, 11, 30, 13 8 // numbers[2] = 30; *pointer = 30; 7 /* adds 8 (2 ints) to address */ 6 5 array[2] and *(array + 2) still the same // numbers[0] = 20; *pointer = 20; 4 3 int *pointer; 2 int numbers[4] = {10, 11, 12, 13}; 1 44 pointer = numbers;
exercise 1 C. "baz" E. something else/crash B. "zao" D. "bao" Final value of foo ? *(foo + 1) = 'a'; 8 pointer[0] = 'z'; 7 45 6 *pointer = 'b'; 5 4 char *pointer; 3 // {'f', 'o', 'o', '\0'} 2 char foo[4] = "foo"; pointer = foo; pointer = pointer + 2; A. "fao"
exercise 1 C. "baz" E. something else/crash B. "zao" D. "bao" Final value of foo ? *(foo + 1) = 'a'; 8 pointer[0] = 'z'; 7 45 6 *pointer = 'b'; 5 4 char *pointer; 3 // {'f', 'o', 'o', '\0'} 2 char foo[4] = "foo"; pointer = foo; pointer = pointer + 2; A. "fao"
exercise explanation better style: *pointer = 'z'; foo + 1 == &foo[0] + 1 pointer foo (on stack) 'f''o''o''\0' *(foo + 1) = 'a'; 8 pointer[0] = 'z'; 7 6 *pointer = 'b'; 5 pointer = foo; 4 char *pointer; 3 // {'f', 'o', 'o', '\0'} 2 char foo[4] = "foo"; 1 better style: foo[1] = 'a'; 46 pointer = pointer + 2;
exercise explanation better style: *pointer = 'z'; foo + 1 == &foo[0] + 1 pointer foo (on stack) 'f''o''o''\0' *(foo + 1) = 'a'; 8 pointer[0] = 'z'; 7 6 *pointer = 'b'; 5 pointer = foo; 4 char *pointer; 3 // {'f', 'o', 'o', '\0'} 2 char foo[4] = "foo"; 1 better style: foo[1] = 'a'; 46 pointer = pointer + 2;
exercise explanation better style: *pointer = 'z'; foo + 1 == &foo[0] + 1 pointer foo (on stack) 'b''o''o''\0' *(foo + 1) = 'a'; 8 pointer[0] = 'z'; 7 6 *pointer = 'b'; 5 pointer = foo; 4 char *pointer; 3 // {'f', 'o', 'o', '\0'} 2 char foo[4] = "foo"; 1 better style: foo[1] = 'a'; 46 pointer = pointer + 2;
exercise explanation better style: *pointer = 'z'; foo + 1 == &foo[0] + 1 pointer foo (on stack) 'b''o''o''\0' *(foo + 1) = 'a'; 8 pointer[0] = 'z'; 7 6 *pointer = 'b'; 5 pointer = foo; 4 char *pointer; 3 // {'f', 'o', 'o', '\0'} 2 char foo[4] = "foo"; 1 better style: foo[1] = 'a'; 46 pointer = pointer + 2;
exercise explanation better style: *pointer = 'z'; foo + 1 == &foo[0] + 1 pointer foo (on stack) 'b''o''z''\0' *(foo + 1) = 'a'; 8 pointer[0] = 'z'; 7 6 *pointer = 'b'; 5 pointer = foo; 4 char *pointer; 3 // {'f', 'o', 'o', '\0'} 2 char foo[4] = "foo"; 1 better style: foo[1] = 'a'; 46 pointer = pointer + 2;
exercise explanation better style: *pointer = 'z'; foo + 1 == &foo[0] + 1 pointer foo (on stack) 'b''a''z''\0' *(foo + 1) = 'a'; 8 pointer[0] = 'z'; 7 6 *pointer = 'b'; 5 pointer = foo; 4 char *pointer; 3 // {'f', 'o', 'o', '\0'} 2 char foo[4] = "foo"; 1 better style: foo[1] = 'a'; 46 pointer = pointer + 2;
a note on precedence &foo[42] is the same as &(foo[42]) ( not (&foo)[42] ) *foo[42] is the same as *(foo[42]) ( not (*foo)[42] ) *foo++ is the same as *(foo++) ( not (*foo)++ ) 47
arrays: not quite pointers (1) int array[100]; int *pointer; Legal: pointer = array; Illegal: array = pointer; 48 same as pointer = &(array[0]);
arrays: not quite pointers (1) int array[100]; int *pointer; Legal: pointer = array; Illegal: array = pointer; 48 same as pointer = &(array[0]); ❤❤❤❤❤❤❤❤❤❤❤❤❤❤ ✭ ✭✭✭✭✭✭✭✭✭✭✭✭✭✭ ❤
arrays: not quite pointers (2) int array[100]; int *pointer = array; sizeof (array) == 400 size of all elements sizeof (pointer) == 8 size of address sizeof (&array[0]) == ??? ( &array[0] same as &(array[0]) ) 49
arrays: not quite pointers (2) int array[100]; int *pointer = array; sizeof (array) == 400 size of all elements sizeof (pointer) == 8 size of address sizeof (&array[0]) == ??? ( &array[0] same as &(array[0]) ) 49
arrays: not quite pointers (2) int array[100]; int *pointer = array; sizeof (array) == 400 size of all elements sizeof (pointer) == 8 size of address sizeof (&array[0]) == ??? ( &array[0] same as &(array[0]) ) 49
interlude: command line tips cr4bd@reiss-lenovo:~$ man man 50
man man 51
man man 52
man chmod 53
chmod chmod --recursive og-r /home/USER others and group (student) - remove read user (yourself) / group / others - remove / + add read / write / execute or search 54
chmod chmod --recursive og-r /home/USER others and group (student) - remove read user (yourself) / group / others - remove / + add read / write / execute or search 54
chmod chmod --recursive og-r /home/USER others and group (student) - remove read user (yourself) / group / others - remove / + add read / write / execute or search 54
tar the standard Linux/Unix fjle archive utility Table of contents: tar tf filename.tar eXtract: tar xvf filename.tar Create: tar cvf filename.tar directory ( v : verbose; f : fjle — default is tape) 55
Tab completion and history 56
struct struct rational { int numerator; int denominator; }; // ... struct rational two_and_a_half; struct rational *pointer = &two_and_a_half; printf("%d/%d \n ", pointer->numerator, pointer->denominator); 57 two_and_a_half.numerator = 5; two_and_a_half.denominator = 2;
Recommend
More recommend