Skip to content
Snippets Groups Projects
Select Git revision
  • f43d22d73633802f95a8845b3f33881ac81f5d8e
  • 2024ws default
  • 2023ws
  • 2022ws
  • 2021ws
  • 2020ws
  • 2018ws
  • 2019ws
  • 2017ws
  • 2016ws
10 results

hp-20211115.tex

Blame
  • hp-20211115.tex 24.73 KiB
    % hp-20211115.pdf - Lecture Slides on Low-Level Programming
    % Copyright (C) 2012, 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021  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: I/O-Ports
    
    \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{15.\ November 2021}
    
    \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}}}
        \item[\textbf{2}] \textbf{Einführung in C}
          \begin{itemize}
            \vspace*{-\smallskipamount}
            \item[\dots]
            \item[2.12] Strukturen
            \item[2.13] Dateien und Fehlerbehandlung
            \color{medgreen}
            \item[2.14] Parameter des Hauptprogramms
            \item[2.15] String-Operationen
          \end{itemize}
        \item[\textbf{3}] \textbf{Bibliotheken}
        \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
          \begin{itemize}
            \color{medgreen}
            \item[4.1] Bit-Operationen
            \color{orange}
            \item[4.2] I/O-Ports
            \color{black}
            \item[4.3] Interrupts
            \vspace*{-0.1cm}
            \item[\dots]
          \end{itemize}
        \item[\textbf{5}] \textbf{Algorithmen}
        \vspace*{-\smallskipamount}
        \item[\textbf{\dots}]
      \end{itemize}
    
    \end{frame}
    
    \setcounter{section}{1}
    \section{Einführung in C}
    \setcounter{subsection}{13}
    \subsection{Parameter des Hauptprogramms}
    
    \begin{frame}[fragile]
    
      \showsubsection
    
      \vspace*{-\bigskipamount}
    
      \begin{lstlisting}
        #include <stdio.h>
    
        int main (int argc, char **argv)
        {
          printf ("argc = %d\n", argc);
          for (int i = 0; i < argc; i++)
            printf ("argv[%d] = \"%s\"\n", i, argv[i]);
          return 0;
        }
      \end{lstlisting}
    
    \end{frame}
    
    \begin{frame}[fragile]
    
      \showsubsection
    
      \vspace*{-\bigskipamount}
    
      \begin{lstlisting}
        #include <stdio.h>
    
        int main (int argc, char **argv)
        {
          printf ("argc = %d\n", argc);
          for (int i = 0; *argv; i++, argv++)
            printf ("argv[%d] = \"%s\"\n", i, *argv);
          return 0;
        }
      \end{lstlisting}
    
    \end{frame}
    
    \subsection{String-Operationen}
    
    \begin{frame}[fragile]
    
      \showsubsection
    
      \vspace*{-\bigskipamount}
    
      \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*{-\bigskipamount}
    
      \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}
    
    \end{frame}
    
    \begin{frame}[fragile]
    
      \showsubsection
    
      \vspace*{-\bigskipamount}
    
      \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}
    
    \end{frame}
    
    \begin{frame}[fragile]
    
      \showsubsection
    
      \vspace*{-\bigskipamount}
    
      \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}
    
    \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}
            \color{medgreen}
            \item[4.1] Bit-Operationen
            \color{orange}
            \item[4.2] I/O-Ports
            \color{black}
            \item[4.3] Interrupts
            \item[4.4] 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}
        \item[\textbf{\dots}]
    %    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
    %    \item[\textbf{5}] \textbf{Algorithmen}
    %    \item[\textbf{6}] \textbf{Ergänzungen und Ausblicke}
      \end{itemize}
      \vspace*{-1cm}
    
    \end{frame}
    
    \setcounter{section}{4}
    \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}
    
    \subsection{I/O-Ports}
    
    \begin{frame}[fragile]
    
    %  \showsection
      \showsubsection
      \vspace*{-1.5\medskipamount}
      {\large\textbf{\color{structure}5.3\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}
    
    \iffalse
    
    \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}
    
    \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}
    
    \iffalse
    
    \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}
    
    \fi
    
    \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}{} & \pause für Menschen leichter lesbar \pause \\
        \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}{} & \pause 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
      \medskip
      Little-Endian:
    
      \smallskip
    
      \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
      \medskip
      Big-Endian:
    
      \smallskip
    
      \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}
    
      \vspace*{-1cm}
    
    \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}
    
    \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*{-\smallskipamount}
            \item[\dots]
            \item[2.14] Parameter des Hauptprogramms
            \item[2.15] String-Operationen
          \end{itemize}
        \item[\textbf{3}] \textbf{Bibliotheken}
        \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
          \begin{itemize}
            \item[4.1] Bit-Operationen
            \color{medgreen}
            \item[4.2] I/O-Ports
            \color{red}
            \item[4.3] Interrupts
            \item[4.4] 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}
        \item[\textbf{\dots}]
      \end{itemize}
    
    \end{frame}
    
    \end{document}