Systems Group Department of Computer Science ETH Zürich Exercise Session 2 Systems Programming and Computer Architecture Herbstsemester 216
Agenda Linux vs. Windows Working with SVN Exercise 1: bitcount() Questions Regarding the Lecture More on C-Programming Outlook to Exercise 2
Linux vs. Windows You CAN use Windows for exercises BUT stack frame layout is different alignment is different compiler (and hence assembly-code) is different linux-gcc different from cygwin-gcc All you learn about those things in the lecture refers to Linux However: If you know all the differences between Linux and Windows, this is of course also a plus
SVN Read the hand-in instructions on the assignment sheet carefully Several students submitted their solutions in a wrongly named file Hand in at least something, even if you just solved one puzzle Systems Programming and Computer Architecture 4
SVN Subversion: a tool for software versioning and revision control It s ok to submit code that contains known bugs, but make sure to leave a comment Your team mate may know hot to fix it, but must be aware of it NEVER commit code that does not compile. Your team mates will be thankful Systems Programming and Computer Architecture 5
SVN Subversion is good for versioning text-based files Do only commit your source files Do NOT commit compiled binary files Unless really needed Systems Programming and Computer Architecture 6
Making sure it compiles Obviously gcc program.c In this assignment it s a bit different Use the tools in the tar ball to do the checks Test for syntax:./dlc bits.c./dlc produces no output if all is fine Test for semantics: make./btest this command will create your./btest (make sure your file is named bits.c here) this will test your solution Systems Programming and Computer Architecture 7
Exercise 1 Beat the Prof Only works if your program compiles (use gcc-89 on Linux to be sure) Only works if your program follows the specified structure (which means dlc produces no output)
Exercise 1 bitcount(x) Naïve Approach: (x & 1) + ((x >> 1) & 1) + + ((x >> 31) & 1) requires: 31 +, 32 &, 31 >> 94 operators!! Another Idea: Divide 32 bits into segements of «bit counters» accumumulate bit 25 to 32 accumumulate bit 9 to 16 accumumulate bit 17 to 24 accumumulate bit 1 to 8
bitcount(x) with counters Mask: unsigned int m = 1 + (1 << 8) + (1 << 16) + (1 << 24) 1 1 Accumulate: unsigned int counts = (x & m) + ((x >> 1) & m) + ((x >> 7) & m) Sum up: unsigned int sum = (counts & xff) + ((counts >> 8) & xff) + ((counts >> 16) & xff) + ((counts >> 24) & xff) # Operators? 1 1 6 22 1 38
bitcount(x) better solution? int bitcount(int x) { /* Sum 8 groups of 4 bits each */ int m1 = x11 (x11 << 8); 1 1 1 1 1 1 1 1 int mask = m1 (m1 << 16); int s = x & mask; s += x>>1 & mask; m1 s += x>>2 & mask; s += x>>3 & mask; mask /* Now combine high and low order sums */ s = s + (s >> 16); /* Low order 16 bits now consists of 4 sums, each ranging between and 8. Split into two groups and sum */ mask = xf (xf << 8); 1 1 1 1 1 1 1 1 s = (s & mask) + ((s >> 4) & mask); } return (s + (s>>8)) & x3f; Operators: 25
More on C-Programming Function Pointers a pointer to a function declaration: int (*f) (int, int); f = &function_that_takes_a_and_b_and_returns_x invocation: int x = (*f)(a,b) of course the function has to be defined somewhere usage: generic functions (e.g. comparison function for sorting function)
Some hints Function Pointers http://www.cprogramming.com/tutorial/function-pointers.html Pointer Tutorial http://www.cplusplus.com/doc/tutorial/pointers/ Systems Programming and Computer Architecture 17
Example Structure of a C file #include <stdio.h> int i = 79; static void print_name(void) { const char s[] = "Mothy"; printf("my name is %s and I work in CAB F %d\n", s, i); } int main(int argc, char *argv[]) { print_name(); return ; } You have function definitions and declarations and calls. You have variable declarations Systems Programming and Computer Architecture 18
How about calling print_name() from another source file? Or How does the other_program.c knows about the location / signature of print_name()? Systems Programming and Computer Architecture 19
Solution: Header Files and Modules There is a difference between declaration and definition Declaration gives the signature of the function / variable void print_name(void); Definitions gives the code / storage space for variables put declarations in header files http://en.wikipedia.org/wiki/header_file Systems Programming and Computer Architecture void print_name(void) { const char s[] = "Mothy"; printf("my name is %s and I work in CAB F %d\n", s, i); } 2
Outsourced print_name() /* print_name.h */ void print_name(void); /* print_name.c */ #include <stdio.h> int i = 79; void print_name(void) { const char s[] = "Mothy"; printf("my name is %s and I work in CAB F %d\n", s, i); } Systems Programming and Computer Architecture 21
New Structure of Main #include print_name.h int main(int argc, char *argv[]) { print_name(); return ; } Note: You do not need to include stdio.h anymore, since you do not make use of printf here #include print_name.h #include <stdio.h> Your header files (same directory) Header file of the system (libc) Systems Programming and Computer Architecture 22
Different file types Header Files (*.h) Forward declarations (function prototypes, ) Source Files (*.c) Function definitions (source code) Globally usable definitions, typedefs, structs, [Macro definitions] Variable storage Local (static) function declarations & definitions Note: Everything that is declared in an header file which can be included is considered to be globally accessible. Only put there what s necessary i.e. the public interface Systems Programming and Computer Architecture 23
Header Files h-files are included by (text injection): #include "header1.h" #include <system-file> Include Guards (make sure that h-file is only included once in an executable): #ifndef HEADER_FILE #define HEADER_FILE // the entire header file #endif // HEADER_FILE
Compiling The Program Just executing gcc with your program.c does not work anymore You have to specify every source file you used: gcc o program program.c print_name.c -o output should be named my_program You do not have to list the *.h files gcc looks for the *.h files in the current directory Systems Programming and Computer Architecture 25
make? GNU make: In software development, Make is a utility that automatically builds executable programs and libraries from source code by reading files called makefiles which specify how to derive the target program. http://www.linuxforu.com/212/6/gnu-make-indetail-for-beginners/ Systems Programming and Computer Architecture 26
Example (this assignment) CC = gcc CFLAGS = -O -Wall -m32 btest: btest.c bits.c decl.c tests.c btest.h bits.h $(CC) $(CFLAGS) -o btest bits.c btest.c decl.c tests.c clean: rm -f *.o btest Usage: make or make btest: make clean: runs the compilation but only if the files are modified removes your generated binary file Systems Programming and Computer Architecture 27
GCC Flags for better coding style -Werror Make all warnings into errors. -Wpedantic Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions -Wall This enables all the warnings about constructions that some users consider questionable, https://gcc.gnu.org/onlinedocs/gcc/warning-options.html
More on C-Programming More on modules and header files http://www.tutorialspoint.com/cprogramming/c_ header_files.htm Make files (important for later ) http://www.cs.colby.edu/maxwell/courses/tutoria ls/maketutor/ More on this in the lecture next week
Assignment 2
Integer Data Types You may use the types defined in C99 s stdit.h #include <stdint.h> void main(int argc, char *argv[]) { uint8_t x = 22; int16_t y = 4434; int64_t z = 1 << 44; } Keep in mind not to overflow by using a too small representation for the value http://www.cplusplus.com/reference/cstdint/ http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdint.h.html Systems Programming and Computer Architecture 31
Reverse an array Write a C program that has a function that: accepts an array of 32-bit unsigned integers and a length reverses the elements of the array in place returns void (nothing) #include <stdint.h>; void reverse(uint32_t *arr, unsigned int len) { }
First whitespace-separated word Write a C program that has a function that: accepts a string as a parameter returns the first whitespace-separated word in the string (as a newly allocated string) and the size of that word int first_word(char *input_string, char ** output_word) { }
Box-and-arrow diagram Use a box-and-arrow diagram for the following program to explain what it prints out... Pen & Paper Exercise you can hand it in manually or scan it
Little vs. big endian Write a C program that prints out whether the computer it is running on is little endian or big endian. (hint: pointers and casts) // returns true if little endian, if big endian bool is_little_endian() { }
Binary Search Tree (BST) Implement and test a binary search tree in C: implement key insert() and lookup() functions implement it as a C module: bst.c, bst.h implement test_bst.c (contains main(), tests out your BST) don't worry about making it balanced as a bonus implement a key delete() function
Function pointers basics Write a C program that has a function that: accepts a function pointer and an array of integers invokes the pointed-to function with each of the elements in the array as an argument overrides the current array element with the return value of the called function void map(int (*f) (int), int *array, size_t len) { } int pow2(int a) { return a*a; }
Quiz
Quiz: Rewrite the conditions if (A) { if (B) if (C) D; else; else; else if (B) if (C) E; else F; else; }
Quiz: Programming Style if (A && B && C) D; else if (!A && B && C) E; else if (!A && B &&!C) F;
Quiz: Simple Pointer #define PRINT(fmt, val) printf(#val = % #fmt \t, (val)) int a[] = {,1,2,3,4 }; main() { int i, *p; for (i=; i<=4; i++) PRINT(d, a[i]); for (p = &a[]; p <= &a[4]; p++) PRINT(d, *p); }
Quiz: Simple Pointer PRINT(d, a[i]); a[i] = a[i] = 1 a[i] = 2 a[i] = 3 a[i] = 4 PRINT(d, *p); *p = *p = 1 *p = 2 *p = 3 *p = 4
Quiz: Simple Pointer #define PRINT(fmt, val) printf(#val = % #fmt \t, (val)) int a[] = {,1,2,3,4 }; int i, *p; for (p = &a[], i=; p+i <= a+4; p++,i++) PRINT(d, *(p+i));
Quiz: Simple Pointer *p+i = *p+i = 2 *p+i = 4
Quiz: Arrays and Pointers #define PRINT(fmt, val) printf(#val = % #fmt \t, (val)) #define PRINT3(fmt, v1, v2, v3) PRINT(fmt, v1); PRINT(fmt, v2); PRINT(fmt, v3); int a[] = {, 1, 2, 3, 4 }; int *p[] = {a, a+1, a+2, a+3, a+4 }; int **pp = p; main() { PRINT3(d, a, *a, **a); PRINT3(d, p, *p, **p); PRINT3(d, pp, *pp, **pp); }
Quiz: Arrays and Pointers a = address of a *a = **a = Segmentation Fault (Null pointer dereference) p = address of p *p = address of a **p = pp = address of p *pp address of a **pp =
Good luck! Have a nice weekend! Systems Programming and Computer Architecture 47