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}