diff --git a/20181210/blink-10.E b/20181210/blink-10.E new file mode 100644 index 0000000000000000000000000000000000000000..0fed6b59d71f6a2b8c8e06ec69a99087556defbf --- /dev/null +++ b/20181210/blink-10.E @@ -0,0 +1,492 @@ +# 1 "blink-10.c" +# 1 "<built-in>" +# 1 "<command-line>" +# 1 "blink-10.c" +# 1 "/usr/lib/avr/include/avr/io.h" 1 3 +# 99 "/usr/lib/avr/include/avr/io.h" 3 +# 1 "/usr/lib/avr/include/avr/sfr_defs.h" 1 3 +# 126 "/usr/lib/avr/include/avr/sfr_defs.h" 3 +# 1 "/usr/lib/avr/include/inttypes.h" 1 3 +# 37 "/usr/lib/avr/include/inttypes.h" 3 +# 1 "/usr/lib/gcc/avr/4.9.2/include/stdint.h" 1 3 4 +# 9 "/usr/lib/gcc/avr/4.9.2/include/stdint.h" 3 4 +# 1 "/usr/lib/avr/include/stdint.h" 1 3 4 +# 121 "/usr/lib/avr/include/stdint.h" 3 4 +typedef signed int int8_t __attribute__((__mode__(__QI__))); +typedef unsigned int uint8_t __attribute__((__mode__(__QI__))); +typedef signed int int16_t __attribute__ ((__mode__ (__HI__))); +typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__))); +typedef signed int int32_t __attribute__ ((__mode__ (__SI__))); +typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__))); + +typedef signed int int64_t __attribute__((__mode__(__DI__))); +typedef unsigned int uint64_t __attribute__((__mode__(__DI__))); +# 142 "/usr/lib/avr/include/stdint.h" 3 4 +typedef int16_t intptr_t; + + + + +typedef uint16_t uintptr_t; +# 159 "/usr/lib/avr/include/stdint.h" 3 4 +typedef int8_t int_least8_t; + + + + +typedef uint8_t uint_least8_t; + + + + +typedef int16_t int_least16_t; + + + + +typedef uint16_t uint_least16_t; + + + + +typedef int32_t int_least32_t; + + + + +typedef uint32_t uint_least32_t; + + + + + + + +typedef int64_t int_least64_t; + + + + + + +typedef uint64_t uint_least64_t; +# 213 "/usr/lib/avr/include/stdint.h" 3 4 +typedef int8_t int_fast8_t; + + + + +typedef uint8_t uint_fast8_t; + + + + +typedef int16_t int_fast16_t; + + + + +typedef uint16_t uint_fast16_t; + + + + +typedef int32_t int_fast32_t; + + + + +typedef uint32_t uint_fast32_t; + + + + + + + +typedef int64_t int_fast64_t; + + + + + + +typedef uint64_t uint_fast64_t; +# 273 "/usr/lib/avr/include/stdint.h" 3 4 +typedef int64_t intmax_t; + + + + +typedef uint64_t uintmax_t; +# 10 "/usr/lib/gcc/avr/4.9.2/include/stdint.h" 2 3 4 +# 38 "/usr/lib/avr/include/inttypes.h" 2 3 +# 77 "/usr/lib/avr/include/inttypes.h" 3 +typedef int32_t int_farptr_t; + + + +typedef uint32_t uint_farptr_t; +# 127 "/usr/lib/avr/include/avr/sfr_defs.h" 2 3 +# 100 "/usr/lib/avr/include/avr/io.h" 2 3 +# 272 "/usr/lib/avr/include/avr/io.h" 3 +# 1 "/usr/lib/avr/include/avr/iom328p.h" 1 3 +# 273 "/usr/lib/avr/include/avr/io.h" 2 3 +# 627 "/usr/lib/avr/include/avr/io.h" 3 +# 1 "/usr/lib/avr/include/avr/portpins.h" 1 3 +# 628 "/usr/lib/avr/include/avr/io.h" 2 3 + +# 1 "/usr/lib/avr/include/avr/common.h" 1 3 +# 630 "/usr/lib/avr/include/avr/io.h" 2 3 + +# 1 "/usr/lib/avr/include/avr/version.h" 1 3 +# 632 "/usr/lib/avr/include/avr/io.h" 2 3 + + + + + + +# 1 "/usr/lib/avr/include/avr/fuse.h" 1 3 +# 239 "/usr/lib/avr/include/avr/fuse.h" 3 +typedef struct +{ + unsigned char low; + unsigned char high; + unsigned char extended; +} __fuse_t; +# 639 "/usr/lib/avr/include/avr/io.h" 2 3 + + +# 1 "/usr/lib/avr/include/avr/lock.h" 1 3 +# 642 "/usr/lib/avr/include/avr/io.h" 2 3 +# 2 "blink-10.c" 2 +# 1 "/usr/lib/avr/include/avr/interrupt.h" 1 3 +# 3 "blink-10.c" 2 + + + +# 1 "/usr/lib/avr/include/util/delay.h" 1 3 +# 43 "/usr/lib/avr/include/util/delay.h" 3 +# 1 "/usr/lib/avr/include/util/delay_basic.h" 1 3 +# 40 "/usr/lib/avr/include/util/delay_basic.h" 3 +static inline void _delay_loop_1(uint8_t __count) __attribute__((always_inline)); +static inline void _delay_loop_2(uint16_t __count) __attribute__((always_inline)); +# 80 "/usr/lib/avr/include/util/delay_basic.h" 3 +void +_delay_loop_1(uint8_t __count) +{ + __asm__ volatile ( + "1: dec %0" "\n\t" + "brne 1b" + : "=r" (__count) + : "0" (__count) + ); +} +# 102 "/usr/lib/avr/include/util/delay_basic.h" 3 +void +_delay_loop_2(uint16_t __count) +{ + __asm__ volatile ( + "1: sbiw %0,1" "\n\t" + "brne 1b" + : "=w" (__count) + : "0" (__count) + ); +} +# 44 "/usr/lib/avr/include/util/delay.h" 2 3 +# 1 "/usr/lib/avr/include/math.h" 1 3 +# 127 "/usr/lib/avr/include/math.h" 3 +extern double cos(double __x) __attribute__((__const__)); + + + + + +extern double sin(double __x) __attribute__((__const__)); + + + + + +extern double tan(double __x) __attribute__((__const__)); + + + + + + +extern double fabs(double __x) __attribute__((__const__)); + + + + + + +extern double fmod(double __x, double __y) __attribute__((__const__)); +# 168 "/usr/lib/avr/include/math.h" 3 +extern double modf(double __x, double *__iptr); + + + +extern float modff (float __x, float *__iptr); + + + + +extern double sqrt(double __x) __attribute__((__const__)); +extern float sqrtf (float) __attribute__((__const__)); + + + + +extern double cbrt(double __x) __attribute__((__const__)); +# 194 "/usr/lib/avr/include/math.h" 3 +extern double hypot (double __x, double __y) __attribute__((__const__)); + + + + + + + +extern double square(double __x) __attribute__((__const__)); + + + + + + +extern double floor(double __x) __attribute__((__const__)); + + + + + + +extern double ceil(double __x) __attribute__((__const__)); +# 234 "/usr/lib/avr/include/math.h" 3 +extern double frexp(double __x, int *__pexp); + + + + + + + +extern double ldexp(double __x, int __exp) __attribute__((__const__)); + + + + + +extern double exp(double __x) __attribute__((__const__)); + + + + + +extern double cosh(double __x) __attribute__((__const__)); + + + + + +extern double sinh(double __x) __attribute__((__const__)); + + + + + +extern double tanh(double __x) __attribute__((__const__)); + + + + + + + +extern double acos(double __x) __attribute__((__const__)); + + + + + + + +extern double asin(double __x) __attribute__((__const__)); + + + + + + +extern double atan(double __x) __attribute__((__const__)); +# 298 "/usr/lib/avr/include/math.h" 3 +extern double atan2(double __y, double __x) __attribute__((__const__)); + + + + + +extern double log(double __x) __attribute__((__const__)); + + + + + +extern double log10(double __x) __attribute__((__const__)); + + + + + +extern double pow(double __x, double __y) __attribute__((__const__)); + + + + + + +extern int isnan(double __x) __attribute__((__const__)); +# 333 "/usr/lib/avr/include/math.h" 3 +extern int isinf(double __x) __attribute__((__const__)); + + + + + + +__attribute__((__const__)) static inline int isfinite (double __x) +{ + unsigned char __exp; + __asm__ ( + "mov %0, %C1 \n\t" + "lsl %0 \n\t" + "mov %0, %D1 \n\t" + "rol %0 " + : "=r" (__exp) + : "r" (__x) ); + return __exp != 0xff; +} + + + + + + +__attribute__((__const__)) static inline double copysign (double __x, double __y) +{ + __asm__ ( + "bst %D2, 7 \n\t" + "bld %D0, 7 " + : "=r" (__x) + : "0" (__x), "r" (__y) ); + return __x; +} +# 376 "/usr/lib/avr/include/math.h" 3 +extern int signbit (double __x) __attribute__((__const__)); + + + + + + +extern double fdim (double __x, double __y) __attribute__((__const__)); +# 392 "/usr/lib/avr/include/math.h" 3 +extern double fma (double __x, double __y, double __z) __attribute__((__const__)); + + + + + + + +extern double fmax (double __x, double __y) __attribute__((__const__)); + + + + + + + +extern double fmin (double __x, double __y) __attribute__((__const__)); + + + + + + +extern double trunc (double __x) __attribute__((__const__)); +# 426 "/usr/lib/avr/include/math.h" 3 +extern double round (double __x) __attribute__((__const__)); +# 439 "/usr/lib/avr/include/math.h" 3 +extern long lround (double __x) __attribute__((__const__)); +# 453 "/usr/lib/avr/include/math.h" 3 +extern long lrint (double __x) __attribute__((__const__)); +# 45 "/usr/lib/avr/include/util/delay.h" 2 3 +# 84 "/usr/lib/avr/include/util/delay.h" 3 +static inline void _delay_us(double __us) __attribute__((always_inline)); +static inline void _delay_ms(double __ms) __attribute__((always_inline)); +# 141 "/usr/lib/avr/include/util/delay.h" 3 +void +_delay_ms(double __ms) +{ + double __tmp ; + + + + uint32_t __ticks_dc; + extern void __builtin_avr_delay_cycles(unsigned long); + __tmp = ((16000000l) / 1e3) * __ms; +# 160 "/usr/lib/avr/include/util/delay.h" 3 + __ticks_dc = (uint32_t)(ceil(fabs(__tmp))); + + + __builtin_avr_delay_cycles(__ticks_dc); +# 186 "/usr/lib/avr/include/util/delay.h" 3 +} +# 223 "/usr/lib/avr/include/util/delay.h" 3 +void +_delay_us(double __us) +{ + double __tmp ; + + + + uint32_t __ticks_dc; + extern void __builtin_avr_delay_cycles(unsigned long); + __tmp = ((16000000l) / 1e6) * __us; +# 242 "/usr/lib/avr/include/util/delay.h" 3 + __ticks_dc = (uint32_t)(ceil(fabs(__tmp))); + + + __builtin_avr_delay_cycles(__ticks_dc); +# 268 "/usr/lib/avr/include/util/delay.h" 3 +} +# 7 "blink-10.c" 2 + +volatile uint8_t key_pressed = 0; + +void __vector_1 (void) __attribute__ ((signal,used, externally_visible)) ; void __vector_1 (void) +{ + key_pressed = 1; +} + +int main (void) +{ + __asm__ __volatile__ ("cli" ::: "memory"); + (*(volatile uint8_t *)(0x69)) = 1 << 0 | 1 << 1; + (*(volatile uint8_t *)((0x1D) + 0x20)) = 1 << 0; + __asm__ __volatile__ ("sei" ::: "memory"); + (*(volatile uint8_t *)((0x0A) + 0x20)) = 0xfb; + (*(volatile uint8_t *)((0x0B) + 0x20)) = 0x40; + while (1) + { + while (!key_pressed) + ; + (*(volatile uint8_t *)((0x0B) + 0x20)) ^= 0x40; + key_pressed = 0; + } + return 0; +} diff --git a/20181210/blink-10.s b/20181210/blink-10.s new file mode 100644 index 0000000000000000000000000000000000000000..3041ef100c9be473cf97c6034fdfaa6efc9cba4b --- /dev/null +++ b/20181210/blink-10.s @@ -0,0 +1,75 @@ + .file "blink-10.c" +__SP_H__ = 0x3e +__SP_L__ = 0x3d +__SREG__ = 0x3f +__tmp_reg__ = 0 +__zero_reg__ = 1 + .text +.global __vector_1 + .type __vector_1, @function +__vector_1: + push r1 + push r0 + in r0,__SREG__ + push r0 + clr __zero_reg__ + push r24 +/* prologue: Signal */ +/* frame size = 0 */ +/* stack size = 4 */ +.L__stack_usage = 4 + ldi r24,lo8(1) + sts key_pressed,r24 +/* epilogue start */ + pop r24 + pop r0 + out __SREG__,r0 + pop r0 + pop r1 + reti + .size __vector_1, .-__vector_1 + .section .text.startup,"ax",@progbits +.global main + .type main, @function +main: +/* prologue: function */ +/* frame size = 0 */ +/* stack size = 0 */ +.L__stack_usage = 0 +/* #APP */ + ; 17 "blink-10.c" 1 + cli + ; 0 "" 2 +/* #NOAPP */ + ldi r24,lo8(3) + sts 105,r24 + ldi r24,lo8(1) + out 0x1d,r24 +/* #APP */ + ; 20 "blink-10.c" 1 + sei + ; 0 "" 2 +/* #NOAPP */ + ldi r24,lo8(-5) + out 0xa,r24 + ldi r24,lo8(64) + out 0xb,r24 + ldi r25,lo8(64) +.L3: + lds r24,key_pressed + tst r24 + breq .L3 + in r24,0xb + eor r24,r25 + out 0xb,r24 + sts key_pressed,__zero_reg__ + rjmp .L3 + .size main, .-main +.global key_pressed + .section .bss + .type key_pressed, @object + .size key_pressed, 1 +key_pressed: + .zero 1 + .ident "GCC: (GNU) 4.9.2" +.global __do_clear_bss diff --git a/20181210/blink-9.s b/20181210/blink-9.s new file mode 100644 index 0000000000000000000000000000000000000000..1d0b2665172ba50f9596ed3c3c8e5ea994a28119 --- /dev/null +++ b/20181210/blink-9.s @@ -0,0 +1,78 @@ + .file "blink-9.c" +__SP_H__ = 0x3e +__SP_L__ = 0x3d +__SREG__ = 0x3f +__tmp_reg__ = 0 +__zero_reg__ = 1 + .text +.global __vector_1 + .type __vector_1, @function +__vector_1: + push r1 + push r0 + in r0,__SREG__ + push r0 + clr __zero_reg__ + push r24 +/* prologue: Signal */ +/* frame size = 0 */ +/* stack size = 4 */ +.L__stack_usage = 4 + ldi r24,lo8(1) + sts key_pressed,r24 +/* epilogue start */ + pop r24 + pop r0 + out __SREG__,r0 + pop r0 + pop r1 + reti + .size __vector_1, .-__vector_1 + .section .text.startup,"ax",@progbits +.global main + .type main, @function +main: +/* prologue: function */ +/* frame size = 0 */ +/* stack size = 0 */ +.L__stack_usage = 0 +/* #APP */ + ; 17 "blink-9.c" 1 + cli + ; 0 "" 2 +/* #NOAPP */ + ldi r24,lo8(3) + sts 105,r24 + ldi r24,lo8(1) + out 0x1d,r24 +/* #APP */ + ; 20 "blink-9.c" 1 + sei + ; 0 "" 2 +/* #NOAPP */ + ldi r24,lo8(-5) + out 0xa,r24 + ldi r24,lo8(64) + out 0xb,r24 + ldi r25,lo8(64) +.L4: + lds r24,key_pressed + cpse r24,__zero_reg__ + rjmp .L7 +.L6: + rjmp .L6 +.L7: + in r24,0xb + eor r24,r25 + out 0xb,r24 + sts key_pressed,__zero_reg__ + rjmp .L4 + .size main, .-main +.global key_pressed + .section .bss + .type key_pressed, @object + .size key_pressed, 1 +key_pressed: + .zero 1 + .ident "GCC: (GNU) 4.9.2" +.global __do_clear_bss diff --git a/20181210/hp-20181210.pdf b/20181210/hp-20181210.pdf index bfef43119db2e0de5aeee917ccdc3846cd41200f..abcae2a12f7eb260dd8764fa975bd9da3e1ffd83 100644 Binary files a/20181210/hp-20181210.pdf and b/20181210/hp-20181210.pdf differ diff --git a/20181210/hp-20181210.tex b/20181210/hp-20181210.tex index 5286d8be04d90998924580d982fae5bcc52969ea..11ed78708c406a18c692cd25903a3cab2854b913 100644 --- a/20181210/hp-20181210.tex +++ b/20181210/hp-20181210.tex @@ -847,12 +847,11 @@ \item[\textbf{3}] \textbf{Bibliotheken} \item[\textbf{4}] \textbf{Hardwarenahe Programmierung} \begin{itemize} - \color{medgreen} \item[4.1] Bit-Operationen \item[4.2] Programmierung von Mikrocontrollern \item[4.3] I/O-Ports \item[4.4] Interrupts - \color{red} + \color{medgreen} \item[4.5] volatile-Variable \item[4.6] Byte-Reihenfolge -- Endianness \item[4.7] Binärdarstellung negativer Zahlen diff --git a/20181210/photo-20181210-173116.jpg b/20181210/photo-20181210-173116.jpg new file mode 100644 index 0000000000000000000000000000000000000000..64e2fc893afbd0f9e7e31b1dbf76bb0f769accc7 Binary files /dev/null and b/20181210/photo-20181210-173116.jpg differ diff --git a/20181210/photo-20181210-173116.txt b/20181210/photo-20181210-173116.txt new file mode 100644 index 0000000000000000000000000000000000000000..bf1fadff2b26627224b1962ca6ae35abb6afd8f3 --- /dev/null +++ b/20181210/photo-20181210-173116.txt @@ -0,0 +1 @@ +README: Grafik abspeichern; Zweierkomplement auf 4-Bit-Rechner diff --git a/20181217/Tower_of_Hanoi.jpeg b/20181217/Tower_of_Hanoi.jpeg new file mode 120000 index 0000000000000000000000000000000000000000..a1a794afda08596ffa2f46f278db53455de25b6c --- /dev/null +++ b/20181217/Tower_of_Hanoi.jpeg @@ -0,0 +1 @@ +../common/Tower_of_Hanoi.jpeg \ No newline at end of file diff --git a/20181217/aufgabe-1.c b/20181217/aufgabe-1.c new file mode 100644 index 0000000000000000000000000000000000000000..abbf364a3db17611e41d086591826e98a8a3672b --- /dev/null +++ b/20181217/aufgabe-1.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +int fak (int n) +{ + if (n <= 0) + return 1; + else + return n * fak (n - 1); +} + +int main (void) +{ + for (int n = 0; n <= 5; n++) + printf ("%d\n", fak (n)); + return 0; +} diff --git a/20181217/aufgabe-2.c b/20181217/aufgabe-2.c new file mode 100644 index 0000000000000000000000000000000000000000..d9a61080ab762fb3077ada2a578a9678820e8751 --- /dev/null +++ b/20181217/aufgabe-2.c @@ -0,0 +1,20 @@ +#include <avr/io.h> +#include <avr/interrupt.h> + +int counter = 0; + +ISR (TIMER0_COMP_vect) +{ + PORTA = 1 << ((counter++ >> 6) & 7); +} + +int main (void) +{ + cli (); + TCCR0 = (1 << CS01) | (1 << CS00); + TIMSK = 1 << OCIE0; + sei (); + DDRA = 0xff; + while (1); + return 0; +} diff --git a/20181217/aufgabe-2.gif b/20181217/aufgabe-2.gif new file mode 100644 index 0000000000000000000000000000000000000000..38a7918f4518377428f910f9075f301ae2f58895 Binary files /dev/null and b/20181217/aufgabe-2.gif differ diff --git a/20181217/aufgabe-3.c b/20181217/aufgabe-3.c new file mode 100644 index 0000000000000000000000000000000000000000..d0b065941fbc0082bf867d872527299dca97b98f --- /dev/null +++ b/20181217/aufgabe-3.c @@ -0,0 +1,18 @@ +#include <string.h> + +int fun_1 (char *s) +{ + int x = 0; + for (int i = 0; i < strlen (s); i++) + x += s[i]; + return x; +} + +int fun_2 (char *s) +{ + int i = 0, x = 0; + int len = strlen (s); + while (i < len) + x += s[i++]; + return x; +} diff --git a/20181217/hanoi-0.c b/20181217/hanoi-0.c new file mode 100644 index 0000000000000000000000000000000000000000..83b5f081e33e699f2d5eaa1f858320530e1b2820 --- /dev/null +++ b/20181217/hanoi-0.c @@ -0,0 +1,26 @@ +#include <stdio.h> + +#define DISKS 4 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +int main (void) +{ + n[0] = 0; + n[1] = 0; + n[2] = 0; + display (); + return 0; +} diff --git a/20181217/hanoi-1.c b/20181217/hanoi-1.c new file mode 100644 index 0000000000000000000000000000000000000000..6d005f0b12afa6086afb65e1794fb5c977b474e2 --- /dev/null +++ b/20181217/hanoi-1.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +#define DISKS 4 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +int main (void) +{ + n[0] = 4; + tower[0][0] = 4; + tower[0][1] = 3; + tower[0][2] = 2; + tower[0][3] = 1; + n[1] = 0; + n[2] = 0; + display (); + return 0; +} diff --git a/20181217/hanoi-2.c b/20181217/hanoi-2.c new file mode 100644 index 0000000000000000000000000000000000000000..c928c1130539da08d0882249bdffc877d72289b2 --- /dev/null +++ b/20181217/hanoi-2.c @@ -0,0 +1,28 @@ +#include <stdio.h> + +#define DISKS 4 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +int main (void) +{ + n[0] = DISKS; + for (int i = 0; i < DISKS; i++) + tower[0][i] = DISKS - i; + n[1] = 0; + n[2] = 0; + display (); + return 0; +} diff --git a/20181217/hanoi-3.c b/20181217/hanoi-3.c new file mode 100644 index 0000000000000000000000000000000000000000..4b59c046962c1f79eca315882d93faf6b6c298c1 --- /dev/null +++ b/20181217/hanoi-3.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <error.h> + +#define DISKS 4 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +void move (int from, int to, int disks) +{ + if (disks == 1) + { + if (n[from] <= 0) + error (1, 0, "trying to move disk from empty tower"); + if (n[to] > 0 && tower[to][n[to] - 1] < tower[from][n[from] - 1]) + error (1, 0, "trying to move larger disk on smaller one"); + tower[to][n[to]] = tower[from][n[from] - 1]; + n[to]++; + n[from]--; + } +} + +int main (void) +{ + n[0] = DISKS; + for (int i = 0; i < DISKS; i++) + tower[0][i] = DISKS - i; + n[1] = 0; + n[2] = 0; + move (2, 0, 1); + display (); + return 0; +} diff --git a/20181217/hanoi-4.c b/20181217/hanoi-4.c new file mode 100644 index 0000000000000000000000000000000000000000..162a5ba7cccedf64bff8ae9a514aaf146088e3a4 --- /dev/null +++ b/20181217/hanoi-4.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <error.h> + +#define DISKS 4 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +void move (int from, int to, int disks) +{ + if (disks == 1) + { + if (n[from] <= 0) + error (1, 0, "trying to move disk from empty tower"); + if (n[to] > 0 && tower[to][n[to] - 1] < tower[from][n[from] - 1]) + error (1, 0, "trying to move larger disk on smaller one"); + tower[to][n[to]] = tower[from][n[from] - 1]; + n[to]++; + n[from]--; + } +} + +int main (void) +{ + n[0] = DISKS; + for (int i = 0; i < DISKS; i++) + tower[0][i] = DISKS - i; + n[1] = 0; + n[2] = 0; + move (0, 2, 1); + display (); + return 0; +} diff --git a/20181217/hanoi-5.c b/20181217/hanoi-5.c new file mode 100644 index 0000000000000000000000000000000000000000..e04ad85f63fe92e5c15d22646beb9e9107bf78d6 --- /dev/null +++ b/20181217/hanoi-5.c @@ -0,0 +1,45 @@ +#include <stdio.h> +#include <error.h> + +#define DISKS 4 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +void move (int from, int to, int disks) +{ + if (disks == 1) + { + if (n[from] <= 0) + error (1, 0, "trying to move disk from empty tower"); + if (n[to] > 0 && tower[to][n[to] - 1] < tower[from][n[from] - 1]) + error (1, 0, "trying to move larger disk on smaller one"); + tower[to][n[to]] = tower[from][n[from] - 1]; + n[to]++; + n[from]--; + display (); + } +} + +int main (void) +{ + n[0] = DISKS; + for (int i = 0; i < DISKS; i++) + tower[0][i] = DISKS - i; + n[1] = 0; + n[2] = 0; + display (); + move (0, 2, 1); + return 0; +} diff --git a/20181217/hanoi-6.c b/20181217/hanoi-6.c new file mode 100644 index 0000000000000000000000000000000000000000..1267605f802246e857c32d29cc0a132609cb24ce --- /dev/null +++ b/20181217/hanoi-6.c @@ -0,0 +1,52 @@ +#include <stdio.h> +#include <error.h> + +#define DISKS 4 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +void move (int from, int to, int disks) +{ + if (disks == 1) + { + if (n[from] <= 0) + error (1, 0, "trying to move disk from empty tower"); + if (n[to] > 0 && tower[to][n[to] - 1] < tower[from][n[from] - 1]) + error (1, 0, "trying to move larger disk on smaller one"); + tower[to][n[to]] = tower[from][n[from] - 1]; + n[to]++; + n[from]--; + display (); + } + else + { + int help = 0 + 1 + 2 - from - to; + move (from, help, disks - 1); + move (from, to, 1); + move (help, to, disks - 1); + } +} + +int main (void) +{ + n[0] = DISKS; + for (int i = 0; i < DISKS; i++) + tower[0][i] = DISKS - i; + n[1] = 0; + n[2] = 0; + display (); + move (0, 2, DISKS); + return 0; +} diff --git a/20181217/hanoi-7.c b/20181217/hanoi-7.c new file mode 100644 index 0000000000000000000000000000000000000000..f71fcdc0c3f66047ee3ad870d019a06eb328050f --- /dev/null +++ b/20181217/hanoi-7.c @@ -0,0 +1,52 @@ +#include <stdio.h> +#include <error.h> + +#define DISKS 5 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +void move (int from, int to, int disks) +{ + if (disks == 1) + { + if (n[from] <= 0) + error (1, 0, "trying to move disk from empty tower"); + if (n[to] > 0 && tower[to][n[to] - 1] < tower[from][n[from] - 1]) + error (1, 0, "trying to move larger disk on smaller one"); + tower[to][n[to]] = tower[from][n[from] - 1]; + n[to]++; + n[from]--; + display (); + } + else + { + int help = 0 + 1 + 2 - from - to; + move (from, help, disks - 1); + move (from, to, 1); + move (help, to, disks - 1); + } +} + +int main (void) +{ + n[0] = DISKS; + for (int i = 0; i < DISKS; i++) + tower[0][i] = DISKS - i; + n[1] = 0; + n[2] = 0; + display (); + move (0, 2, DISKS); + return 0; +} diff --git a/20181217/hanoi-8.c b/20181217/hanoi-8.c new file mode 100644 index 0000000000000000000000000000000000000000..6d804063531d424a82924a89d85424c33994793b --- /dev/null +++ b/20181217/hanoi-8.c @@ -0,0 +1,52 @@ +#include <stdio.h> +#include <error.h> + +#define DISKS 64 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +void move (int from, int to, int disks) +{ + if (disks == 1) + { + if (n[from] <= 0) + error (1, 0, "trying to move disk from empty tower"); + if (n[to] > 0 && tower[to][n[to] - 1] < tower[from][n[from] - 1]) + error (1, 0, "trying to move larger disk on smaller one"); + tower[to][n[to]] = tower[from][n[from] - 1]; + n[to]++; + n[from]--; + display (); + } + else + { + int help = 0 + 1 + 2 - from - to; + move (from, help, disks - 1); + move (from, to, 1); + move (help, to, disks - 1); + } +} + +int main (void) +{ + n[0] = DISKS; + for (int i = 0; i < DISKS; i++) + tower[0][i] = DISKS - i; + n[1] = 0; + n[2] = 0; + display (); + move (0, 2, DISKS); + return 0; +} diff --git a/20181217/hanoi-9.c b/20181217/hanoi-9.c new file mode 100644 index 0000000000000000000000000000000000000000..7694b373b7011e96f6be0ad0f00ba54b67086158 --- /dev/null +++ b/20181217/hanoi-9.c @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <error.h> + +#define DISKS 64 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +void move (int from, int to, int disks) +{ + if (disks == 1) + { + if (n[from] <= 0) + error (1, 0, "trying to move disk from empty tower"); + if (n[to] > 0 && tower[to][n[to] - 1] < tower[from][n[from] - 1]) + error (1, 0, "trying to move larger disk on smaller one"); + tower[to][n[to]] = tower[from][n[from] - 1]; + n[to]++; + n[from]--; + static int counter = 1; + if (counter++ >= 100000000) + { + display (); + counter = 1; + } + } + else + { + int help = 0 + 1 + 2 - from - to; + move (from, help, disks - 1); + move (from, to, 1); + move (help, to, disks - 1); + } +} + +int main (void) +{ + n[0] = DISKS; + for (int i = 0; i < DISKS; i++) + tower[0][i] = DISKS - i; + n[1] = 0; + n[2] = 0; + display (); + move (0, 2, DISKS); + display (); + return 0; +} diff --git a/20181217/hanoi-9a.c b/20181217/hanoi-9a.c new file mode 100644 index 0000000000000000000000000000000000000000..55e8d74db6d7284d6db225a6f8f3e08ab4efdc06 --- /dev/null +++ b/20181217/hanoi-9a.c @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <error.h> + +#define DISKS 32 + +int n[3], tower[3][DISKS]; + +void display (void) +{ + printf ("\n"); + for (int i = 0; i < 3; i++) + { + printf ("tower %d:", i); + for (int j = 0; j < n[i]; j++) + printf (" %d", tower[i][j]); + printf ("\n"); + } +} + +void move (int from, int to, int disks) +{ + if (disks == 1) + { + if (n[from] <= 0) + error (1, 0, "trying to move disk from empty tower"); + if (n[to] > 0 && tower[to][n[to] - 1] < tower[from][n[from] - 1]) + error (1, 0, "trying to move larger disk on smaller one"); + tower[to][n[to]] = tower[from][n[from] - 1]; + n[to]++; + n[from]--; + static int counter = 1; + if (counter++ >= 100000000) + { + display (); + counter = 1; + } + } + else + { + int help = 0 + 1 + 2 - from - to; + move (from, help, disks - 1); + move (from, to, 1); + move (help, to, disks - 1); + } +} + +int main (void) +{ + n[0] = DISKS; + for (int i = 0; i < DISKS; i++) + tower[0][i] = DISKS - i; + n[1] = 0; + n[2] = 0; + display (); + move (0, 2, DISKS); + display (); + return 0; +} diff --git a/20181217/hp-20181217.pdf b/20181217/hp-20181217.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c58f29686dccc93e452a1d3d4da6a7c2de7ef0ef Binary files /dev/null and b/20181217/hp-20181217.pdf differ diff --git a/20181217/hp-20181217.tex b/20181217/hp-20181217.tex new file mode 100644 index 0000000000000000000000000000000000000000..53f974c95f2a5deed2f32c6a41b01ca1d5d29812 --- /dev/null +++ b/20181217/hp-20181217.tex @@ -0,0 +1,1090 @@ +% hp-20181217.pdf - Lecture Slides on Low-Level Programming +% Copyright (C) 2012, 2013, 2015, 2016, 2017, 2018 Peter Gerwinski +% +% This document is free software: you can redistribute it and/or +% modify it either under the terms of the Creative Commons +% Attribution-ShareAlike 3.0 License, or under the terms of the +% GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% This document is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this document. If not, see <http://www.gnu.org/licenses/>. +% +% You should have received a copy of the Creative Commons +% Attribution-ShareAlike 3.0 Unported License along with this +% document. If not, see <http://creativecommons.org/licenses/>. + +% README: Rekursion, Aufwandsabschätzungen + +\documentclass[10pt,t]{beamer} + +\usepackage{pgslides} +\usepackage{pdftricks} +\usepackage{tikz} + +\begin{psinputs} + \usepackage[utf8]{inputenc} + \usepackage[german]{babel} + \usepackage[T1]{fontenc} + \usepackage{helvet} + \renewcommand*\familydefault{\sfdefault} + \usepackage{pstricks,pst-grad} +\end{psinputs} + +\title{Hardwarenahe Programmierung} +\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski} +\date{10.\ Dezember 2018} + +\begin{document} + +\maketitleframe + +\nosectionnonumber{\inserttitle} + +\begin{frame} + + \shownosectionnonumber + + \begin{itemize} + \item[\textbf{1}] \textbf{Einführung} + \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp.git}}} + \item[\textbf{2}] \textbf{Einführung in C} + \item[\textbf{3}] \textbf{Bibliotheken} + \item[\textbf{4}] \textbf{Hardwarenahe Programmierung} + \begin{itemize} + \item[4.1] Bit-Operationen + \item[4.2] Programmierung von Mikrocontrollern + \item[4.3] I/O-Ports + \item[4.4] Interrupts + \color{medgreen} + \item[4.5] volatile-Variable + \item[4.6] Byte-Reihenfolge -- Endianness + \item[4.7] Binärdarstellung negativer Zahlen + \color{red} + \item[4.8] Speicherausrichtung -- Alignment + \end{itemize} + \item[\textbf{5}] \textbf{Algorithmen} + \begin{itemize} + \item[5.1] Differentialgleichungen + \vspace*{-0.1cm} + \item[\dots] + \end{itemize} + \item[\textbf{\dots}] + \end{itemize} + \vspace*{-1cm} + +\end{frame} + +\setcounter{section}{3} +\section{Hardwarenahe Programmierung} +\subsection{Bit-Operationen} +\subsubsection{Zahlensysteme} + +\begin{frame}[fragile] + + \showsubsubsection + + \begin{tabular}{rlrlrc} + \qquad 000 & \bf 0 \hspace*{1.5cm} & 0000 & \bf 0 & \quad 1000 & \bf 8\\ + 001 & \bf 1 & 0001 & \bf 1 & 1001 & \bf 9\\ + 010 & \bf 2 & 0010 & \bf 2 & 1010 & \bf A\\ + 011 & \bf 3 & 0011 & \bf 3 & 1011 & \bf B\\[\smallskipamount] + 100 & \bf 4 & 0100 & \bf 4 & 1100 & \bf C\\ + 101 & \bf 5 & 0101 & \bf 5 & 1101 & \bf D\\ + 110 & \bf 6 & 0110 & \bf 6 & 1110 & \bf E\\ + 111 & \bf 7 & 0111 & \bf 7 & 1111 & \bf F\\ + \end{tabular} + + \medskip + + \begin{itemize} + \item + Oktal- und Hexadezimalzahlen lassen sich ziffernweise\\ + in Binär-Zahlen umrechnen. + \item + Hexadezimalzahlen sind eine Kurzschreibweise für Binärzahlen,\\ + gruppiert zu jeweils 4 Bits. + \item + Oktalzahlen sind eine Kurzschreibweise für Binärzahlen,\\ + gruppiert zu jeweils 3 Bits. + \item + Trotz Taschenrechner u.\,ä.\ lohnt es sich,\\ + die o.\,a.\ Umrechnungstabelle \textbf{auswendig} zu kennen. + \end{itemize} + +\end{frame} + +\subsubsection{Bit-Operationen in C} + +\begin{frame}[fragile] + + \showsubsubsection + + \begin{tabular}{lll} + C-Operator & Verknüpfung & Anwendung \\[\smallskipamount] + \lstinline,&, & Und & Bits gezielt löschen \\ + \lstinline,|, & Oder & Bits gezielt setzen \\ + \lstinline,^, & Exklusiv-Oder & Bits gezielt invertieren \\ + \lstinline,~, & Nicht & Alle Bits invertieren \\[\smallskipamount] + \lstinline,<<, & Verschiebung nach links & Maske generieren \\ + \lstinline,>>, & Verschiebung nach rechts & Bits isolieren + \end{tabular} + + \bigskip + + Numerierung der Bits: von rechts ab 0 + + \medskip + + \begin{tabular}{ll} + Bit Nr.\ 3 auf 1 setzen: & + \lstinline,a |= 1 << 3;, \\ + Bit Nr.\ 4 auf 0 setzen: & + \lstinline,a &= ~(1 << 4);, \\ + Bit Nr.\ 0 invertieren: & + \lstinline,a ^= 1 << 0;, + \end{tabular} + + \smallskip + + ~~Abfrage, ob Bit Nr.\ 1 gesetzt ist:\quad + \lstinline{if (a & (1 << 1))} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsubsection + + C-Datentypen für Bit-Operationen: + \smallskip\par + \lstinline{#include <stdint.h>} + \medskip\par + \begin{tabular}{lllll} + & 8 Bit & 16 Bit & 32 Bit & 64 Bit \\ + mit Vorzeichen & \lstinline,int8_t, + & \lstinline,int16_t, + & \lstinline,int32_t, + & \lstinline,int64_t, \\ + ohne Vorzeichen & \lstinline,uint8_t, + & \lstinline,uint16_t, + & \lstinline,uint32_t, + & \lstinline,uint64_t, + \end{tabular} + + \bigskip + \bigskip + + Ausgabe: + \smallskip\par + \begin{lstlisting} + #include <stdio.h> + #include <stdint.h> + #include <inttypes.h> + ... + uint64_t x = 42; + printf ("Die Antwort lautet: %" PRIu64 "\n", x); + \end{lstlisting} + +\end{frame} + +\iffalse + +\subsection{Programmierung von Mikrocontrollern} + +\begin{frame}[fragile] + \showsubsection + + Cross-Entwicklungswerkzeuge + \begin{itemize} + \item + laufen auf "`normalem"' Computer,\\ + erzeugen Software für anderen Computer oder Mikrocontroller + \item + Cross-Compiler, -Assembler und -Linker + \begin{lstlisting}[style=cmd,gobble=8] + avr-gcc -Wall -Os -mmcu=atmega328p blink.c -o blink.elf + \end{lstlisting} + \item + Werkzeuge zum Herunterladen\footnote{So ist die Sprechweise.} + auf den Mikrocontroller + \begin{lstlisting}[style=cmd,gobble=8] + avr-objcopy -O ihex blink.elf blink.hex + avrdude -P /dev/ttyACM0 -c arduino -p m328p \ + -U flash:w:blink.hex + \end{lstlisting} + \end{itemize} + \begin{picture}(0,0) + \color{red} + \put(9,-1.2){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(1,2);}}} + \put(9,-1.3){\makebox(0,0)[t]{\shortstack{"`Es geht in der\\ + nächsten Zeile\\ + weiter."'}}} + \end{picture} + +\end{frame} + +\subsection{I/O-Ports} + +\begin{frame}[fragile] + +% \showsection + \showsubsection + \vspace*{-1.5\medskipamount} + {\large\textbf{\color{structure}4.4\quad Interrupts}} + + \bigskip + + Kommunikation mit externen Geräten + + \bigskip + + \begin{center} + \includegraphics{io-ports-and-interrupts.pdf} + \end{center} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + In Output-Port schreiben = Aktoren ansteuern + + Beispiel: LED + + \medskip + + \begin{lstlisting} + #include <avr/io.h> + ... + DDRC = 0x70; + PORTC = 0x40; + \end{lstlisting} + \begin{picture}(0,0) + \put(3,0.67){\begin{minipage}{3cm} + \color{red}% + binär: 0111\,0000\\ + binär: 0100\,0000 + \end{minipage}} + \put(10,0.67){\makebox(0,0)[r]{\color{red}Herstellerspezifisch!}} + \end{picture} + + \bigskip + + \lstinline{DDR} = Data Direction Register\\ + Bit = 1 für Output-Port\\ + Bit = 0 für Input-Port + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Aus Input-Port lesen = Sensoren abfragen + + Beispiel: Taster + + \medskip + + \begin{lstlisting} + #include <avr/io.h> + ... + DDRC = 0xfd; + while ((PINC & 0x02) == 0) + ; /* just wait */ + \end{lstlisting} + \begin{picture}(0,0)(-1.5,-0.42) + \put(3,0.67){\begin{minipage}{3cm} + \color{red}% + binär: 1111\,1101\\ + binär: 0000\,0010 + \end{minipage}} + \put(10,0.67){\makebox(0,0)[r]{\color{red}Herstellerspezifisch!}} + \end{picture} + + \bigskip + + \lstinline{DDR} = Data Direction Register\\ + Bit = 1 für Output-Port\\ + Bit = 0 für Input-Port + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + + \bigskip + + Praktikumsaufgabe: Druckknopfampel + +\end{frame} + +\subsection{Interrupts} + +\begin{frame}[fragile] + + \showsubsection + + Externes Gerät ruft (per Stromsignal) Unterprogramm auf + + Zeiger hinterlegen: "`Interrupt-Vektor"' + + Beispiel: eingebaute Uhr\hfill + \makebox(0,0)[tr]{% + \only<1->{\begin{minipage}[t]{4.7cm} + \vspace*{-0.3cm}% + statt Zählschleife (\lstinline{_delay_ms}):\\ + Hauptprogramm kann\\ + andere Dinge tun + \end{minipage}}% + } + + \medskip + + \begin{lstlisting} + #include <avr/interrupt.h> + + ... + + + ISR (TIMER0B_COMP_vect) + { + PORTD ^= 0x40; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(1.9,3.1){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-1.4,-1.0);}}} + \put(2.0,3.2){\makebox(0,0)[l]{"`Dies ist ein Interrupt-Handler."'}} + \put(2.3,2.6){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.6,-0.55);}}} + \put(2.4,2.6){\makebox(0,0)[l]{Interrupt-Vektor darauf zeigen lassen}} + \end{picture} + + Initialisierung über spezielle Ports: + \lstinline{TCCR0B}, \lstinline{TIMSK0} + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + + \vspace*{-2.5cm}\hfill + {\color{red}Herstellerspezifisch!}% + \hspace*{1cm} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Externes Gerät ruft (per Stromsignal) Unterprogramm auf + + Zeiger hinterlegen: "`Interrupt-Vektor"' + + Beispiel: Taster\hfill + \makebox(0,0)[tr]{% + \begin{minipage}[t]{4.7cm} + \vspace*{-0.3cm}% + statt \newterm{Busy Waiting\/}:\\ + Hauptprogramm kann\\ + andere Dinge tun + \end{minipage}} + + \medskip + + \begin{lstlisting} + #include <avr/interrupt.h> + ... + + ISR (INT0_vect) + { + PORTD ^= 0x40; + } + \end{lstlisting} + + \medskip + + Initialisierung über spezielle Ports: + \lstinline{EICRA}, \lstinline{EIMSK} + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + + \vspace*{-2.5cm}\hfill + {\color{red}Herstellerspezifisch!}% + \hspace*{1cm} + +\end{frame} + +\fi + +\setcounter{subsection}{4} +\subsection{volatile-Variable} + +\begin{frame}[fragile] + + \showsubsection + + Externes Gerät ruft (per Stromsignal) Unterprogramm auf + + Zeiger hinterlegen: "`Interrupt-Vektor"' + + Beispiel: Taster + + \vspace*{-2.5pt} + + \begin{minipage}[t]{5cm} + \begin{onlyenv}<1> + \begin{lstlisting}[gobble=8] + ¡#include <avr/interrupt.h> + ... + + uint8_t key_pressed = 0; + + ISR (INT0_vect) + { + key_pressed = 1; + }¿ + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<2> + \begin{lstlisting}[gobble=8] + ¡#include <avr/interrupt.h> + ... + + volatile uint8_t key_pressed = 0; + + ISR (INT0_vect) + { + key_pressed = 1; + }¿ + \end{lstlisting} + \end{onlyenv} + \end{minipage}\hfill + \begin{minipage}[t]{6cm} + \begin{lstlisting}[gobble=6] + ¡int main (void) + { + ... + + while (1) + { + while (!key_pressed) + ; /* just wait */ + PORTD ^= 0x40; + key_pressed = 0; + } + return 0; + }¿ + \end{lstlisting} + \end{minipage} + + \pause + \begin{picture}(0,0) + \color{red} + \put(10.3,4.0){\makebox(0,0)[b]{\begin{minipage}{6cm} + \begin{center} + \textbf{volatile}:\\ + Speicherzugriff\\ + nicht wegoptimieren + \end{center} + \end{minipage}}} + \put(10.3,3.95){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.5,-0.9);}}} + \end{picture} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Was ist eigentlich \lstinline{PORTD}? + + \bigskip +% \pause + + \lstinline[style=cmd]{avr-gcc -Wall -Os -mmcu=atmega328p blink-3.c -E} + + \bigskip +% \pause + \lstinline{PORTD = 0x01;}\\ + \textarrow\quad + \lstinline[style=terminal]{(*(volatile uint8_t *)((0x0B) + 0x20)) = 0x01;}\\ +% \pause + \begin{picture}(0,2)(0,-1.7) + \color{red} + \put(5.75,0.3){$\underbrace{\rule{2.95cm}{0pt}}_{\mbox{Zahl: \lstinline|0x2B|}}$} +% \pause + \put(1.55,0.3){$\underbrace{\rule{4.0cm}{0pt}}_{\mbox{\shortstack[t]{Umwandlung in Zeiger\\ + auf \lstinline|volatile uint8_t|}}}$} +% \pause + \put(1.32,-1){\makebox(0,0)[b]{\tikz{\draw[-latex](0,0)--(0,1.3)}}} + \put(1.12,-1.1){\makebox(0,0)[tl]{Dereferenzierung des Zeigers}} + \end{picture} + +% \pause + \textarrow\quad + \lstinline|volatile uint8_t|-Variable an Speicheradresse \lstinline|0x2B| + +% \pause + \bigskip + \bigskip + + \textarrow\quad + \lstinline|PORTA = PORTB = PORTC = PORTD = 0| ist eine schlechte Idee. + +\end{frame} + +\subsection{Byte-Reihenfolge -- Endianness} +\subsubsection{Konzept} + +\begin{frame}[fragile] + + \showsubsection + \showsubsubsection + + Eine Zahl geht über mehrere Speicherzellen.\\ + Beispiel: 16-Bit-Zahl in 2 8-Bit-Speicherzellen + + \smallskip + + Welche Bits liegen wo? + +% \pause + \bigskip + + $1027 = 1024 + 2 + 1 = 0000\,0100\,0000\,0011_2 = 0403_{16}$ + +% \pause + \bigskip + Speicherzellen: + + \medskip + \begin{tabular}{|c|c|l}\cline{1-2} + \raisebox{-0.25ex}{04} & \raisebox{-0.25ex}{03} & \strut Big-Endian "`großes Ende zuerst"' \\\cline{1-2} + \multicolumn{2}{c}{} & für Menschen leichter lesbar \\ + \multicolumn{3}{c}{} \\[-5pt]\cline{1-2} + \raisebox{-0.25ex}{03} & \raisebox{-0.25ex}{04} & \strut Little-Endian "`kleines Ende zuerst"' \\\cline{1-2} + \multicolumn{2}{c}{} & bei Additionen effizienter + \end{tabular} + +% \pause + \medskip + \textarrow\ Geschmackssache\\ +% \pause\\ + \quad\textbf{\dots\ außer bei Datenaustausch!} + +% \pause +% \bigskip +% +% Aber: nicht verwechseln! \qquad $0304_{16} = 772$ + +\end{frame} + +\begin{frame} + + \showsubsection + \showsubsubsection + + Eine Zahl geht über mehrere Speicherzellen.\\ + Beispiel: 16-Bit-Zahl in 2 8-Bit-Speicherzellen + + \smallskip + + Welche Bits liegen wo? + + \medskip + + \textarrow\ Geschmackssache\\ + \textbf{\dots\ außer bei Datenaustausch!} + + \begin{itemize} + \item + Dateiformate + \item + Datenübertragung + \end{itemize} + +\end{frame} + +\subsubsection{Dateiformate} + +\begin{frame} + + \showsubsection + \showsubsubsection + + Audio-Formate: Reihenfolge der Bytes in 16- und 32-Bit-Zahlen + \begin{itemize} + \item + RIFF-WAVE-Dateien (\file{.wav}): Little-Endian + \item + Au-Dateien (\file{.au}): Big-Endian +% \pause + \item + ältere AIFF-Dateien (\file{.aiff}): Big-Endian + \item + neuere AIFF-Dateien (\file{.aiff}): Little-Endian + \end{itemize} + +% \pause + \bigskip + + Grafik-Formate: Reihenfolge der Bits in den Bytes + \begin{itemize} + \item + PBM-Dateien: Big-Endian\only<4->{, MSB first} + \item + XBM-Dateien: Little-Endian\only<4->{, LSB first} + \end{itemize} + \only<4->{MSB/LSB = most/least significant bit} + +\end{frame} + +\subsubsection{Datenübertragung} + +\begin{frame} + + \showsubsection + \showsubsubsection + + \begin{itemize} + \item + RS-232 (serielle Schnittstelle): LSB first + \item + I$^2$C: MSB first + \item + USB: beides +% \pause + \medskip + \item + Ethernet: LSB first + \item + TCP/IP (Internet): Big-Endian + \end{itemize} + +\end{frame} + +\subsection{Binärdarstellung negativer Zahlen} + +\begin{frame}[fragile] + + \showsubsection + + Speicher ist begrenzt!\\ + \textarrow\ feste Anzahl von Bits + + \medskip + + 8-Bit-Zahlen ohne Vorzeichen: \lstinline{uint8_t}\\ + \textarrow\ Zahlenwerte von \lstinline{0x00} bis \lstinline{0xff} = 0 bis 255\\ +% \pause + \textarrow\ 255 + 1 = 0 + +% \pause + \medskip + + 8-Bit-Zahlen mit Vorzeichen: \lstinline{int8_t}\\ + \lstinline{0xff} = 255 ist die "`natürliche"' Schreibweise für $-1$.\\ +% \pause + \textarrow\ Zweierkomplement + +% \pause + \medskip + + Oberstes Bit = 1: negativ\\ + Oberstes Bit = 0: positiv\\ + \textarrow\ 127 + 1 = $-128$ + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Speicher ist begrenzt!\\ + \textarrow\ feste Anzahl von Bits + + \medskip + + 16-Bit-Zahlen ohne Vorzeichen: + \lstinline{uint16_t}\hfill\lstinline{uint8_t}\\ + \textarrow\ Zahlenwerte von \lstinline{0x0000} bis \lstinline{0xffff} + = 0 bis 65535\hfill 0 bis 255\\ + \textarrow\ 65535 + 1 = 0\hfill 255 + 1 = 0 + + \medskip + + 16-Bit-Zahlen mit Vorzeichen: + \lstinline{int16_t}\hfill\lstinline{int8_t}\\ + \lstinline{0xffff} = 66535 ist die "`natürliche"' Schreibweise für $-1$.\hfill + \lstinline{0xff} = 255 = $-1$\\ + \textarrow\ Zweierkomplement + + \medskip + + Oberstes Bit = 1: negativ\\ + Oberstes Bit = 0: positiv\\ + \textarrow\ 32767 + 1 = $-32768$ + + \bigskip + Literatur: \url{http://xkcd.com/571/} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Frage: \emph{Für welche Zahl steht der Speicherinhalt\, + \raisebox{2pt}{% + \tabcolsep0.25em + \begin{tabular}{|c|c|}\hline + \rule{0pt}{11pt}a3 & 90 \\\hline + \end{tabular}} + (hexadezimal)?} + +% \pause + \smallskip + Antwort: \emph{Das kommt darauf an.} ;--) + +% \pause + \bigskip + Little-Endian: + + \begin{tabular}{lrl} + als \lstinline,int8_t,: & $-93$ & (nur erstes Byte)\\ + als \lstinline,uint8_t,: & $163$ & (nur erstes Byte)\\ + als \lstinline,int16_t,: & $-28509$\\ + als \lstinline,uint16_t,: & $37027$\\ + \lstinline,int32_t, oder größer: & $37027$ + & (zusätzliche Bytes mit Nullen aufgefüllt) + \end{tabular} + + \pause + \bigskip + Big-Endian: + + \begin{tabular}{lrl} + als \lstinline,int8_t,: & $-93$ & (nur erstes Byte)\\ + als \lstinline,uint8_t,: & $163$ & (nur erstes Byte)\\ + als \lstinline,int16_t,: & $-23664$\\ + als \lstinline,uint16_t,: & $41872$\\ + als \lstinline,int32_t,: & $-1550843904$ & (zusätzliche Bytes\\ + als \lstinline,uint32_t,: & $2744123392$ & mit Nullen aufgefüllt)\\ + als \lstinline,int64_t,: & $-6660823848880963584$\\ + als \lstinline,uint64_t,: & $11785920224828588032$\\ + \end{tabular} + +\end{frame} + +\subsection{Speicherausrichtung -- Alignment} + +\begin{frame}[fragile] + + \showsubsection + + \begin{lstlisting} + #include <stdint.h> + + uint8_t a; + uint16_t b; + uint8_t c; + \end{lstlisting} + +% \pause + \bigskip + + Speicheradresse durch 2 teilbar -- "`16-Bit-Alignment"' + \begin{itemize} + \item + 2-Byte-Operation: effizienter +% \pause + \item + \dots\ oder sogar nur dann erlaubt +% \pause + \arrowitem + Compiler optimiert Speicherausrichtung + \end{itemize} + + \medskip + +% \pause + \begin{minipage}{3cm} + \begin{lstlisting}[gobble=6] + ¡uint8_t a; + uint8_t dummy; + uint16_t b; + uint8_t c;¿ + \end{lstlisting} + \end{minipage} +% \pause + \begin{minipage}{3cm} + \begin{lstlisting}[gobble=6] + ¡uint8_t a; + uint8_t c; + uint16_t b;¿ + \end{lstlisting} + \end{minipage} + +% \pause + \vspace{-1.75cm} + \strut\hfill + \begin{minipage}{6.5cm} + Fazit: + \begin{itemize} + \item + \textbf{Adressen von Variablen\\ + sind systemabhängig} + \item + Bei Definition von Datenformaten\\ + Alignment beachten \textarrow\ effizienter + \end{itemize} + \end{minipage} + +\end{frame} + +\section{Algorithmen} +\setcounter{subsection}{1} +\subsection{Rekursion} + +\begin{frame}[fragile] + + \showsubsection + + Vollständige Induktion: + \vspace*{-0.725cm} + \begin{displaymath} + \hspace*{4cm} + \left. + \begin{array}{r} + \mbox{Aussage gilt für $n = 1$}\\[2pt] + \mbox{Schluß von $n - 1$ auf $n$} + \end{array} + \right\} + \mbox{Aussage gilt für alle $n\in\mathbb{N}$} + \end{displaymath} + \vspace*{-0.5cm} + + \pause + + Türme von Hanoi + + \begin{onlyenv}<2> + \begin{center} + \includegraphics[width=12.2cm]{Tower_of_Hanoi.jpeg} + \end{center} + \end{onlyenv} + + \begin{onlyenv}<3-> + \begin{itemize} + \item + 64 Scheiben, 3 Plätze, + \only<3-4>{\hfill\makebox(0,0)[rt]{\includegraphics[width=6cm]{Tower_of_Hanoi.jpeg}}}\\ + immer 1 Scheibe verschieben + \item + Ziel: Turm verschieben + \item + Es dürfen nur kleinere Scheiben\\ + auf größeren liegen. + \bigskip + \pause + \pause + \item + $n = 1$ Scheibe: fertig + \item + Wenn $n - 1$ Scheiben verschiebbar:\\ + schiebe $n - 1$ Scheiben auf Hilfsplatz,\\ + verschiebe die darunterliegende,\\ + hole $n - 1$ Scheiben von Hilfsplatz + \end{itemize} + \begin{onlyenv}<5> + \vspace{-4.3cm} + \begin{lstlisting}[gobble=8,xleftmargin=6.4cm] + void move (int from, int to, int disks) + { + if (disks == 1) + move_one_disk (from, to); + else + { + int help = 0 + 1 + 2 - from - to; + move (from, help, disks - 1); + move (from, to, 1); + move (help, to, disks - 1); + } + } + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<6-> + \vspace{-5.0cm} + \hspace*{7.4cm}\begin{minipage}[t]{5cm} + 32 Scheiben: + \begin{lstlisting}[gobble=10,style=terminal] + $ ¡time ./hanoi-9a¿ + ... + real 0m32,712s + user 0m32,708s + sys 0m0,000s + \end{lstlisting} + \pause[7] + \begin{itemize} + \arrowitem + etwas über 1 Minute\\ + für 64 Scheiben + \end{itemize} + \pause + \vspace*{-0.5cm} + \begin{picture}(0,0) + \color{red} + \put(0,0){\makebox(0,0)[bl]{\tikz[line width=1pt]{\draw(0,0)--(4,0.8);}}} + \put(0,0.8){\makebox(0,0)[tl]{\tikz[line width=1pt]{\draw(0,0)--(4,-0.8);}}} + \end{picture} + + Für jede zusätzliche Scheibe\\verdoppelt sich die Rechenzeit! + % 32.712 * 2^32 / 3600 / 24 / 365.25 = 4452.08032888280477602859 + \begin{itemize} + \arrowitem + $\frac{32,712\,\text{s}\,\cdot\,2^{32}}{3600\,\cdot\,24\,\cdot\,365,25} \approx 4452$ + Jahre\\[\smallskipamount] + für 64 Scheiben + \end{itemize} + \end{minipage} + \end{onlyenv} + \end{onlyenv} + +\end{frame} + +\subsection{Aufwandsabschätzungen \protect\color{gray}-- Komplexitätsanalyse} + +\begin{frame}[fragile] + + \newcommand{\w}{\hspace*{0.75pt}} + + \showsubsection + + \begin{picture}(0,0) + \put(7.8,-0.3){% + \begin{minipage}[t]{5.3cm} + \vspace*{-1.0cm}\includegraphics{landau-symbols.pdf} +% \vspace*{-1.0cm}\alt<2->{\includegraphics{landau-symbols-2.pdf}}% +% {\includegraphics{landau-symbols.pdf}} + \small + \begin{description}\itemsep0pt\leftskip-0.5cm + \item[$n$:] Eingabedaten + \item[$g(n)$:] Rechenzeit + \end{description} + \end{minipage}} + \end{picture} + + \vspace*{-1.5\bigskipamount} + + \begin{itemize} + \item + Türme von Hanoi: $\mathcal{O}(2^n)$ + \begin{onlyenv}<1> + \par\medskip + Für jede zusätzliche Scheibe\\verdoppelt sich die Rechenzeit! + % 32.712 * 2^32 / 3600 / 24 / 365.25 = 4452.08032888280477602859 + \begin{itemize} + \arrowitem + $\frac{32,712\,\text{s}\,\cdot\,2^{32}}{3600\,\cdot\,24\,\cdot\,365,25} \approx 4452$ + Jahre\\[\smallskipamount] + für 64 Scheiben + \end{itemize} + \end{onlyenv} + \end{itemize} + + \pause + + Beispiel: Sortieralgorithmen + + \begin{itemize} + \item + Minimum suchen: \alt<4->{$\mathcal{O}(n)$}{$\mathcal{O}(\textbf{\color{red}?})$} + \pause + \item + \dots\ mit Schummeln: $\mathcal{O}(1)$ + \pause + \pause + \begin{picture}(0,0) + \put(-4.742,-3.7){\begin{minipage}[t]{12cm} + Faustregel:\\Schachtelung der Schleifen zählen\\ + $x$ Schleifen \textarrow\ $\mathcal{O}(n\w^x)$ +% \pause +% \begin{tabbing} +% Verschlüsselung brechen (Primfaktorzerlegung):~\=\kill +% \textbf{\color{red}RSA}: Schlüsselerzeugung (Berechnung von $d\/$): +% \> \color{red}$\mathcal{O}\bigl((\log n)^2\bigr)$,\\[\smallskipamount] +% Ver- und Entschlüsselung (Exponentiation): +% \> \color{red}$\mathcal{O}\kern0.5pt(n\log n)$,\\[0.5\smallskipamount] +% Verschlüsselung brechen (Primfaktorzerlegung): +% \> \color{red}$\mathcal{O}\bigl(2^{\sqrt{\log n\,\cdot\,\log\log n}}\bigr)$ +% \end{tabbing} + \end{minipage}} + \end{picture} + \pause + \item + Minimum an den Anfang tauschen,\\ + nächstes Minimum suchen:\\ + \textarrow\ Selectionsort\pause: $\mathcal{O}(n\w^2)$ +% \pause +% \item +% Während Minimumsuche prüfen\\und abbrechen, falls schon sortiert\\ +% \textarrow\ Bubblesort\pause: $\mathcal{O}(n)$ bis $\mathcal{O}(n\w^2)$ +% \pause +% \item +% Rekursiv sortieren\\ +% \textarrow\ Quicksort\pause: $\mathcal{O}(n\log n)$ bis $\mathcal{O}(n\w^2)$\hfill + \end{itemize} + +\end{frame} + +\nosectionnonumber{\inserttitle} + +\begin{frame} + + \shownosectionnonumber + + \begin{itemize} + \item[\textbf{1}] \textbf{Einführung} + \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp.git}}} + \item[\textbf{2}] \textbf{Einführung in C} + \item[\textbf{3}] \textbf{Bibliotheken} + \item[\textbf{4}] \textbf{Hardwarenahe Programmierung} + \begin{itemize} + \vspace*{-\smallskipamount} + \item[\dots] + \color{medgreen} + \item[4.5] volatile-Variable + \item[4.6] Byte-Reihenfolge -- Endianness + \item[4.7] Binärdarstellung negativer Zahlen + \item[4.8] Speicherausrichtung -- Alignment + \end{itemize} + \item[\textbf{5}] \textbf{Algorithmen} + \begin{itemize} + \color{medgreen} + \item[5.1] Differentialgleichungen + \item[5.2] Rekursion + \color{orange} + \item[5.3] Aufwandsabschätzungen + \end{itemize} + \item[\textbf{6}] \textbf{Objektorientierte Programmierung} + \item[\textbf{7}] \textbf{Datenstrukturen} + \end{itemize} + \vspace*{-1cm} + +\end{frame} + +\end{document} diff --git a/20181217/hp-uebung-20181217.pdf b/20181217/hp-uebung-20181217.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c08a5e53b945910716c84d9ed23568550ab63d0e Binary files /dev/null and b/20181217/hp-uebung-20181217.pdf differ diff --git a/20181217/hp-uebung-20181217.tex b/20181217/hp-uebung-20181217.tex new file mode 100644 index 0000000000000000000000000000000000000000..8848aff4dddcd698f904000b5c9b4ffbc8389be5 --- /dev/null +++ b/20181217/hp-uebung-20181217.tex @@ -0,0 +1,240 @@ +% hp-uebung-20181217.pdf - Exercises on Low-Level Programming / Applied Computer Sciences +% Copyright (C) 2013, 2015, 2016, 2017, 2018 Peter Gerwinski +% +% This document is free software: you can redistribute it and/or +% modify it either under the terms of the Creative Commons +% Attribution-ShareAlike 3.0 License, or under the terms of the +% GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% This document is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this document. If not, see <http://www.gnu.org/licenses/>. +% +% You should have received a copy of the Creative Commons +% Attribution-ShareAlike 3.0 Unported License along with this +% document. If not, see <http://creativecommons.org/licenses/>. + +% README: Fakultät, Lauflicht, Länge von Strings (Neuauflage) + +\documentclass[a4paper]{article} + +\usepackage{pgscript} + +\begin{document} + +% \thispagestyle{empty} + + \section*{Hardwarenahe Programmierung\\ + Übungsaufgaben -- 17.\ Dezember 2018} + + Diese Übung enthält Punkteangaben wie in einer Klausur. + Um zu "`bestehen"', müssen Sie innerhalb von 100 Minuten + unter Verwendung ausschließlich zugelassener Hilfsmittel + 18 Punkte (von insgesamt \totalpoints) erreichen. + + \exercise{Fakultät} + + Die Fakultät $n!$ einer ganzen Zahl $n \ge 0$ ist definiert als: + \begin{eqnarray*} + 1 & \mbox{für} & n = 0, \\ + n \cdot (n-1)! & \mbox{für} & n > 0. + \end{eqnarray*} + + Mit anderen Worten: $n! = 1\cdot2\cdot3\cdot\dots\cdot n$. + + Die folgende Funktion \lstinline{fak()} berechnet die Fakultät \emph{rekursiv} + (Datei: \gitfile{hp}{20181217}{aufgabe-1.c}): + + \begin{lstlisting} + int fak (int n) + { + if (n <= 0) + return 1; + else + return n * fak (n - 1); + } + \end{lstlisting} + + \begin{enumerate}[\quad(a)] + \item + Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\ + d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion. + \points{3} + \item + Wie viele Multiplikationen (Landau-Symbol) + erfordern beide Versionen der Fakultätsfunktion\\ + in Abhängigkeit von \lstinline$n$? + Begründen Sie Ihre Antwort. + \points{2} + \item + Wieviel Speicherplatz (Landau-Symbol) + erfordern beide Versionen der Fakultätsfunktion\\ + in Abhängigkeit von \lstinline$n$? + Begründen Sie Ihre Antwort. + \points{3} + \end{enumerate} + + \exercise{Lauflicht} + + \begin{minipage}[t]{8cm} + An die vier Ports eines ATmega16-Mikrocontrollers sind Leuchtdioden angeschlossen: + \begin{itemize} + \item + von links nach rechts\\ + an die Ports A, B, C und D, + \item + von oben nach unten\\ + an die Bits Nr.\ 0 bis 7. + + \bigskip + + \includegraphics[width=3cm]{leds.jpg} + \end{itemize} + \end{minipage}\hfill + \begin{minipage}[t]{7cm} + Wir betrachten das folgende C-Programm (Datei: \gitfile{hp}{20181217}{aufgabe-2.c}) + für diesen Mikrocontroller: + + \begin{lstlisting}[gobble=6] + #include <avr/io.h> + #include <avr/interrupt.h> + + int counter = 0; + + ISR (TIMER0_COMP_vect) + { + PORTA = 1 << ((counter++ >> 6) & 7); + } + + int main (void) + { + cli (); + TCCR0 = (1 << CS01) | (1 << CS00); + TIMSK = 1 << OCIE0; + sei (); + DDRA = 0xff; + while (1); + return 0; + } + \end{lstlisting} + \end{minipage} + + \medskip + + Das Programm bewirkt ein periodisches Lauflicht in der linken Spalte von oben nach unten. + Eine Animation davon finden Sie in der Datei \gitfile{hp}{20181217}{aufgabe-2.gif}. + + \begin{itemize} + \item[(a)] + Wieso bewirkt das Programm überhaupt etwas, wenn doch das Hauptprogramm + nach dem Initialisieren lediglich eine Endlosschleife ausführt, + in der \emph{nichts\/} passiert? \points 3 + \item[(b)] + Erklären Sie, wie die Anweisung + \begin{lstlisting}[gobble=8] + PORTA = 1 << ((counter++ >> 6) & 7); + \end{lstlisting} + \vspace{-\medskipamount} + das LED-Blinkmuster hervorruft. \points 6 + + Hinweis: Zerlegen Sie die eine lange Anweisung in mehrere kürzere.\\ + Wenn nötig, verwenden Sie zusätzliche Variable für Zwischenergebnisse. + \item[(c)] + Was bedeutet "`\lstinline{ISR (TIMER0_COMP_vect)}"'? \points 1 + \item[(d)] + Wieso leuchten die Leuchtdioden PB2 und PD1? \points 2 + \end{itemize} + + \exercise{Länge von Strings} + + Diese Aufgabe ist eine Neuauflage von Aufgabe 3 der + Übung vom 5.\ November 2017,\\ + ergänzt um die Teilaufgaben (f) und (g). + + \medskip + + Strings werden in der Programmiersprache C durch Zeiger auf \lstinline{char}-Variable realisiert. + + Beispiel: \lstinline{char *hello_world = "Hello, world!\n"} + + Die Systembibliothek stellt eine Funktion \lstinline{strlen()} zur Ermittlung der Länge von Strings\\ + zur Verfügung (\lstinline{#include <string.h>}). + + \begin{enumerate}[\quad(a)] + \item + Auf welche Weise ist die Länge eines Strings gekennzeichnet? + \points 1 + \item + Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"}, + und wieviel Speicherplatz belegt sie?\\ + \points 2 + \item + Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)}, + die die Länge eines Strings zurückgibt.\\ + \points 3 + \end{enumerate} + + Wir betrachten nun die folgenden Funktionen (Datei: \gitfile{hp}{20181217}{aufgabe-3.c}): + \begin{center} + \begin{minipage}{8cm} + \begin{lstlisting}[gobble=8] + int fun_1 (char *s) + { + int x = 0; + for (int i = 0; i < strlen (s); i++) + x += s[i]; + return x; + } + \end{lstlisting} + \end{minipage}% + \begin{minipage}{6cm} + \vspace*{-1cm} + \begin{lstlisting}[gobble=8] + int fun_2 (char *s) + { + int i = 0, x = 0; + int len = strlen (s); + while (i < len) + x += s[i++]; + return x; + } + \end{lstlisting} + \vspace*{-1cm} + \end{minipage} + \end{center} + \begin{enumerate}[\quad(a)]\setcounter{enumi}{3} + \item + Was bewirken die beiden Funktionen? + \points 2 + \item + Schreiben Sie eine eigene Funktion, + die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},\\ + nur effizienter. + \points 4 + \item + Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen + hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String? + Begründen Sie Ihre Antwort. + Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen. + \points 3 + \item + Von welcher Ordnung (Landau-Symbol) ist Ihre effizientere Funktion?\\ + Begründen Sie Ihre Antwort. + \points 1 + \end{enumerate} + + \begin{flushright} + \textit{Viel Erfolg!} + \end{flushright} + + \makeatletter + \immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}} + \makeatother + +\end{document} diff --git a/20181217/landau-symbols.pdf b/20181217/landau-symbols.pdf new file mode 120000 index 0000000000000000000000000000000000000000..ca145425bf07439c680632aa0663f84be601a565 --- /dev/null +++ b/20181217/landau-symbols.pdf @@ -0,0 +1 @@ +../common/landau-symbols.pdf \ No newline at end of file diff --git a/20181217/leds.jpg b/20181217/leds.jpg new file mode 120000 index 0000000000000000000000000000000000000000..5e66b77c5c428129f6f4abcc80ae48f0c9a53c35 --- /dev/null +++ b/20181217/leds.jpg @@ -0,0 +1 @@ +../common/leds.jpg \ No newline at end of file diff --git a/20181217/logo-hochschule-bochum-cvh-text-v2.pdf b/20181217/logo-hochschule-bochum-cvh-text-v2.pdf new file mode 120000 index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8 --- /dev/null +++ b/20181217/logo-hochschule-bochum-cvh-text-v2.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum-cvh-text-v2.pdf \ No newline at end of file diff --git a/20181217/logo-hochschule-bochum.pdf b/20181217/logo-hochschule-bochum.pdf new file mode 120000 index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1 --- /dev/null +++ b/20181217/logo-hochschule-bochum.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum.pdf \ No newline at end of file diff --git a/20181217/names.h b/20181217/names.h new file mode 100644 index 0000000000000000000000000000000000000000..a265ff4141a2cc578d3f6f402822a2dbbd5cea90 --- /dev/null +++ b/20181217/names.h @@ -0,0 +1,50 @@ +"Michael", "Laura", +"Elias", "Julia", +"Luca", "Anna", +"Liam", "Emma", +"Alexander", "Lena", +"Noah", "Vanessa", +"Jonas", "Lea", +"Marcel", "Mila", +"Daniel", "Lisa", +"David", "Lina", +"Milan", "Sarah", +"Julian", "Alina", +"Linus", "Emilia", +"Thomas", "Nina", +"Samuel", "Elena", +"Levin", "Lara", +"Levi", "Melanie", +"Jan", "Hannah", +"Lukas", "Sandra", +"Tim", "Leonie", +"Patrick", "Sophie", +"Marvin", "Mia", +"Andreas", "Amelie", +"Leon", "Selina", +"Tobias", "Luisa", +"Simon", "Maria", +"Valentin", "Jana", +"Robin", "Johanna", +"Paul", "Marie", +"Markus", "Milena", +"Benjamin", "Melina", +"Stefan", "Michelle", +"Felix", "Emily", +"Florian", "Renesmee", +"Fabian", "Aylin", +"Emil", "Jessica", +"Aaron", "Franziska", +"Manuel", "Jasmin", +"Christian", "Fiona", +"Dominik", "Sina", +"Joshua", "Jennifer", +"Moritz", "Claudia", +"Sebastian", "Nicole", +"Peter", "Annika", +"Philipp", "Sophia", +"Max", "Katharina", +"Johannes", "Isabella", +"Finn", "Nele", +"Adrian", "Elisabeth", +"Martin", "Pia", diff --git a/20181217/pgscript.sty b/20181217/pgscript.sty new file mode 120000 index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b --- /dev/null +++ b/20181217/pgscript.sty @@ -0,0 +1 @@ +../common/pgscript.sty \ No newline at end of file diff --git a/20181217/pgslides.sty b/20181217/pgslides.sty new file mode 120000 index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64 --- /dev/null +++ b/20181217/pgslides.sty @@ -0,0 +1 @@ +../common/pgslides.sty \ No newline at end of file diff --git a/20181217/sort-0.c b/20181217/sort-0.c new file mode 100644 index 0000000000000000000000000000000000000000..70e0e717cbfd42a27bf90f419c216fa18b0783c7 --- /dev/null +++ b/20181217/sort-0.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +int find_first (char **name) +{ + return 2; +} + +int main (void) +{ + char *name[] = { "Otto", "Lisa", "Anna", "Heinrich", "Siegfried", "Peter", + "Dieter", "Hugo", "Berta", "Maria", "Fritz", "Box", "Hans", + "Thomas", "Ulrich", "Zacharias", NULL }; + int first = find_first (name); + printf ("%s\n", name[first]); + return 0; +} diff --git a/20181217/sort-1.c b/20181217/sort-1.c new file mode 100644 index 0000000000000000000000000000000000000000..3f009d45657f84e462db48a67fa22821819216ad --- /dev/null +++ b/20181217/sort-1.c @@ -0,0 +1,21 @@ +#include <stdio.h> +#include <string.h> + +int find_first (char **name) +{ + int first = 0; + for (int i = 1; name[i]; i++) + if (strcmp (name[i], name[first]) < 0) + first = i; + return first; +} + +int main (void) +{ + char *name[] = { "Otto", "Lisa", "Anna", "Heinrich", "Siegfried", "Peter", + "Dieter", "Hugo", "Berta", "Maria", "Fritz", "Box", "Hans", + "Thomas", "Ulrich", "Zacharias", NULL }; + int first = find_first (name); + printf ("%s\n", name[first]); + return 0; +} diff --git a/20181217/sort-2.c b/20181217/sort-2.c new file mode 100644 index 0000000000000000000000000000000000000000..638e6e2caa670ceace0a854d0827292dfcb59ca5 --- /dev/null +++ b/20181217/sort-2.c @@ -0,0 +1,46 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int comparisons = 0; + +void display (char **name, int left, int right) +{ + printf ("\e[H\e[J"); + for (int i = 0; name[i]; i++) + { + printf ("%s", name[i]); + if (i == left || i == right) + printf (" <--"); + printf ("\n"); + } + printf ("%d\n", comparisons); +} + +int compare (char **name, int left, int right) +{ + int result = strcmp (name[left], name[right]); + comparisons++; + display (name, left, right); + usleep (200000); + return result; +} + +int find_first (char **name) +{ + int first = 0; + for (int i = 1; name[i]; i++) + if (compare (name, i, first) < 0) + first = i; + return first; +} + +int main (void) +{ + char *name[] = { "Otto", "Lisa", "Anna", "Heinrich", "Siegfried", "Peter", + "Dieter", "Hugo", "Berta", "Maria", "Fritz", "Box", "Hans", + "Thomas", "Ulrich", "Zacharias", NULL }; + int first = find_first (name); + display (name, first, -1); + return 0; +} diff --git a/20181217/sort-3.c b/20181217/sort-3.c new file mode 100644 index 0000000000000000000000000000000000000000..430a6fc0e95fcb9bc225e3572566c8d187016130 --- /dev/null +++ b/20181217/sort-3.c @@ -0,0 +1,46 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int comparisons = 0; + +void display (char **name, int left, int right) +{ + printf ("\e[H\e[J"); + for (int i = 0; name[i]; i++) + { + printf ("%s", name[i]); + if (i == left || i == right) + printf (" <--"); + printf ("\n"); + } + printf ("%d\n", comparisons); +} + +int compare (char **name, int left, int right) +{ + int result = strcmp (name[left], name[right]); + comparisons++; + display (name, left, right); + usleep (200000); + return result; +} + +int find_first (char **name, int i0) +{ + int first = i0; + for (int i = i0 + 1; name[i]; i++) + if (compare (name, i, first) < 0) + first = i; + return first; +} + +int main (void) +{ + char *name[] = { "Otto", "Lisa", "Anna", "Heinrich", "Siegfried", "Peter", + "Dieter", "Hugo", "Berta", "Maria", "Fritz", "Box", "Hans", + "Thomas", "Ulrich", "Zacharias", NULL }; + int first = find_first (name, 0); + display (name, first, -1); + return 0; +} diff --git a/20181217/sort-4.c b/20181217/sort-4.c new file mode 100644 index 0000000000000000000000000000000000000000..19d4f416a2d30c5181ad289fe1d0dcba91ee81cf --- /dev/null +++ b/20181217/sort-4.c @@ -0,0 +1,59 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int comparisons = 0; + +void display (char **name, int left, int right) +{ + printf ("\e[H\e[J"); + for (int i = 0; name[i]; i++) + { + printf ("%s", name[i]); + if (i == left || i == right) + printf (" <--"); + printf ("\n"); + } + printf ("%d\n", comparisons); +} + +int compare (char **name, int left, int right) +{ + int result = strcmp (name[left], name[right]); + comparisons++; + display (name, left, right); + usleep (200000); + return result; +} + +int find_first (char **name, int i0) +{ + int first = i0; + for (int i = i0 + 1; name[i]; i++) + if (compare (name, i, first) < 0) + first = i; + return first; +} + +void sort (char **name) +{ + int sorted = 0; + while (name[sorted]) + { + int first = find_first (name, sorted); + char *temp = name[sorted]; + name[sorted] = name[first]; + name[first] = temp; + sorted++; + } +} + +int main (void) +{ + char *name[] = { "Otto", "Lisa", "Anna", "Heinrich", "Siegfried", "Peter", + "Dieter", "Hugo", "Berta", "Maria", "Fritz", "Box", "Hans", + "Thomas", "Ulrich", "Zacharias", NULL }; + sort (name); + display (name, -1, -1); + return 0; +} diff --git a/20181217/sort-5.c b/20181217/sort-5.c new file mode 100644 index 0000000000000000000000000000000000000000..f0742bc8665d0b13edf4ad4ad3fe4790c1e6b929 --- /dev/null +++ b/20181217/sort-5.c @@ -0,0 +1,60 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int comparisons = 0; + +void display (char **name, int left, int right) +{ + printf ("\e[H\e[J"); + for (int i = 0; name[i]; i++) + { + printf ("%s", name[i]); + if (i == left || i == right) + printf (" <--"); + printf ("\n"); + } + printf ("%d\n", comparisons); +} + +int compare (char **name, int left, int right) +{ + int result = strcmp (name[left], name[right]); + comparisons++; + display (name, left, right); + usleep (200); + return result; +} + +int find_first (char **name, int i0) +{ + int first = i0; + for (int i = i0 + 1; name[i]; i++) + if (compare (name, i, first) < 0) + first = i; + return first; +} + +void sort (char **name) +{ + int sorted = 0; + while (name[sorted]) + { + int first = find_first (name, sorted); + char *temp = name[sorted]; + name[sorted] = name[first]; + name[first] = temp; + sorted++; + } +} + +int main (void) +{ + char *name[] = { + #include "names.h" + NULL + }; + sort (name); + display (name, -1, -1); + return 0; +} diff --git a/20181217/sort-6.c b/20181217/sort-6.c new file mode 100644 index 0000000000000000000000000000000000000000..94a1a16abfacda7bb728f8d3317cd00b4cf8ccde --- /dev/null +++ b/20181217/sort-6.c @@ -0,0 +1,60 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int comparisons = 0; + +void display (char **name, int left, int right) +{ + printf ("\e[H\e[J"); + for (int i = 0; name[i]; i++) + { + printf ("%s", name[i]); + if (i == left || i == right) + printf (" <--"); + printf ("\n"); + } + printf ("%d\n", comparisons); +} + +int compare (char **name, int left, int right) +{ + int result = strcmp (name[left], name[right]); + comparisons++; +// display (name, left, right); +// usleep (200); + return result; +} + +int find_first (char **name, int i0) +{ + int first = i0; + for (int i = i0 + 1; name[i]; i++) + if (compare (name, i, first) < 0) + first = i; + return first; +} + +void sort (char **name) +{ + int sorted = 0; + while (name[sorted]) + { + int first = find_first (name, sorted); + char *temp = name[sorted]; + name[sorted] = name[first]; + name[first] = temp; + sorted++; + } +} + +int main (void) +{ + char *name[] = { + #include "names.h" + NULL + }; + sort (name); + display (name, -1, -1); + return 0; +} diff --git a/20181217/sort-7.c b/20181217/sort-7.c new file mode 100644 index 0000000000000000000000000000000000000000..46132dd247a061dda0e5ebade9c5b818a1a74fcb --- /dev/null +++ b/20181217/sort-7.c @@ -0,0 +1,53 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int comparisons = 0; + +void display (char **name, int left, int right) +{ + printf ("\e[H\e[J"); + for (int i = 0; name[i]; i++) + { + printf ("%s", name[i]); + if (i == left || i == right) + printf (" <--"); + printf ("\n"); + } + printf ("%d\n", comparisons); +} + +int compare (char **name, int left, int right) +{ + int result = strcmp (name[left], name[right]); + comparisons++; + display (name, left, right); + usleep (200000); + return result; +} + +void sort (char **name) +{ + int sorted = 0; + while (name[sorted]) + { + int first = sorted; + for (int i = sorted + 1; name[i]; i++) + if (compare (name, i, first) < 0) + first = i; + char *temp = name[sorted]; + name[sorted] = name[first]; + name[first] = temp; + sorted++; + } +} + +int main (void) +{ + char *name[] = { "Otto", "Lisa", "Anna", "Heinrich", "Siegfried", "Peter", + "Dieter", "Hugo", "Berta", "Maria", "Fritz", "Box", "Hans", + "Thomas", "Ulrich", "Zacharias", NULL }; + sort (name); + display (name, -1, -1); + return 0; +} diff --git a/README.md b/README.md index 21b4f85b1ea7185ccace3c6c3c0a6c6b5a10967d..7cbf9838eaa48b2b4bdd8ae614caede514f88bf9 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Vortragsfolien: * [26.11.2018: make; Hardwarenahe Programmierung: Zahlensysteme, Bit-Operationen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181126/hp-20181126.pdf) * [03.12.2018: Bit-Operationen, Programmierung von Mikrocontrollern, I/O-Ports, Interrupts](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181203/hp-20181203.pdf) * [10.12.2018: volatile-Variable, Byte-Reihenfolge - Endianness, Binärdarstellung negativer Zahlen, Speicherausrichtung - Alignment](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181210/hp-20181210.pdf) + * [17.12.2018: Rekursion, Aufwandsabschätzungen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181217/hp-20181217.pdf) * [alle in 1 Datei](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/hp-slides-2018ws.pdf) Übungsaufgaben: @@ -41,6 +42,7 @@ Vortragsfolien: * [26.11.2018: Zahlensysteme, Mikrocontroller](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181126/hp-uebung-20181126.pdf) * [03.12.2018: XBM-Grafik, LED-Blinkmuster](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181203/hp-uebung-20181203.pdf) * [10.12.2018: Trickprogrammierung, Thermometer-Baustein an I²C-Bus](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181210/hp-uebung-20181210.pdf) + * [17.12.2018: Fakultät, Lauflicht, Länge von Strings (Neuauflage)](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181217/hp-uebung-20181217.pdf) Musterlösungen: --------------- @@ -56,6 +58,7 @@ Tafelbilder: * [12.11.2018: Differentialgleichung für gleichförmige und gleichmäßig beschleunigte Bewegung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181112/photo-20181112-173737.jpg) * [26.11.2018: Prakikumstermine, Bit-Operationen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181126/photo-20181126-174025.jpg) * [03.12.2018: Pull-Down- und Pull-Up-Widerstand](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181203/photo-20181203-173451.jpg) + * [10.12.2018: Grafik abspeichern; Zweierkomplement auf 4-Bit-Rechner](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181210/photo-20181210-173116.jpg) Praktikumsunterlagen: --------------------- diff --git a/hp-slides-2018ws.pdf b/hp-slides-2018ws.pdf index cdc39ee27d169e8c84d84022161f8d28e9a4de78..bb84601d91dff6f393de6df658211a63ae9200f0 100644 Binary files a/hp-slides-2018ws.pdf and b/hp-slides-2018ws.pdf differ diff --git a/hp-slides-2018ws.tex b/hp-slides-2018ws.tex index 2a2e8ee1b71924318513aa3dd8bdee4ce7331269..2e80bef0ae0d3290e2c0d83769f4428ea7461f8b 100644 --- a/hp-slides-2018ws.tex +++ b/hp-slides-2018ws.tex @@ -30,4 +30,6 @@ \includepdf[pages=-]{20181203/hp-20181203.pdf} \pdfbookmark[1]{10.12.2018: volatile-Variable, Byte-Reihenfolge - Endianness, Binärdarstellung negativer Zahlen, Speicherausrichtung - Alignment}{20181210} \includepdf[pages=-]{20181210/hp-20181210.pdf} + \pdfbookmark[1]{17.12.2018: Rekursion, Aufwandsabschätzungen}{20181217} + \includepdf[pages=-]{20181217/hp-20181217.pdf} \end{document}