diff --git a/20231102/Makefile-1 b/20231102/Makefile-1
new file mode 100644
index 0000000000000000000000000000000000000000..bfc1b10a929f22a8c2f4f0cf0368c78db14ad0b0
--- /dev/null
+++ b/20231102/Makefile-1
@@ -0,0 +1,8 @@
+philosophy: philosophy.o answer.o
+	gcc philosophy.o answer.o -o philosophy
+
+answer.o: answer.c answer.h
+	gcc -Wall -O answer.c -c
+
+philosophy.o: philosophy.c answer.h
+	gcc -Wall -O philosophy.c -c
diff --git a/20231102/Makefile-2 b/20231102/Makefile-2
new file mode 100644
index 0000000000000000000000000000000000000000..60aab7c7d51b28879c41e8590ab422e9edfadee5
--- /dev/null
+++ b/20231102/Makefile-2
@@ -0,0 +1,16 @@
+TARGET = philosophy
+OBJECTS = philosophy.o answer.o
+HEADERS = answer.h
+CFLAGS = -Wall -O
+
+$(TARGET): $(OBJECTS)
+	gcc $(OBJECTS) -o $(TARGET)
+
+answer.o: answer.c $(HEADERS)
+	gcc $(CFLAGS) answer.c -c
+
+philosophy.o: philosophy.c $(HEADERS)
+	gcc $(CFLAGS) philosophy.c -c
+
+clean:
+	rm -f $(OBJECTS) $(TARGET)
diff --git a/20231102/Makefile-3 b/20231102/Makefile-3
new file mode 100644
index 0000000000000000000000000000000000000000..0ac355bfddfd237fe0f1b5062c5a242ab0d3e97e
--- /dev/null
+++ b/20231102/Makefile-3
@@ -0,0 +1,13 @@
+TARGET = philosophy
+OBJECTS = philosophy.o answer.o
+HEADERS = answer.h
+CFLAGS = -Wall -O
+
+$(TARGET): $(OBJECTS)
+	gcc $(OBJECTS) -o $(TARGET)
+
+%.o: %.c $(HEADERS)
+	gcc $(CFLAGS) $< -c
+
+clean:
+	rm -f $(OBJECTS) $(TARGET)
diff --git a/20231102/aufgabe-3.c b/20231102/aufgabe-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..9ae72941b931c04f3c380cb3bbcd64bec7f08c20
--- /dev/null
+++ b/20231102/aufgabe-3.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <string.h>
+
+void insert_into_string (char src, char *target, int pos)
+{
+  int len = strlen (target);
+  for (int i = pos; i < len; i++)
+    target[i+1] = target[i];
+  target[pos] = src;
+}
+
+int main (void)
+{
+  char test[100] = "Hochshule Bochum";
+  insert_into_string ('c', test, 5);
+  printf ("%s\n", test);
+  return 0;
+}
diff --git a/20231102/hp-20231102.pdf b/20231102/hp-20231102.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..bec0c954a377bc13efe2cc1f7a79aded717ef2c0
Binary files /dev/null and b/20231102/hp-20231102.pdf differ
diff --git a/20231102/hp-20231102.tex b/20231102/hp-20231102.tex
new file mode 100644
index 0000000000000000000000000000000000000000..435fb26e793f7e09ef15222e168ed674fad161a2
--- /dev/null
+++ b/20231102/hp-20231102.tex
@@ -0,0 +1,801 @@
+% hp-20231102.pdf - Lecture Slides on Low-Level Programming
+% Copyright (C) 2012, 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023  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: Bibliotheken
+
+\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}
+
+\newcommand{\redurl}[1]{\href{#1}{\color{red}\nolinkurl{#1}}}
+
+\title{Hardwarenahe Programmierung}
+\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski}
+\date{2.\ November 2023}
+
+\begin{document}
+
+\maketitleframe
+
+%\date{\begin{picture}(0,0)
+%        \color{red}
+%        \put(0.65,1.05){\makebox(0,0)[t]{$\underbrace{\rule{1.45cm}{0pt}}_{%
+%          \mbox{\emph{rerum naturalium\/} = der natürlichen Dinge (lat.)}}$}}
+%        \put(1.65,-3){\makebox(0,0)[bl]{\redurl{https://www.peter.gerwinski.de/physik/}}}
+%      \end{picture}%
+%      12.\ Oktober 2023}
+%
+%\maketitleframe
+
+\title{Hardwarenahe Programmierung}
+
+\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}}}
+    \item[\textbf{2}] \textbf{Einführung in C}
+      \begin{itemize}
+        \vspace{-1.5\smallskipamount}
+        \item[\dots]
+        \item[2.11] Arrays und Strings
+        \item[2.12] Strukturen
+        \item[2.13] Dateien und Fehlerbehandlung
+        \item[2.14] Parameter des Hauptprogramms
+        \color{medgreen}
+        \item[2.15] String-Operationen
+      \end{itemize}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+      \begin{itemize}
+        \color{medgreen}
+        \item[3.1] Der Präprozessor
+        \item[3.2] Bibliotheken einbinden
+        \item[3.3] Bibliotheken verwenden
+        \color{orange}
+        \item[3.4] Callbacks
+        \color{red}
+        \item[3.5] Projekt organisieren: make
+      \end{itemize}
+    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+    \vspace*{-\smallskipamount}
+    \item[\textbf{\dots}]
+%    \item[\textbf{5}] \textbf{Algorithmen}
+%    \item[\textbf{6}] \textbf{Ergänzungen und Ausblicke}
+  \end{itemize}
+
+\end{frame}
+
+\section{Einführung}
+\section{Einführung in C}
+\setcounter{subsection}{14}
+\subsection{String-Operationen}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+%  \vspace*{-0.4cm}
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    int main (void)
+    {
+      char hello[] = "Hello, world!\n";
+
+      printf ("%s\n", hello);
+      printf ("%zd\n", strlen (hello));
+
+      printf ("%s\n", hello + 7);
+      printf ("%zd\n", strlen (hello + 7));
+
+      hello[5] = 0;
+      printf ("%s\n", hello);
+      printf ("%zd\n", strlen (hello));
+
+      return 0;
+    }
+  \end{lstlisting}
+  \vspace*{-1cm}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+%  \vspace*{-0.4cm}
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    int main (void)
+    {
+      char *anton = "Anton";
+      char *zacharias = "Zacharias";
+
+      printf ("%d\n", strcmp (anton, zacharias));
+      printf ("%d\n", strcmp (zacharias, anton));
+      printf ("%d\n", strcmp (anton, anton));
+
+      char buffer[100] = "Huber ";
+      strcat (buffer, anton);
+      printf ("%s\n", buffer);
+
+      return 0;
+    }
+  \end{lstlisting}
+  \vspace*{-1cm}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+%  \vspace*{-0.4cm}
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    int main (void)
+    {
+      char buffer[100] = "";
+      sprintf (buffer, "Die Antwort lautet: %d", 42);
+      printf ("%s\n", buffer);
+
+      char *answer = strstr (buffer, "Antwort");
+      printf ("%s\n", answer);
+      printf ("found at: %zd\n", answer - buffer);
+
+      return 0;
+    }
+  \end{lstlisting}
+  \vspace*{-1cm}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+%  \vspace*{-0.4cm}
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    int main (void)
+    {
+      char buffer[100] = "";
+      snprintf (buffer, 100, "Die Antwort lautet: %d", 42);
+      printf ("%s\n", buffer);
+
+      char *answer = strstr (buffer, "Antwort");
+      printf ("%s\n", answer);
+      printf ("found at: %zd\n", answer - buffer);
+
+      return 0;
+    }
+  \end{lstlisting}
+
+\end{frame}
+
+\begin{frame}
+
+  \showsection
+
+  Sprachelemente weitgehend komplett
+
+  \bigskip
+  Es fehlen:
+  \begin{itemize}
+    \item
+      Ergänzungen (z.\,B.\ ternärer Operator, \lstinline{union}, \lstinline{unsigned}, \lstinline{volatile})
+    \item
+      Bibliotheksfunktionen (z.\,B.\ \lstinline{malloc()})
+    \arrowitem
+      werden eingeführt, wenn wir sie brauchen
+    \bigskip
+    \item
+      Konzepte (z.\,B.\ rekursive Datenstrukturen, Klassen selbst bauen)
+    \arrowitem
+      werden eingeführt, wenn wir sie brauchen, oder:
+    \arrowitem
+      Literatur\\[\smallskipamount]
+      (z.\,B.\ Wikibooks: C-Programmierung,\\
+      Dokumentation zu Compiler und Bibliotheken)
+    \bigskip
+    \item
+      Praxiserfahrung
+    \arrowitem
+      Übung und Praktikum: nur Einstieg
+    \arrowitem
+      selbständig arbeiten
+  \end{itemize}
+\end{frame}
+
+\section{Bibliotheken}
+\subsection{Der Präprozessor}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \lstinline{#include}: %\pause:
+  Text einbinden
+  \begin{itemize}
+%    \pause
+    \item
+      \lstinline{#include <stdio.h>}: Standard-Verzeichnisse -- Standard-Header
+%    \pause
+    \item
+      \lstinline{#include "answer.h"}: auch aktuelles Verzeichnis -- eigene Header
+  \end{itemize}
+
+%  \pause
+  \bigskip
+
+  \lstinline{#define SIX 6}: Text ersetzen lassen -- Konstante definieren
+  \begin{itemize}
+%    \pause
+    \item
+      Kein Semikolon!
+%    \pause
+    \item
+      Berechnungen in Klammern setzen:\\
+      \lstinline{#define SIX (1 + 5)}
+%    \pause
+    \item
+      Konvention: Großbuchstaben
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Bibliotheken einbinden}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  Inhalt der Header-Datei: externe Deklarationen
+
+%  \pause
+  \smallskip
+  \lstinline{extern int answer (void);}
+
+%  \pause
+  \smallskip
+  \lstinline{extern int printf (__const char *__restrict __format, ...);}
+
+%  \pause
+  \bigskip
+  Funktion wird "`anderswo"' definiert
+  \begin{itemize}
+%    \pause
+    \item
+      separater C-Quelltext: mit an \lstinline[style=terminal]{gcc} übergeben
+%    \pause
+    \item
+      Zusammenfügen zu ausführbarem Programm durch den \newterm{Linker}
+%    \pause
+    \item
+      vorcompilierte Bibliothek: \lstinline[style=terminal]{-lfoo}\\
+%      \pause
+      = Datei \file{libfoo.a} in Standard-Verzeichnis
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Bibliothek verwenden (Beispiel: GTK)}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{itemize}
+    \item
+      \lstinline{#include <gtk/gtk.h>}
+    \pause
+    \smallskip
+    \item
+      Mit \lstinline[style=cmd]{pkg-config --cflags --libs gtk4} erfährt man,\\
+      welche Optionen und Bibliotheken man an \lstinline[style=cmd]{gcc}
+      übergeben muß\alt<4->{.}{:}
+      \pause
+      \begin{onlyenv}<3>
+        \begin{lstlisting}[style=terminal,gobble=10]
+          $ ¡pkg-config --cflags --libs gtk4¿
+          -I/usr/include/gtk-4.0 -I/usr/include/pango-1.0 -I/usr/
+          include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/i
+          nclude -I/usr/include/harfbuzz -I/usr/include/freetype2
+          -I/usr/include/libpng16 -I/usr/include/libmount -I/usr/
+          include/blkid -I/usr/include/fribidi -I/usr/include/cai
+          ro -I/usr/include/pixman-1 -I/usr/include/gdk-pixbuf-2.
+          0 -I/usr/include/x86_64-linux-gnu -I/usr/include/graphe
+          ne-1.0 -I/usr/lib/x86_64-linux-gnu/graphene-1.0/include
+          -mfpmath=sse -msse -msse2 -pthread -lgtk-4 -lpangocairo
+          -1.0 -lpango-1.0 -lharfbuzz -lgdk_pixbuf-2.0 -lcairo-go
+          bject -lcairo -lgraphene-1.0 -lgio-2.0 -lgobject-2.0 -l
+          glib-2.0 
+        \end{lstlisting}
+        \vspace*{-3cm}
+      \end{onlyenv}
+    \pause
+    \arrowitem
+      Compiler-Aufruf:
+      \begin{onlyenv}<4>
+        \begin{lstlisting}[style=terminal,gobble=10]
+          $ ¡gcc -Wall -O hello-gtk.c -I/usr/include/gtk-4.0 -I/u
+          sr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib
+          /x86_64-linux-gnu/glib-2.0/include -I/usr/include/harfb
+          uzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I
+          /usr/include/libmount -I/usr/include/blkid -I/usr/inclu
+          de/fribidi -I/usr/include/cairo -I/usr/include/pixman-1
+          -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/x86_64-lin
+          ux-gnu -I/usr/include/graphene-1.0 -I/usr/lib/x86_64-li
+          nux-gnu/graphene-1.0/include -mfpmath=sse -msse -msse2
+          -pthread -lgtk-4 -lpangocairo -1.0 -lpango-1.0 -lharfbu
+          zz -lgdk_pixbuf-2.0 -lcairo-gobject -lcairo -lgraphene-
+          1.0 -lgio-2.0 -lgobject-2.0 -l glib-2.0 -o hello-gtk¿
+        \end{lstlisting}
+        \vspace*{-2cm}
+      \end{onlyenv}
+      \begin{onlyenv}<5->
+        \begin{lstlisting}[style=terminal,gobble=10]
+          $ ¡gcc -Wall -O hello-gtk.c $(pkg-config --cflags --libs
+                 gtk4) -o hello-gtk¿
+        \end{lstlisting}
+      \end{onlyenv}
+      \begin{onlyenv}<5>
+        \begin{picture}(0,0)(0.3,0.3)
+          \color{red}
+          \put(6.6,-0.6){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(3,1.5);}}}
+          \put(6.3,-0.7){\makebox(0,0)[t]{\shortstack{\strut Optionen:\\
+                           \strut u.\,a.\ viele Include-Verzeichnisse:\\
+                           \lstinline[style=cmd]{-I/usr/include/gtk-4.0}}}}
+          \put(10.0,-2.1){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(1.5,3);}}}
+          \put(10.3,-2.2){\makebox(0,0)[t]{\shortstack{\strut Bibliotheken:\\
+                            \strut u.\,a.\ \lstinline[style=cmd]{-lgtk-4}}}}
+        \end{picture}
+      \end{onlyenv}
+    \pause
+    \pause
+    \item
+      Auf manchen Plattformen kommt es auf die Reihenfolge an:
+      \begin{lstlisting}[style=terminal,gobble=8]
+        $ ¡gcc -Wall -O $(pkg-config --cflags gtk4) \
+               hello-gtk.c $(pkg-config --libs gtk4) \
+               -o hello-gtk¿
+      \end{lstlisting}
+      (Backslash = "`Es geht in der nächsten Zeile weiter."')
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Callbacks}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Selbst geschriebene Funktion übergeben: \newterm{Callback}
+
+  \bigskip
+
+  \begin{lstlisting}[xleftmargin=1em]
+    static void hello (GtkWidget *this, gpointer user_data)
+    {
+      char *world = user_data;
+      printf ("Hello, %s!\n", world);
+    }
+  
+    ...
+
+    g_signal_connect (button, "clicked", G_CALLBACK (hello), "world");
+  \end{lstlisting}
+
+  \medskip
+
+  \begin{itemize}
+    \arrowitem 
+      GTK ruft immer dann, wenn der Button betätigt wurde,\\
+      die Funktion \lstinline{hello} auf.
+  \end{itemize}
+
+  \pause
+  \begin{picture}(0,0)(1.1,0.8)
+    \color{red}
+    \put(9.7,5.1){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.3,0.5);}}}
+    \put(10.0,5.0){\makebox(0,0)[t]{\shortstack{\strut optionale Zusatzinformationen\\
+                     \strut für hello(), hier ein String\\
+                     \strut oft ein Zeiger auf ein struct}}}
+    \put(10.5,3.5){\makebox(0,0)[tl]{\tikz{\draw[-latex](0,0)--(0.3,-0.5);}}}
+  \end{picture}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Selbst geschriebene Funktion übergeben: \newterm{Callback}
+
+  \bigskip
+
+  \begin{lstlisting}[xleftmargin=1em]
+    static void draw (GtkDrawingArea *drawing_area, cairo_t *c,
+                      int width, int height, gpointer user_data)
+    {
+      /* Zeichenbefehle */
+      ...
+    }
+  
+    ...
+
+    gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area),
+                                       draw, NULL, NULL);
+  \end{lstlisting}
+
+  \medskip
+
+  \begin{itemize}
+    \arrowitem 
+      GTK ruft immer dann, wenn es etwas zu zeichnen gibt,\\
+      die Funktion \lstinline{draw} auf.
+  \end{itemize}
+
+  \pause
+  \begin{picture}(0,0)
+    \color{red}
+    \put(10.0,4.9){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.3,0.9);}}}
+    \put(10.0,4.8){\makebox(0,0)[t]{\shortstack{\strut repräsentiert den\\
+                     \strut Bildschirm, auf den\\
+                     \strut gezeichnet werden soll}}}
+  \end{picture}
+
+\end{frame}
+
+\iffalse
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Selbst geschriebene Funktion übergeben: \newterm{Callback}
+
+  \bigskip
+
+  \begin{lstlisting}[xleftmargin=1em]
+    gboolean timer (GtkWidget *widget)
+    {
+      /* Rechenbefehle */
+      ...
+
+      gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+      g_timeout_add (50, (GSourceFunc) timer, widget);
+      return FALSE;
+    }
+  
+    ...
+
+    g_timeout_add (50, (GSourceFunc) timer, drawing_area);
+  \end{lstlisting}
+
+  \medskip
+
+  \begin{itemize}
+    \arrowitem 
+      GTK+ ruft nach 50 Millisekunden
+      die Funktion \lstinline{timer} auf.
+  \end{itemize}
+
+  \pause
+  \begin{picture}(0,0)(-0.07,0.2)
+    \color{red}
+    \put(9.7,6.7){\makebox(0,0)[t]{\shortstack{\strut Dieser Bereich soll\\
+                    \strut neu gezeichnet werden.}}}
+    \put(9.7,5.7){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.6,-0.8);}}}
+    \pause
+    \put(4.3,3.2){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.7,0.6);}}}
+    \put(4.3,3.1){\makebox(0,0)[t]{\shortstack{\strut In weiteren 50 Millisekunden soll\\
+                    \strut die Funktion erneut aufgerufen werden.}}}
+    \pause
+    \put(9.3,2.9){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-3.3,0.9);}}}
+    \put(9.8,2.8){\makebox(0,0)[t]{\shortstack{\strut Explizite Typumwandlung\\
+                    \strut eines Zeigers (später)}}}
+  \end{picture}
+
+\end{frame}
+
+\fi
+
+\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}}}
+    \item[\textbf{2}] \textbf{Einführung in C}
+      \begin{itemize}
+        \vspace{-1.5\smallskipamount}
+        \item[\dots]
+        \item[2.11] Arrays und Strings
+        \item[2.12] Strukturen
+        \item[2.13] Dateien und Fehlerbehandlung
+        \item[2.14] Parameter des Hauptprogramms
+        \color{medgreen}
+        \item[2.15] String-Operationen
+      \end{itemize}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+      \begin{itemize}
+        \color{medgreen}
+        \item[3.1] Der Präprozessor
+        \item[3.2] Bibliotheken einbinden
+        \item[3.3] Bibliotheken verwenden
+        \color{orange}
+        \item[3.4] Callbacks
+        \color{red}
+        \item[3.5] Projekt organisieren: make
+      \end{itemize}
+    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+    \vspace*{-\smallskipamount}
+    \item[\textbf{\dots}]
+%    \item[\textbf{5}] \textbf{Algorithmen}
+%    \item[\textbf{6}] \textbf{Ergänzungen und Ausblicke}
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Projekt organisieren: make}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+  \begin{itemize}
+    \item
+      \only<4->{explizite und implizite} Regeln
+      \begin{onlyenv}<2>
+        \smallskip
+        \begin{lstlisting}[language=make,gobble=10]
+          philosophy: philosophy.o answer.o
+                  gcc philosophy.o answer.o -o philosophy
+
+          answer.o: answer.c answer.h
+                  gcc -Wall -O answer.c -c
+
+          philosophy.o: philosophy.c answer.h
+                  gcc -Wall -O philosophy.c -c
+        \end{lstlisting}
+      \end{onlyenv}
+      \begin{onlyenv}<4>
+        \smallskip
+        \begin{lstlisting}[language=make,gobble=10]
+          TARGET = philosophy
+          OBJECTS = philosophy.o answer.o
+          HEADERS = answer.h
+          CFLAGS = -Wall -O
+
+          $(TARGET): $(OBJECTS)
+                  gcc $(OBJECTS) -o $(TARGET)
+
+          %.o: %.c $(HEADERS)
+                  gcc $(CFLAGS) $< -c
+
+          clean:
+                  rm -f $(OBJECTS) $(TARGET)
+        \end{lstlisting}
+      \end{onlyenv}
+    \item
+      Makros
+      \begin{onlyenv}<3>
+        \smallskip
+        \begin{lstlisting}[language=make,gobble=10]
+          TARGET = philosophy
+          OBJECTS = philosophy.o answer.o
+          HEADERS = answer.h
+          CFLAGS = -Wall -O
+
+          $(TARGET): $(OBJECTS)
+                  gcc $(OBJECTS) -o $(TARGET)
+
+          answer.o: answer.c $(HEADERS)
+                  gcc $(CFLAGS) answer.c -c
+
+          philosophy.o: philosophy.c $(HEADERS)
+                  gcc $(CFLAGS) philosophy.c -c
+
+          clean:
+                  rm -f $(OBJECTS) $(TARGET)
+        \end{lstlisting}
+        \vspace*{-1cm}
+      \end{onlyenv}
+    \begin{onlyenv}<5->
+      \smallskip
+      \arrowitem
+        3 Sprachen: C, Präprozessor, make
+    \end{onlyenv}
+  \end{itemize}
+
+\end{frame}
+
+\section{Hardwarenahe Programmierung}
+\subsection{Bit-Operationen}
+\subsubsection{Zahlensysteme}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \vspace*{-\smallskipamount}
+  \showsubsection
+  \vspace*{-\medskipamount}
+  \showsubsubsection
+
+  \begin{tabular}{rlrl}
+    Basis & Name & Beispiel & Anwendung \\[\smallskipamount]
+      2 & Binärsystem & 1\,0000\,0011 & Bit-Operationen \\
+      8 & Oktalsystem & \lstinline,0403, & Dateizugriffsrechte (Unix) \\
+     10 & Dezimalsystem & \lstinline,259, & Alltag \\
+     16 & Hexadezimalsystem & \lstinline,0x103, & Bit-Operationen \\
+    256 & (keiner gebräuchlich) & 0.0.1.3 & IP-Adressen (IPv4)
+  \end{tabular}
+
+  \bigskip
+
+  \begin{itemize}
+    \item
+      Computer rechnen im Binärsystem.
+    \item
+      Für viele Anwendungen (z.\,B.\ I/O-Ports, Grafik, \dots) ist es notwendig,\\
+      Bits in Zahlen einzeln ansprechen zu können.
+  \end{itemize}
+
+\end{frame}
+
+\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}
+
+\end{document}
diff --git a/20231102/hp-musterloesung-20231102.pdf b/20231102/hp-musterloesung-20231102.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..c4d6f358ca66162c954859b82ddfd5a133ae99a4
Binary files /dev/null and b/20231102/hp-musterloesung-20231102.pdf differ
diff --git a/20231102/hp-musterloesung-20231102.tex b/20231102/hp-musterloesung-20231102.tex
new file mode 100644
index 0000000000000000000000000000000000000000..c08babb5a37b01520a2f1ea4a7ea064831186c5b
--- /dev/null
+++ b/20231102/hp-musterloesung-20231102.tex
@@ -0,0 +1,492 @@
+% hp-musterloesung-20231102.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023  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: Zahlensysteme, Ausgabe von Hexadezimalzahlen, Einfügen in Strings
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+\renewcommand{\breath}{\bigskip}
+
+\begin{document}
+
+  \section*{Hardwarenahe Programmierung\\
+            Musterlösung zu den Übungsaufgaben -- 2.\ November 2023}
+
+  \exercise{Zahlensysteme}
+
+  Wandeln Sie ohne Hilfsmittel
+
+  \begin{minipage}[t]{0.3\textwidth}
+    \begin{itemize}
+      \item
+        nach Dezimal:
+        \begin{itemize}
+          \item[(a)]
+            0010\,0000$_2$
+          \item[(b)]
+            42$_{16}$
+          \item[(c)]
+            17$_8$
+        \end{itemize}
+    \end{itemize}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.3\textwidth}
+    \begin{itemize}
+      \item
+        nach Hexadezimal:
+        \begin{itemize}
+          \item[(d)]
+            0010\,0000$_2$
+          \item[(e)]
+            42$_{10}$
+          \item[(f)]
+            192.168.20.254$_{256}$
+        \end{itemize}
+    \end{itemize}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.3\textwidth}
+    \begin{itemize}
+      \item
+        nach Binär:
+        \begin{itemize}
+          \item[(g)]
+            750$_8$
+          \item[(h)]
+            42$_{10}$
+          \item[(i)]
+            AFFE$_{16}$
+        \end{itemize}
+    \end{itemize}
+  \end{minipage}
+  
+  \medskip
+
+  Berechnen Sie ohne Hilfsmittel:
+  \begin{itemize}
+    \item[(j)]
+      750$_8$ \& 666$_8$
+    \item[(k)]
+      A380$_{16}$ + B747$_{16}$
+    \item[(l)]
+      AFFE$_{16} >> 1$
+  \end{itemize}
+
+  Die tiefgestellte Zahl steht für die Basis des Zahlensystems.
+  Jede Teilaufgabe zählt 1 Punkt. \addtocounter{points}{12}
+
+  (In der Klausur sind Hilfsmittel zugelassen,
+  daher ist dies \emph{keine\/} typische Klausuraufgabe.)
+
+  \solution
+
+  Wandeln Sie ohne Hilfsmittel
+
+  \begin{itemize}
+    \item
+      nach Dezimal:
+      \begin{itemize}
+        \item[(a)]
+          $0010\,0000_2 = 32_{10}$
+
+          Eine Eins mit fünf Nullen dahinter steht binär für $2^5 = 32$:\\
+          mit $1$ anfangen und fünfmal verdoppeln.
+        \item[(b)]
+          $42_{16} = 4 \cdot 16 + 2 \cdot 1 = 64 + 2 = 66$
+        \item[(c)]
+          $17_8 = 1 \cdot 8 + 7 \cdot 1 = 8 + 7 = 15$
+      \end{itemize}
+      Umwandlung von und nach Dezimal ist immer rechenaufwendig.
+      Umwandlungen zwischen Binär, Oktal und Hexadezimal gehen ziffernweise
+      und sind daher wesentlich einfacher.
+    \item
+      nach Hexadezimal:
+      \begin{itemize}
+        \item[(d)]
+          $0010\,0000_2 = 20_{16}$
+
+          Umwandlung von Binär nach Hexadezimal geht ziffernweise:\\
+          Vier Binärziffern werden zu einer Hex-Ziffer.
+        \item[(e)]
+          $\rm 42_{10} = 32_{10} + 10_{10} = 20_{16} + A_{16} = 2A_{16}$
+        \item[(f)]
+          $\rm 192.168.20.254_{256} = C0\,A8\,14\,FE_{16}$
+
+          Umwandlung von der Basis 256 nach Hexadezimal geht ziffernweise:\\
+          Eine 256er-Ziffer wird zu zwei Hex-Ziffern.
+
+          Da die 256er-Ziffern dezimal angegeben sind,
+          müssen wir viermal Dezimal nach Hexadezimal umwandeln.
+          Hierfür bieten sich unterschiedliche Wege an.
+
+          $\rm 192_{10} = 128_{10} + 64_{10} = 1100\,0000_{2} = C0_{16}$
+
+          $\rm 168_{10} = 10_{10} \cdot 16_{10} + 8_{10} = A_{16} \cdot 10_{16} + 8_{16} = A8_{16}$
+
+          $20_{10} = 16_{10} + 4_{10} = 10_{16} + 4_{16} = 14$
+          
+          $\rm 254_{10} = 255_{10} - 1_{10} = FF_{16} - 1_{16} = FE_{16}$
+      \end{itemize}
+    \item
+      nach Binär:
+      \begin{itemize}
+        \item[(g)]
+          $750_8 = 111\,101\,000_2$
+
+          Umwandlung von Oktal nach Binär geht ziffernweise:\\
+          Eine Oktalziffer wird zu drei Binärziffern.
+        \item[(h)]
+          $\rm 42_{10} = 2A_{16}$ (siehe oben) $= 0010\,1010_{16}$
+
+          Umwandlung von Hexadezimal nach Binär geht ziffernweise:\\
+          Eine Hex-Ziffer wird zu vier Binärziffern.
+        \item[(i)]
+          $\rm AFFE_{16} = 1010\,1111\,1111\,1110_2$
+
+          Umwandlung von Hexadezimal nach Binär geht ziffernweise:\\
+          Eine Hex-Ziffer wird zu vier Binärziffern.
+      \end{itemize}
+  \end{itemize}
+  
+  \medskip
+
+  Berechnen Sie ohne Hilfsmittel:
+  \begin{itemize}
+    \item[(j)]
+      $750_8\,\&\,666_8
+      = 111\,101\,000_2\,\&\,110\,110\,110_2
+      = 110\,100\,000_2
+      = 640_8$
+
+      Binäre Und-Operationen lassen sich am leichtesten
+      in binärer Schreibweise durchführen.
+      Umwandlung zwischen Oktal und Binär geht ziffernweise:
+      Eine Oktalziffer wird zu drei Binärziffern und umgekehrt.
+
+      Mit etwas Übung funktionieren diese Operationen
+      auch direkt mit Oktalzahlen im Kopf.
+
+    \item[(k)]
+      $\rm\phantom{+}A380_{16}$\\
+      $\rm+\kern2ptB747_{16}$\\[-\medskipamount]
+      \rule{1.4cm}{0.5pt}\\
+      $\rm 15AC7_{16}$
+      \begin{picture}(0,0)
+        \put(-1.4,0.35){\mbox{\scriptsize\bf 1}}
+      \end{picture}
+
+      Mit Hexadezimalzahlen (und Binär- und Oktal- und sonstigen Zahlen)
+      kann man genau wie mit Dezimalzahlen schriftlich rechnen.
+      Man muß nur daran denken, daß der "`Zehner"'-Überlauf nicht bei
+      $10_{10}$ stattfindet, sondern erst bei $10_{16} = 16_{10}$
+      (hier: $\rm 8_{16} + 4_{16} = C_{16}$ und
+      $\rm 3_{16} + 7_{16} = A_{16}$, aber
+      $\rm A_{16} + B_{16} = 10_{10} + 11_{10}
+      = 21_{10} = 16_{10} + 5_{10} = 10_{16} + 5_{16} =  15_{16}$).
+
+    \item[(l)]
+      $\rm AFFE_{16} >> 1
+      = 1010\,1111\,1111\,1110_2 >> 1
+      = 0101\,0111\,1111\,1111_2
+      = 57FF_{16}$
+
+      Bit-Verschiebungen lassen sich am leichtesten
+      in binärer Schreibweise durchführen.
+      Umwandlung zwischen Hexadezimal und Binär geht ziffernweise:
+      Eine Hex-Ziffer wird zu vier Binärziffern und umgekehrt.
+
+      Mit etwas Übung funktionieren diese Operationen
+      auch direkt mit Hexadezimalzahlen im Kopf.
+
+  \end{itemize}
+
+  \exercise{Ausgabe von Hexadezimalzahlen}
+
+  Schreiben Sie eine Funktion \lstinline{void print_hex (uint32_t x)},
+  die eine gegebene vorzeichenlose 32-Bit-Ganzzahl \lstinline{x}
+  als Hexadezimalzahl ausgibt.
+  (Der Datentyp \lstinline{uint32_t} ist mit \lstinline{#include <stdint.h>} verfügbar.)
+
+  Verwenden Sie dafür \emph{nicht\/} \lstinline{printf()} mit
+  der Formatspezifikation \lstinline{%x} als fertige Lösung,
+  sondern programmieren Sie die nötige Ausgabe selbst.
+  (Für Tests ist \lstinline{%x} hingegen erlaubt und sicherlich nützlich.)
+
+  Die Verwendung von \lstinline{printf()}
+  mit anderen Formatspezifikationen wie z.\,B.\ \lstinline{%d}
+  oder \lstinline{%c} oder \lstinline{%s} ist hingegen zulässig.
+
+  \points{8}
+
+  (Hinweis für die Klausur: Abgabe auf Datenträger ist erlaubt und erwünscht,
+  aber nicht zwingend.)
+
+  \solution
+
+  Um die Ziffern von \lstinline{x} zur Basis 16 zu isolieren,
+  berechnen wir \lstinline{x % 16} (modulo 16 = Rest bei Division durch 16)
+  und dividieren anschließend \lstinline{x} durch 16,
+  solange bis \lstinline{x} den Wert 0 erreicht.
+
+  Wenn wir die auf diese Weise ermittelten Ziffern direkt ausgeben,
+  sind sie \emph{Little-Endian}, erscheinen also in umgekehrter Reihenfolge.
+  Die Datei \gitfile{hp}{2023ws/20231102}{loesung-2-1.c} setzt diesen Zwischenschritt um.
+
+  Die Ausgabe der Ziffern erfolgt in \gitfile{hp}{2023ws/20231102}{loesung-2-1.c}
+  über \lstinline{printf ("%d")}
+  für die Ziffern 0 bis 9. Für die darüberliegenden Ziffern
+  wird der Buchstabe \lstinline{a} um die Ziffer abzüglich 10 inkrementiert
+  und der erhaltene Wert mit \lstinline{printf ("%c")} als Zeichen ausgegeben.
+
+  Um die umgekehrte Reihenfolge zu beheben,
+  speichern wir die Ziffern von \lstinline{x}
+  in einem Array \lstinline{digits[]} zwischen
+  und geben sie anschließend in einer zweiten Schleife
+  in umgekehrter Reihenfolge aus (siehe \gitfile{hp}{2023ws/20231102}{loesung-2-2.c}).
+  Da wir wissen, daß \lstinline{x} eine 32-Bit-Zahl ist
+  und daher höchstens 8 Hexadezimalziffern haben kann,
+  ist 8 eine sinnvolle Länge für das Ziffern-Array \lstinline{digits[8]}.
+
+  Nun sind die Ziffern in der richtigen Reihenfolge,
+  aber wir erhalten zusätzlich zu den eigentlichen Ziffern führende Nullen.
+  Da in der Aufgabenstellung nicht von führenden Nullen die Rede war,
+  sind diese nicht verboten; \gitfile{hp}{2023ws/20231102}{loesung-2-2.c} ist daher
+  eine richtige Lösung der Aufgabe.
+
+  \breath
+
+  Wenn wir die führenden Nullen vermeiden wollen,
+  können wir die \lstinline{for}-Schleifen durch \lstinline{while}-Schleifen ersetzen.
+  Die erste Schleife zählt hoch, solange \lstinline{x} ungleich 0 ist;
+  die zweite zählt von dem erreichten Wert aus wieder herunter
+  -- siehe \gitfile{hp}{2023ws/20231102}{loesung-2-3.c}.
+  Da wir wissen, daß die Zahl \lstinline{x} höchstens 32 Bit,
+  also höchstens 8 Hexadezimalziffern hat,
+  wissen wir, daß \lstinline{i} höchstens den Wert 8 erreichen kann,
+  das Array also nicht überlaufen wird.
+
+  Man beachte, daß der Array-Index nach der ersten Schleife "`um einen zu hoch"' ist.
+  In der zweiten Schleife muß daher \emph{zuerst\/} der Index dekrementiert werden.
+  Erst danach darf ein Zugriff auf \lstinline{digit[i]} erfolgen.
+
+  \breath
+
+  Alternativ können wir auch mitschreiben,
+  ob bereits eine Ziffer ungleich Null ausgegeben wurde,
+  und andernfalls die Ausgabe von Null-Ziffern unterdrücken
+  -- siehe \gitfile{hp}{2023ws/20231102}{loesung-2-4.c}.
+
+  \breath
+
+  Weitere Möglichkeiten ergeben sich, wenn man bedenkt,
+  daß eine Hexadezimalziffer genau einer Gruppe von vier Binärziffern entspricht.
+  Eine Bitverschiebung um 4 nach rechts
+  ist daher dasselbe wie eine Division durch 16,
+  und eine Und-Verknüpfung mit 15$_{10}$ = f$_{16}$ = 1111$_2$
+  ist dasselbe wie die Operation Modulo 16.
+  Die Datei \gitfile{hp}{2023ws/20231102}{loesung-2-5.c} ist eine in dieser Weise abgewandelte Variante
+  von \gitfile{hp}{2023ws/20231102}{loesung-2-3.c}.
+
+  Mit dieser Methode kann man nicht nur auf die jeweils unterste Ziffer,
+  sondern auf alle Ziffern direkt zugreifen.
+  Damit ist kein Array als zusätzlicher Speicher mehr nötig.
+  Die Datei \gitfile{hp}{2023ws/20231102}{loesung-2-6.c} setzt dies auf einfache Weise um.
+  Sie gibt wieder führende Nullen mit aus,
+  ist aber trotzdem eine weitere richtige Lösung der Aufgabe.
+
+  Die führenden Nullen ließen sich auf die gleiche Weise vermeiden
+  wie in \gitfile{hp}{2023ws/20231102}{loesung-2-4.c}.
+
+  Die Bitverschiebungsmethode hat den Vorteil,
+  daß kein zusätzliches Array benötigt wird.
+  Auch wird die als Parameter übergebene Zahl \lstinline{x} nicht verändert,
+  was bei größeren Zahlen, die über Zeiger übergeben werden, von Vorteil sein kann.
+  Demgegenüber steht der Nachteil,
+  daß diese Methode nur für eine ganze Anzahl von Bits funktioniert,
+  also für Basen, die Zweierpotenzen sind (z.\,B.\ 2, 8, 16, 256).
+  Für alle anderen Basen (z.\,B.\ 10) eignet sich nur die Methode
+  mit Division und Modulo-Operation.
+
+  \exercise{Einfügen in Strings}
+
+  Wir betrachten das folgende Programm (\gitfile{hp}{2023ws/20231102}{aufgabe-3.c}):
+%  \begin{lstlisting}[style=numbered]
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    void insert_into_string (char src, char *target, int pos)
+    {
+      int len = strlen (target);
+      for (int i = pos; i < len; i++)
+        target[i+1] = target[i];
+      target[pos] = src;
+    }
+
+    int main (void)
+    {
+      char test[100] = "Hochshule Bochum";
+      insert_into_string ('c', test, 5);
+      printf ("%s\n", test);
+      return 0;
+    }
+  \end{lstlisting}
+  Die Ausgabe des Programms lautet:
+  \lstinline[style=terminal]{Hochschhhhhhhhhhh}
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Erklären Sie, wie die Ausgabe zustandekommt.
+      \points{3}
+%      \workspace{12}
+    \item
+      Schreiben Sie die Funktion \lstinline|insert_into_string()| so um,
+      daß sie den Buchstaben \lstinline{src} an der Stelle \lstinline{pos}
+      in den String \lstinline{target} einfügt.\par
+      Die Ausgabe des Programms müßte dann
+      \lstinline[style=terminal]{Hochschule Bochum} lauten.
+      \points{2}
+%      \workspace{13}
+    \item
+      Was kann passieren, wenn Sie die Zeile
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char test[] = "Hochshule Bochum";} ersetzen?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+%      \workspace{10}
+    \item
+      Was kann passieren, wenn Sie die Zeile
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char *test = "Hochshule Bochum";} ersetzen?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+%      \workspace{10}
+%    \item
+%      Schreiben Sie eine Funktion
+%      \lstinline{void insert_into_string_sorted (char src, char *target)},
+%      die voraussetzt, daß der String \lstinline{target} alphabetisch sortiert ist
+%      und den Buchstaben \lstinline{src} an der alphabetisch richtigen Stelle
+%      einfügt. Diese Funktion darf die bereits vorhandene Funktion
+%      \lstinline|insert_into_string()| aufrufen.\\
+%      \points{4}\par
+%      Zum Testen eignen sich die folgenden Zeilen im Hauptprogramm:
+%      \begin{lstlisting}[gobble=8]
+%        char test[100] = "";
+%        insert_into_string_sorted ('c', test);
+%        insert_into_string_sorted ('a', test);
+%        insert_into_string_sorted ('d', test);
+%        insert_into_string_sorted ('b', test);
+%      \end{lstlisting}
+%      Danach sollte \lstinline{test[]} die Zeichenfolge \lstinline{"abcd"} enthalten.
+%      \workspace{14}
+%    \item
+%      Wie schnell (Landau-Symbol in Abhängigkeit von der Länge $n$ des Strings)
+%      arbeitet Ihre Funktion
+%      \lstinline{void insert_into_string_sorted (char src, char *target)}
+%      und warum?
+%      \points{1}
+%      \workspace{10}
+%    \item
+%      Beschreiben Sie -- in Worten oder als C-Quelltext --, wie man die Funktion\\
+%      \lstinline{void insert_into_string_sorted (char src, char *target)}
+%      so gestalten kann,\\
+%      daß sie in $\mathcal{O}(\log n)$ arbeitet.
+%      \points{3}
+%      \workspace{35}
+  \end{enumerate}
+
+  \solution
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      \textbf{Erklären Sie, wie die Ausgabe zustandekommt.}
+
+      In der Schleife wird \emph{zuerst\/} der nächste Buchstabe \lstinline{target[i + 1]}
+      gleich dem aktuellen gesetzt
+      und \emph{danach\/} der Zähler \lstinline{i} erhöht.
+      Dadurch wird im nächsten Schleifendurchlauf der bereits verschobene Buchstabe
+      noch weiter geschoben und letztlich alle Buchstaben in \lstinline{target[]}
+      durch den an der Stelle \lstinline{pos} ersetzt.
+
+    \item
+      \textbf{Schreiben Sie die Funktion \lstinline|insert_into_string()| so um,
+      daß sie den Buchstben \lstinline{src} an der Stelle \lstinline{pos}
+      in den String \lstinline{target} einfügt.}\par
+      \textbf{Die Ausgabe des Programms müßte dann
+      \lstinline[style=terminal]{Hochschule Bochum} lauten.}
+
+      Um im String "`Platz zu schaffen"', muß man von hinten beginnen,
+      also die Schleife umdrehen\\
+      (siehe: \gitfile{hp}{2023ws/20231102}{loesung-3.c}):
+      \begin{lstlisting}{gobble=8}
+        for (int i = len; i >= pos; i--)
+          target[i + 1] = target[i];
+      \end{lstlisting}
+
+    \item
+      \textbf{Was kann passieren, wenn Sie die Zeile
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char test[] = "Hochshule Bochum";}
+      ersetzen und warum?}
+
+      Die Schreibweise \lstinline{test[]} bedeutet,
+      daß der Compiler selbst zählt, wieviel Speicherplatz der String benötigt,
+      un dann genau die richtige Menge Speicher reserviert
+      (anstatt, wie wir es manuell getan haben, pauschal Platz für 100 Zeichen).
+
+      Wenn wir nun in den String ein zusätzliches Zeichen einfügen,
+      ist dafür kein Speicherplatz reserviert worden,
+      und wir \textbf{überschreiben} dann Speicher, an dem sich andere Variable befinden,
+      was zu einem \textbf{Absturz} führen kann.
+
+      Da wir hier nur ein einziges Zeichen schreiben,
+      wird dieser Fehler nicht sofort auffallen.
+      Dies ist schlimmer, als wenn das Programm direkt beim ersten Test abstürzt,
+      denn dadurch entsteht bei uns der Eindruck, es sei in Ordnung.
+      Wenn danach der Fehler in einer Produktivumgebung auftritt,
+      kann dadurch Schaden entstehen -- je nach Einsatzgebiet der Software
+      u.\,U.\ erheblicher Vermögens-, Sach- und/oder Personenschaden
+      (z.\,B.\ Absturz eines Raumflugkörpers).
+
+    \item
+      \textbf{Was kann passieren, wenn Sie 
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char *test = "Hochshule Bochum";}
+      ersetzen und warum?}
+
+      In diesem Fall wird der Speicher für den eigentlichen String
+      in einem unbenannten, \textbf{nicht schreibbaren} Teil des Speichers reserviert.
+      Unser Versuch, dorthin ein zusätzliches Zeichen zu schreiben,
+      fürt dann normalerweise zu einem \textbf{Absturz}.
+
+      In manchen Systemen (Betriebssystem, Compiler, \dots)
+      ist der Speicherbereich tatsächlich sehr wohl schreibbar.
+      In diesem Fall tritt der Absturz nicht immer und nicht immer sofort auf --
+      genau wie in Aufgabenteil (c).
+     
+  \end{enumerate}
+
+\end{document}
diff --git a/20231102/hp-uebung-20231102.pdf b/20231102/hp-uebung-20231102.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..4448879c71b160a6acd1b949647b573112303358
Binary files /dev/null and b/20231102/hp-uebung-20231102.pdf differ
diff --git a/20231102/hp-uebung-20231102.tex b/20231102/hp-uebung-20231102.tex
new file mode 100644
index 0000000000000000000000000000000000000000..803fb4a2ed25eb774af13333daa50f7ce56e8afb
--- /dev/null
+++ b/20231102/hp-uebung-20231102.tex
@@ -0,0 +1,227 @@
+% hp-uebung-20231102.pdf - Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023  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: Zahlensysteme, Ausgabe von Hexadezimalzahlen, Einfügen in Strings
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+
+\begin{document}
+
+  \thispagestyle{empty}
+
+  \section*{Hardwarenahe Programmierung\\
+            Übungsaufgaben -- 2.\ November 2023}
+
+  Diese Übung enthält Punkteangaben wie in einer Klausur.
+  Um zu "`bestehen"', müssen Sie innerhalb von 80 Minuten
+  unter Verwendung ausschließlich zugelassener Hilfsmittel
+  14 Punkte (von insgesamt \totalpoints) erreichen.
+
+  \exercise{Zahlensysteme}
+
+  Wandeln Sie ohne Hilfsmittel
+
+  \begin{minipage}[t]{0.3\textwidth}
+    \begin{itemize}
+      \item
+        nach Dezimal:
+        \begin{itemize}
+          \item[(a)]
+            0010\,0000$_2$
+          \item[(b)]
+            42$_{16}$
+          \item[(c)]
+            17$_8$
+        \end{itemize}
+    \end{itemize}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.3\textwidth}
+    \begin{itemize}
+      \item
+        nach Hexadezimal:
+        \begin{itemize}
+          \item[(d)]
+            0010\,0000$_2$
+          \item[(e)]
+            42$_{10}$
+          \item[(f)]
+            192.168.20.254$_{256}$
+        \end{itemize}
+    \end{itemize}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.3\textwidth}
+    \begin{itemize}
+      \item
+        nach Binär:
+        \begin{itemize}
+          \item[(g)]
+            750$_8$
+          \item[(h)]
+            42$_{10}$
+          \item[(i)]
+            AFFE$_{16}$
+        \end{itemize}
+    \end{itemize}
+  \end{minipage}
+  
+  \medskip
+
+  Berechnen Sie ohne Hilfsmittel:
+  \begin{itemize}
+    \item[(j)]
+      750$_8$ \& 666$_8$
+    \item[(k)]
+      A380$_{16}$ + B747$_{16}$
+    \item[(l)]
+      AFFE$_{16} >> 1$
+  \end{itemize}
+
+  Die tiefgestellte Zahl steht für die Basis des Zahlensystems.
+  Jede Teilaufgabe zählt 1 Punkt. \addtocounter{points}{12}
+
+  (In der Klausur sind Hilfsmittel zugelassen,
+  daher ist dies \emph{keine\/} typische Klausuraufgabe.)
+
+  \exercise{Ausgabe von Hexadezimalzahlen}
+
+  Schreiben Sie eine Funktion \lstinline{void print_hex (uint32_t x)},
+  die eine gegebene vorzeichenlose 32-Bit-Ganzzahl \lstinline{x}
+  als Hexadezimalzahl ausgibt.
+  (Der Datentyp \lstinline{uint32_t} ist mit \lstinline{#include <stdint.h>} verfügbar.)
+
+  Verwenden Sie dafür \emph{nicht\/} \lstinline{printf()} mit
+  der Formatspezifikation \lstinline{%x} als fertige Lösung,
+  sondern programmieren Sie die nötige Ausgabe selbst.
+  (Für Tests ist \lstinline{%x} hingegen erlaubt und sicherlich nützlich.)
+
+  Die Verwendung von \lstinline{printf()}
+  mit anderen Formatspezifikationen wie z.\,B.\ \lstinline{%d}
+  oder \lstinline{%c} oder \lstinline{%s} ist hingegen zulässig.
+
+  \points{8}
+
+  (Hinweis für die Klausur: Abgabe auf Datenträger ist erlaubt und erwünscht,
+  aber nicht zwingend.)
+
+  \clearpage
+
+  \exercise{Einfügen in Strings}
+
+  Wir betrachten das folgende Programm (\gitfile{hp}{2023ws/20231102}{aufgabe-3.c}):
+%  \begin{lstlisting}[style=numbered]
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    void insert_into_string (char src, char *target, int pos)
+    {
+      int len = strlen (target);
+      for (int i = pos; i < len; i++)
+        target[i+1] = target[i];
+      target[pos] = src;
+    }
+
+    int main (void)
+    {
+      char test[100] = "Hochshule Bochum";
+      insert_into_string ('c', test, 5);
+      printf ("%s\n", test);
+      return 0;
+    }
+  \end{lstlisting}
+  Die Ausgabe des Programms lautet:
+  \lstinline[style=terminal]{Hochschhhhhhhhhhh}
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Erklären Sie, wie die Ausgabe zustandekommt.
+      \points{3}
+%      \workspace{12}
+    \item
+      Schreiben Sie die Funktion \lstinline|insert_into_string()| so um,
+      daß sie den Buchstaben \lstinline{src} an der Stelle \lstinline{pos}
+      in den String \lstinline{target} einfügt.\par
+      Die Ausgabe des Programms müßte dann
+      \lstinline[style=terminal]{Hochschule Bochum} lauten.
+      \points{2}
+%      \workspace{13}
+    \item
+      Was kann passieren, wenn Sie die Zeile
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char test[] = "Hochshule Bochum";} ersetzen?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+%      \workspace{10}
+    \item
+      Was kann passieren, wenn Sie die Zeile
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char *test = "Hochshule Bochum";} ersetzen?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+%      \workspace{10}
+%    \item
+%      Schreiben Sie eine Funktion
+%      \lstinline{void insert_into_string_sorted (char src, char *target)},
+%      die voraussetzt, daß der String \lstinline{target} alphabetisch sortiert ist
+%      und den Buchstaben \lstinline{src} an der alphabetisch richtigen Stelle
+%      einfügt. Diese Funktion darf die bereits vorhandene Funktion
+%      \lstinline|insert_into_string()| aufrufen.\\
+%      \points{4}\par
+%      Zum Testen eignen sich die folgenden Zeilen im Hauptprogramm:
+%      \begin{lstlisting}[gobble=8]
+%        char test[100] = "";
+%        insert_into_string_sorted ('c', test);
+%        insert_into_string_sorted ('a', test);
+%        insert_into_string_sorted ('d', test);
+%        insert_into_string_sorted ('b', test);
+%      \end{lstlisting}
+%      Danach sollte \lstinline{test[]} die Zeichenfolge \lstinline{"abcd"} enthalten.
+%      \workspace{14}
+%    \item
+%      Wie schnell (Landau-Symbol in Abhängigkeit von der Länge $n$ des Strings)
+%      arbeitet Ihre Funktion
+%      \lstinline{void insert_into_string_sorted (char src, char *target)}
+%      und warum?
+%      \points{1}
+%      \workspace{10}
+%    \item
+%      Beschreiben Sie -- in Worten oder als C-Quelltext --, wie man die Funktion\\
+%      \lstinline{void insert_into_string_sorted (char src, char *target)}
+%      so gestalten kann,\\
+%      daß sie in $\mathcal{O}(\log n)$ arbeitet.
+%      \points{3}
+%      \workspace{35}
+  \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/20231102/loesung-2-1.c b/20231102/loesung-2-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..98b2f03f19d21aa2a794fef1f3f98feff95f5142
--- /dev/null
+++ b/20231102/loesung-2-1.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  while (x)
+    {
+      int digit = x % 16;
+      if (digit < 10)
+        printf ("%d", digit);
+      else
+        printf ("%c", 'a' + digit - 10);
+      x /= 16;
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20231102/loesung-2-2.c b/20231102/loesung-2-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..35aa3b3aea6fc8faaa55c7d5382f0a8de9282aee
--- /dev/null
+++ b/20231102/loesung-2-2.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  char digit[8];
+  for (int i = 0; i < 8; i++)
+    {
+      digit[i] = x % 16;
+      x /= 16;
+    }
+  for (int i = 7; i >= 0; i--)
+    {
+      if (digit[i] < 10)
+        printf ("%d", digit[i]);
+      else
+        printf ("%c", 'a' + digit[i] - 10);
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20231102/loesung-2-3.c b/20231102/loesung-2-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..2462f2b537896722d8d1774a5d47f374ee5ef7fa
--- /dev/null
+++ b/20231102/loesung-2-3.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  char digit[8];
+  int i = 0;
+  while (x)
+    {
+      digit[i] = x % 16;
+      x /= 16;
+      i++;
+    }
+  while (i > 0)
+    {
+      i--;
+      if (digit[i] < 10)
+        printf ("%d", digit[i]);
+      else
+        printf ("%c", 'a' + digit[i] - 10);
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20231102/loesung-2-4.c b/20231102/loesung-2-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..5083dcb865c86beafd43ce3e8837510b13cbe850
--- /dev/null
+++ b/20231102/loesung-2-4.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  char digit[8];
+  for (int i = 0; i < 8; i++)
+    {
+      digit[i] = x % 16;
+      x /= 16;
+    }
+  int printing = 0;
+  for (int i = 7; i >= 0; i--)
+    {
+      if (printing || digit[i] != 0)
+        {
+          printing = 1;
+          if (digit[i] < 10)
+            printf ("%d", digit[i]);
+          else
+            printf ("%c", 'a' + digit[i] - 10);
+        }
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20231102/loesung-2-5.c b/20231102/loesung-2-5.c
new file mode 100644
index 0000000000000000000000000000000000000000..e3446edb4a40348ac14da420f344c208f8916f7e
--- /dev/null
+++ b/20231102/loesung-2-5.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  char digit[8];
+  int i = 0;
+  while (x)
+    {
+      digit[i] = x & 0x0000000f;
+      x >>= 4;
+      i++;
+    }
+  while (i > 0)
+    {
+      i--;
+      if (digit[i] < 10)
+        printf ("%d", digit[i]);
+      else
+        printf ("%c", 'a' + digit[i] - 10);
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20231102/loesung-2-6.c b/20231102/loesung-2-6.c
new file mode 100644
index 0000000000000000000000000000000000000000..7b8e8e1a9d7285b8a1e02ff1a91310f1dc02ed5b
--- /dev/null
+++ b/20231102/loesung-2-6.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  int i = 32;
+  while (i > 0)
+    {
+      i -= 4;
+      int digit = (x >> i) & 0x0000000f;
+      if (digit < 10)
+        printf ("%d", digit);
+      else
+        printf ("%c", 'a' + digit - 10);
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20231102/loesung-3.c b/20231102/loesung-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..85abfcf3e1e4bacf454acd10f6832b757a64ac35
--- /dev/null
+++ b/20231102/loesung-3.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <string.h>
+
+void insert_into_string (char src, char *target, int pos)
+{
+  int len = strlen (target);
+  for (int i = len; i >= pos; i--)
+    target[i + 1] = target[i];
+  target[pos] = src;
+}
+
+int main (void)
+{
+  char test[100] = "Hochshule Bochum";
+  insert_into_string ('c', test, 5);
+  printf ("%s\n", test);
+  return 0;
+}
diff --git a/20231102/logo-hochschule-bochum-cvh-text-v2.pdf b/20231102/logo-hochschule-bochum-cvh-text-v2.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8
--- /dev/null
+++ b/20231102/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/20231102/logo-hochschule-bochum.pdf b/20231102/logo-hochschule-bochum.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1
--- /dev/null
+++ b/20231102/logo-hochschule-bochum.pdf
@@ -0,0 +1 @@
+../common/logo-hochschule-bochum.pdf
\ No newline at end of file
diff --git a/20231102/pgscript.sty b/20231102/pgscript.sty
new file mode 120000
index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b
--- /dev/null
+++ b/20231102/pgscript.sty
@@ -0,0 +1 @@
+../common/pgscript.sty
\ No newline at end of file
diff --git a/20231102/pgslides.sty b/20231102/pgslides.sty
new file mode 120000
index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64
--- /dev/null
+++ b/20231102/pgslides.sty
@@ -0,0 +1 @@
+../common/pgslides.sty
\ No newline at end of file