diff --git a/20181119/hp-musterloesung-20181119.pdf b/20181119/hp-musterloesung-20181119.pdf new file mode 100644 index 0000000000000000000000000000000000000000..84aa7860ad17a31227ae228b2413c74985f57ae6 Binary files /dev/null and b/20181119/hp-musterloesung-20181119.pdf differ diff --git a/20181119/hp-musterloesung-20181119.tex b/20181119/hp-musterloesung-20181119.tex new file mode 100644 index 0000000000000000000000000000000000000000..4e44498e8dd279111dfb34bfeb949e9753e03eb3 --- /dev/null +++ b/20181119/hp-musterloesung-20181119.tex @@ -0,0 +1,329 @@ +% hp-musterloesung-20181112.pdf - Solutions to the 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: Arrays mit Zahlen, hüpfender Ball + +\documentclass[a4paper]{article} + +\usepackage{pgscript} +\usepackage{gnuplot-lua-tikz} + +\begin{document} + + \section*{Hardwarenahe Programmierung\\ + Musterlösung zu den Übungsaufgaben -- 19.\ November 2018} + + \exercise{Arrays mit Zahlen} + + \begin{minipage}[t]{0.5\textwidth} + Wir betrachten das folgende Programm\\ + (Datei: \gitfile{hp}{20181119}{aufgabe-1.c}): + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + void f (int *s0, int *s1) + { + while (*s0 >= 0) + { + int *s = s1; + while (*s >= 0) + if (*s0 == *s++) + printf ("%d ", *s0); + s0++; + } + printf ("\n"); + } + + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1, -1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10, -1 }; + f (a, b); + return 0; + } + \end{lstlisting} + \end{minipage}\hfill + \begin{minipage}[t]{0.5\textwidth} + \vspace*{-\bigskipamount} + \begin{enumerate}[\quad(a)] + \item + Was bewirkt die Funktion \lstinline{f},\\ + und wie funktioniert sie? + \points{4} +% \item +% Von welcher Ordnung (Landau-Symbol) ist die Funktion und warum? +% +% Wir beziehen uns hierbei auf die Anzahl der Vergleiche +% in Abhängigkeit von der Länge der Eingabedaten \lstinline{s0} und \lstinline{s1}. +% Für die Rechnung dürfen Sie beide Längen mit $n$ gleichsetzen, +% obwohl sie normalerweise nicht gleich sind. +% \points{2} + \item + Was passiert, wenn Sie beim Aufruf der Funktion für einen der + Parameter den Wert \lstinline{NULL} übergeben und warum? + \points{2} + \item + Was kann passieren, wenn Sie das Hauptprogramm wie folgt abändern + (\gitfile{hp}{20181119}{aufgabe-1d.c}) und warum? + \begin{lstlisting}[gobble=8] + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10 }; + f (a, b); + return 0; + } + \end{lstlisting} + \points{2} +% \item +% Beschreiben Sie -- in Worten und/oder als C-Quelltext --, wie +% sich die Funktion \lstinline{f} effizienter gestalten läßt, +% wenn man die ihr übergebenen Arrays \lstinline{s0} und +% \lstinline{s1} als sortiert voraussetzt. +% \points{5} +% +% Hinweis: Wie würden Sie als Mensch die Aufgabe erledigen? +% \item +% Von welcher +% Ordnung (Landau-Symbol) ist Ihre effizientere Version der Funktion und warum? +% \points{2} + \end{enumerate} + \end{minipage} + + \solution + + \begin{enumerate}[\quad(a)] + \item + \textbf{Was bewirkt die Funktion \lstinline{f} und wie funktioniert sie?} + + Die Funktion gibt alle Zahlen aus, die sowohl im Array \lstinline{s0} + als auch im Array \lstinline{s1} vorkommen (Schnittmenge). + + Dies geschieht, indem der Zeiger \lstinline{s0} das gesamte Array durchläuft + (äußere Schleife). + Für jedes Element des ersten Arrays durchläuft der Zeiger \lstinline{s} + das gesamte zweite Array (innere Schleife). + Auf diese Weise wird jedes Element von \lstinline{s0} + mit jedem von \lstinline{s1} verglichen und bei Gleichheit ausgegeben. + + Um die Schleifen abbrechen zu können, enthalten beide Arrays + als Ende-Markierung eine negative Zahl (\lstinline{-1}). + + \item + \textbf{Was passiert, wenn Sie beim Aufruf der Funktion für einen der + Parameter den Wert \lstinline{NULL} übergeben und warum?} + + In dem Moment, wo auf den jeweiligen Parameter-Zeiger zugegriffen wird + (\lstinline{while (*s0 >= 0)} für \lstinline{s0} bzw.\ + \lstinline{int *s = s1; while (*s >= 0)} für \lstinline{s1}), + kommt es zu einem Absturz (Speicherzugriffsfehler). + Die Dereferenzierung eines Zeigers mit dem Wert \lstinline{NULL} + ist nicht zulässig. + + \item + \textbf{Was kann passieren, wenn Sie das Hauptprogramm wie folgt abändern + (\gitfile{hp}{20181119}{aufgabe-1d.c}) und warum?} + + \begin{minipage}{0.35\textwidth} + \begin{lstlisting}[gobble=10] + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10 }; + f (a, b); + return 0; + } + \end{lstlisting} + \end{minipage}\hfill + \begin{minipage}{0.575\textwidth} + Durch die fehlenden Ende-Markierungen der Arrays + laufen die Schleifen immer weiter, + bis sie irgendwann zufällig auf Speicherzellen stoßen, + die sich als Ende-Markierungen interpretieren lassen (negative Zahlen). + Dadurch kann es zu einem Lesezugriff auf Speicher kommen, + für den das Programm kein Lesezugriffsrecht hat, + also zu einem Absturz (Speicherzugriffsfehler). + \end{minipage} + \end{enumerate} + + \exercise{Fehlerhaftes Programm: Hüpfender Ball} + + Das auf der nächsten Seite abgedruckte GTK+-Programm + (Datei: \gitfile{hp}{20181119}{aufgabe-2.c}) soll einen + hüpfenden Ball darstellen, ist jedoch fehlerhaft. + + \begin{enumerate}[\quad(a)] + \item + Warum sieht man lediglich ein leeres Fenster? + Welchen Befehl muß man ergänzen, um diesen Fehler zu beheben? + \points{3} + \item + Nach der Fehlerbehebung in Aufgabenteil (a) + zeigt das Programm einen unbeweglichen Ball. + Welchen Befehl muß man ergänzen, um diesen Fehler zu beheben, und warum? + \points{2} + \item + Erklären Sie das merkwürdige Hüpfverhalten des Balls. + Wie kommt es zustande? + Was an diesem Verhalten ist korrekt, und was ist fehlerhaft? \points{5} + \item + Welche Befehle muß man in welcher Weise ändern, + um ein realistischeres Hüpf-Verhalten zu bekommen? \points{2} + \end{enumerate} + + Hinweis: Das Hinzuziehen von Beispiel-Programmen aus der Vorlesung + ist ausdrücklich erlaubt -- auch in der Klausur. + + Allgemeiner Hinweis: + Wenn Sie die Übungsaufgaben zu dieser Lehrveranstaltung + als PDF-Datei betrachten und darin auf die Dateinamen klicken, + können Sie die Beispiel-Programme direkt herunterladen. + Dadurch vermeiden Sie Übertragungsfehler. + + \solution + + \begin{enumerate}[\quad(a)] + \item + \textbf{Warum sieht man lediglich ein leeres Fenster? + Welchen Befehl muß man ergänzen, um diesen Fehler zu beheben?} + + Die für das Zeichnen zuständige Callback-Funktion wurde zwar geschrieben, + aber nicht installiert. + Um dies zu beheben, ergänze man den folgenden Befehl im Hauptprogramm: + + \lstinline{g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);} + + Dies erkennt man sehr schnell durch Vergleich mit dem Beispiel-Programm + \gitfile{hp}{20181112}{gtk-13.c}. + + \item + \textbf{Nach der Fehlerbehebung in Aufgabenteil (a) + zeigt das Programm einen unbeweglichen Ball. + Welchen Befehl muß man ergänzen, um diesen Fehler zu beheben, und warum?} + + Die Timer-Callback-Funktion wurde zwar geschrieben, aber nicht installiert. + Um dies zu beheben, ergänze man den folgenden Befehl im Hauptprogramm: + + \lstinline{g_timeout_add (50, (GSourceFunc) timer, drawing_area);} + + Auch dies erkennt man sehr schnell durch Vergleich mit dem Beispiel-Programm + \gitfile{hp}{20181112}{gtk-13.c}. + + \item + \textbf{Erklären Sie das merkwürdige Hüpfverhalten des Balls. + Wie kommt es zustande? + Was an diesem Verhalten ist korrekt, und was ist fehlerhaft?} + + Die Geschwindigkeit in $y$-Richtung wächst immer weiter. + Der Grund dafür ist, daß die $y$-Komponente der Geschwindigkeit + nicht auf physikalisch sinnvolle Weise berechnet wird. + In der dafür zuständigen Zeile + \lstinline{vy = 0.5 * g * (t * t);} + wird stattdessen der Weg in $y$-Richtung bei einer gleichmäßig + beschleunigten Bewegung berechnet und als Geschwindigkeit verwendet. + + \item + \textbf{Welche Befehle muß man in welcher Weise ändern, + um ein realistischeres Hüpf-Verhalten zu bekommen?} + + Da der Ball am Boden abprallen soll, ist es \emph{nicht\/} sinnvoll, + die $y$-Komponente der Geschwindigkeit über die bekannte physikalische + Formel $v_y = -g\cdot t$ für die Geschwindigkeit in einer + gleichmäßig beschleunigten Bewegung zu berechnen. + + Stattdessen ist es sinnvoll, die \emph{Geschwindigkeitsänderung\/} + innerhalb des Zeitintervalls \lstinline{dt} + zur Geschwindigkeitskomponente zu addieren: + \lstinline{vy += g * dt;} + + Auch dies erkennt man sehr schnell durch Vergleich mit dem Beispiel-Programm + \gitfile{hp}{20181112}{gtk-13.c}. + \end{enumerate} + + \clearpage + + \vbox to \textheight{\vspace*{-0.5cm}\begin{lstlisting} + #include <gtk/gtk.h> + + #define WIDTH 320 + #define HEIGHT 240 + + double t = 0.0; + double dt = 0.2; + + int r = 5; + + double x = 10; + double y = 200; + double vx = 20; + double vy = -60; + double g = 9.81; + + gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data) + { + GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 }; + + gdk_cairo_set_source_rgba (c, &blue); + cairo_arc (c, x, y, r, 0, 2 * G_PI); + cairo_fill (c); + + return FALSE; + } + + gboolean timer (GtkWidget *widget) + { + t += dt; + x += vx * dt; + y += vy * dt; + vx = vx; + vy = 0.5 * g * (t * t); + if (y + r >= HEIGHT) + vy = -vy * 0.9; + if (x + r >= WIDTH) + vx = -vx * 0.9; + if (x - r <= 0) + vx = -vx * 0.9; + gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT); + g_timeout_add (50, (GSourceFunc) timer, widget); + return FALSE; + } + + int main (int argc, char **argv) + { + gtk_init (&argc, &argv); + + GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_show (window); + gtk_window_set_title (GTK_WINDOW (window), "Hello"); + g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); + + GtkWidget *drawing_area = gtk_drawing_area_new (); + gtk_widget_show (drawing_area); + gtk_container_add (GTK_CONTAINER (window), drawing_area); + gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT); + + gtk_main (); + return 0; + } + \end{lstlisting}\vss} + +\end{document} diff --git a/20190121/fifo-1.c b/20190121/fifo-1.c new file mode 100644 index 0000000000000000000000000000000000000000..8bce6c07c152381c11ce367027b980a9330be3e0 --- /dev/null +++ b/20190121/fifo-1.c @@ -0,0 +1,31 @@ +#include <stdio.h> + +#define FIFO_SIZE 10 + +int fifo[FIFO_SIZE]; +int fifo_pointer = 0; + +void push (int x) +{ + fifo[fifo_pointer++] = x; +} + +int pop (void) +{ + return fifo[0]; + fifo[0] = fifo[1]; + fifo[1] = fifo[2]; + fifo[2] = fifo[3]; + /* ... */ +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/fifo-2.c b/20190121/fifo-2.c new file mode 100644 index 0000000000000000000000000000000000000000..f95579893f62180b408ecb10756ac8938b3c9848 --- /dev/null +++ b/20190121/fifo-2.c @@ -0,0 +1,31 @@ +#include <stdio.h> + +#define FIFO_SIZE 10 + +int fifo[FIFO_SIZE]; +int fifo_pointer = 0; + +void push (int x) +{ + fifo[fifo_pointer++] = x; +} + +int pop (void) +{ + fifo[0] = fifo[1]; + fifo[1] = fifo[2]; + fifo[2] = fifo[3]; + /* ... */ + return fifo[0]; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/fifo-3.c b/20190121/fifo-3.c new file mode 100644 index 0000000000000000000000000000000000000000..5214e1b28fb1b060bdaeea7be09e346a644e7f5d --- /dev/null +++ b/20190121/fifo-3.c @@ -0,0 +1,32 @@ +#include <stdio.h> + +#define FIFO_SIZE 10 + +int fifo[FIFO_SIZE]; +int fifo_pointer = 0; + +void push (int x) +{ + fifo[fifo_pointer++] = x; +} + +int pop (void) +{ + int result = fifo[0]; + fifo[0] = fifo[1]; + fifo[1] = fifo[2]; + fifo[2] = fifo[3]; + /* ... */ + return result; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/fifo-4.c b/20190121/fifo-4.c new file mode 100644 index 0000000000000000000000000000000000000000..957d5f18f6c8fe9d7c057db3d2467221b9dc463e --- /dev/null +++ b/20190121/fifo-4.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +#define FIFO_SIZE 10 + +int fifo[FIFO_SIZE]; +int fifo_pointer = 0; + +void push (int x) +{ + fifo[fifo_pointer++] = x; +} + +int pop (void) +{ + int result = fifo[0]; + for (int i = 1; i < FIFO_SIZE; i++) + fifo[i - 1] = fifo[i]; + return result; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/fifo-5.c b/20190121/fifo-5.c new file mode 100644 index 0000000000000000000000000000000000000000..092c1cdb5863d5c7bdac98f48ca8527ca3520e6b --- /dev/null +++ b/20190121/fifo-5.c @@ -0,0 +1,32 @@ +#include <stdio.h> + +#define FIFO_SIZE 10 + +int fifo[FIFO_SIZE]; +int fifo_pointer = 0; + +void push (int x) +{ + fifo[fifo_pointer++] = x; +} + +int pop (void) +{ + int result = fifo[0]; + for (int i = 1; i < FIFO_SIZE; i++) + fifo[i - 1] = fifo[i]; + return result; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + push (42); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/fifo-6.c b/20190121/fifo-6.c new file mode 100644 index 0000000000000000000000000000000000000000..2f055d6ce6df4c2fca950192053a6e008bed38b4 --- /dev/null +++ b/20190121/fifo-6.c @@ -0,0 +1,33 @@ +#include <stdio.h> + +#define FIFO_SIZE 10 + +int fifo[FIFO_SIZE]; +int fifo_pointer = 0; + +void push (int x) +{ + fifo[fifo_pointer++] = x; +} + +int pop (void) +{ + int result = fifo[0]; + for (int i = 1; i < FIFO_SIZE; i++) + fifo[i - 1] = fifo[i]; + fifo_pointer--; + return result; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + push (42); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/fifo-7.c b/20190121/fifo-7.c new file mode 100644 index 0000000000000000000000000000000000000000..0d739115c136639f64c4d98c439af7e4d72fe420 --- /dev/null +++ b/20190121/fifo-7.c @@ -0,0 +1,35 @@ +#include <stdio.h> + +#define FIFO_SIZE 10 + +int fifo[FIFO_SIZE]; +int fifo_write_pointer = 0; +int fifo_read_pointer = 0; + +void push (int x) +{ + fifo[fifo_write_pointer++] = x; + if (fifo_write_pointer >= FIFO_SIZE) + fifo_write_pointer = 0; +} + +int pop (void) +{ + int result = fifo[fifo_read_pointer++]; + if (fifo_read_pointer >= FIFO_SIZE) + fifo_read_pointer = 0; + return result; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + push (42); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/fifo-8.c b/20190121/fifo-8.c new file mode 100644 index 0000000000000000000000000000000000000000..b4ff68713645e0a5782b516071022bf71a8c50ac --- /dev/null +++ b/20190121/fifo-8.c @@ -0,0 +1,50 @@ +#include <stdio.h> +#include <stdlib.h> + +#define FIFO_SIZE 10 + +int fifo[FIFO_SIZE]; +int fifo_write_pointer = 0; +int fifo_read_pointer = 0; + +void push (int x) +{ + fifo[fifo_write_pointer++] = x; + if (fifo_write_pointer >= FIFO_SIZE) + fifo_write_pointer = 0; + if (fifo_write_pointer == fifo_read_pointer) + { + fprintf (stderr, "fifo overflow\n"); + exit (1); + } +} + +int pop (void) +{ + if (fifo_read_pointer == fifo_write_pointer) + { + fprintf (stderr, "fifo underflow\n"); + exit (1); + } + else + { + int result = fifo[fifo_read_pointer++]; + if (fifo_read_pointer >= FIFO_SIZE) + fifo_read_pointer = 0; + return result; + } +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + push (42); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/fifo-9.c b/20190121/fifo-9.c new file mode 100644 index 0000000000000000000000000000000000000000..27f77412bac52fd70c52378c25531f03bd93d734 --- /dev/null +++ b/20190121/fifo-9.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <stdlib.h> + +#define FIFO_SIZE 10 + +int fifo[FIFO_SIZE]; +int fifo_write_pointer = 0; +int fifo_read_pointer = 0; + +void push (int x) +{ + int old_fifo_write_pointer = fifo_write_pointer; + fifo_write_pointer++; + if (fifo_write_pointer >= FIFO_SIZE) + fifo_write_pointer = 0; + if (fifo_write_pointer == fifo_read_pointer) + { + fprintf (stderr, "fifo overflow\n"); + exit (1); + } + else + fifo[old_fifo_write_pointer] = x; +} + +int pop (void) +{ + if (fifo_read_pointer == fifo_write_pointer) + { + fprintf (stderr, "fifo underflow\n"); + exit (1); + } + else + { + int result = fifo[fifo_read_pointer++]; + if (fifo_read_pointer >= FIFO_SIZE) + fifo_read_pointer = 0; + return result; + } +} + +int main (void) +{ + push (3); + push (7); + push (137); + for (int i = 0; i < 42; i++) + push (i); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + push (42); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/lists-1.c b/20190121/lists-1.c new file mode 100644 index 0000000000000000000000000000000000000000..a04067e1403601ef56dd706d6148c1d386884e82 --- /dev/null +++ b/20190121/lists-1.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +typedef struct +{ + int content; + node *next; +} node; + +int main (void) +{ + return 0; +} diff --git a/20190121/lists-2.c b/20190121/lists-2.c new file mode 100644 index 0000000000000000000000000000000000000000..f27d1d5af7c0c237f0d0286155380ef9452a497a --- /dev/null +++ b/20190121/lists-2.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +typedef struct node +{ + int content; + struct node *next; +} node; + +int main (void) +{ + return 0; +} diff --git a/20190121/lists-3.c b/20190121/lists-3.c new file mode 100644 index 0000000000000000000000000000000000000000..9c9029724efff25263813c5491add92504779d17 --- /dev/null +++ b/20190121/lists-3.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +typedef struct node +{ + int content; + struct node *next; +} node; + +int main (void) +{ + node node3 = { 3, NULL }; + node node7 = { 7, NULL }; + node node137 = { 137, NULL }; + + node *first = &node3; + + for (node *p = first; p; p = p->next) + printf ("%d\n", p->content); + + return 0; +} diff --git a/20190121/lists-4.c b/20190121/lists-4.c new file mode 100644 index 0000000000000000000000000000000000000000..e048736b85cc228c35f31644d003e00cdefc5496 --- /dev/null +++ b/20190121/lists-4.c @@ -0,0 +1,25 @@ +#include <stdio.h> + +typedef struct node +{ + int content; + struct node *next; +} node; + +int main (void) +{ + node node3 = { 3, NULL }; + node node7 = { 7, NULL }; + node node137 = { 137, NULL }; + + node3.next = &node7; + node7.next = &node137; + node137.next = NULL; + + node *first = &node3; + + for (node *p = first; p; p = p->next) + printf ("%d\n", p->content); + + return 0; +} diff --git a/20190121/lists-5.c b/20190121/lists-5.c new file mode 100644 index 0000000000000000000000000000000000000000..a0cc620a884c133dd89582de726139091bc9c5d0 --- /dev/null +++ b/20190121/lists-5.c @@ -0,0 +1,29 @@ +#include <stdio.h> + +typedef struct node +{ + int content; + struct node *next; +} node; + +int main (void) +{ + node node3 = { 3, NULL }; + node node7 = { 7, NULL }; + node node137 = { 137, NULL }; + + node3.next = &node7; + node7.next = &node137; + node137.next = NULL; + + node node5 = { 5, NULL }; + node5.next = node3.next; + node3.next = &node5; + + node *first = &node3; + + for (node *p = first; p; p = p->next) + printf ("%d\n", p->content); + + return 0; +} diff --git a/20190121/stack-0.c b/20190121/stack-0.c new file mode 100644 index 0000000000000000000000000000000000000000..289aab7602e1e1f9f1e6433b858f295792499b1b --- /dev/null +++ b/20190121/stack-0.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +void push (int x) +{ +} + +int pop (void) +{ + return 42; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/stack-1.c b/20190121/stack-1.c new file mode 100644 index 0000000000000000000000000000000000000000..d1de6e09d718b69a9d255b6c83f6f7815584b430 --- /dev/null +++ b/20190121/stack-1.c @@ -0,0 +1,28 @@ +#include <stdio.h> + +#define STACK_SIZE 10 + +int stack[STACK_SIZE]; +int stack_pointer = 0; + +void push (int x) +{ + stack[stack_pointer] = x; + stack_pointer++; +} + +int pop (void) +{ + return 42; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/stack-1.s b/20190121/stack-1.s new file mode 100644 index 0000000000000000000000000000000000000000..7cfe1cf190c4a174cec9d5b41e98999db443fd38 --- /dev/null +++ b/20190121/stack-1.s @@ -0,0 +1,73 @@ + .file "stack-1.c" + .text + .globl push + .type push, @function +push: +.LFB11: + .cfi_startproc + movl stack_pointer(%rip), %eax + movslq %eax, %rcx + leaq stack(%rip), %rdx + movl %edi, (%rdx,%rcx,4) + addl $1, %eax + movl %eax, stack_pointer(%rip) + ret + .cfi_endproc +.LFE11: + .size push, .-push + .globl pop + .type pop, @function +pop: +.LFB12: + .cfi_startproc + movl $42, %eax + ret + .cfi_endproc +.LFE12: + .size pop, .-pop + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "%d\n" + .text + .globl main + .type main, @function +main: +.LFB13: + .cfi_startproc + subq $8, %rsp + .cfi_def_cfa_offset 16 + movl $3, %edi + call push + movl $7, %edi + call push + movl $137, %edi + call push + movl $42, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + movl $42, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + movl $42, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + movl $0, %eax + addq $8, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE13: + .size main, .-main + .globl stack_pointer + .bss + .align 4 + .type stack_pointer, @object + .size stack_pointer, 4 +stack_pointer: + .zero 4 + .comm stack,40,32 + .ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516" + .section .note.GNU-stack,"",@progbits diff --git a/20190121/stack-2.c b/20190121/stack-2.c new file mode 100644 index 0000000000000000000000000000000000000000..20bed3660cffea7e0a9803451f69ef56a4a04b93 --- /dev/null +++ b/20190121/stack-2.c @@ -0,0 +1,27 @@ +#include <stdio.h> + +#define STACK_SIZE 10 + +int stack[STACK_SIZE]; +int stack_pointer = 0; + +void push (int x) +{ + stack[stack_pointer++] = x; +} + +int pop (void) +{ + return 42; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/stack-2.s b/20190121/stack-2.s new file mode 100644 index 0000000000000000000000000000000000000000..80ecf1daa0e7f5a5a2b708e4ce2dada052eaa506 --- /dev/null +++ b/20190121/stack-2.s @@ -0,0 +1,73 @@ + .file "stack-2.c" + .text + .globl push + .type push, @function +push: +.LFB11: + .cfi_startproc + movl stack_pointer(%rip), %eax + leal 1(%rax), %edx + movl %edx, stack_pointer(%rip) + cltq + leaq stack(%rip), %rdx + movl %edi, (%rdx,%rax,4) + ret + .cfi_endproc +.LFE11: + .size push, .-push + .globl pop + .type pop, @function +pop: +.LFB12: + .cfi_startproc + movl $42, %eax + ret + .cfi_endproc +.LFE12: + .size pop, .-pop + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "%d\n" + .text + .globl main + .type main, @function +main: +.LFB13: + .cfi_startproc + subq $8, %rsp + .cfi_def_cfa_offset 16 + movl $3, %edi + call push + movl $7, %edi + call push + movl $137, %edi + call push + movl $42, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + movl $42, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + movl $42, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + movl $0, %eax + addq $8, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE13: + .size main, .-main + .globl stack_pointer + .bss + .align 4 + .type stack_pointer, @object + .size stack_pointer, 4 +stack_pointer: + .zero 4 + .comm stack,40,32 + .ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516" + .section .note.GNU-stack,"",@progbits diff --git a/20190121/stack-3.c b/20190121/stack-3.c new file mode 100644 index 0000000000000000000000000000000000000000..b20a444d628a88101416097c79b34e0669b24d21 --- /dev/null +++ b/20190121/stack-3.c @@ -0,0 +1,28 @@ +#include <stdio.h> + +#define STACK_SIZE 10 + +int stack[STACK_SIZE]; +int stack_pointer = 0; + +void push (int x) +{ + stack[stack_pointer++] = x; +} + +int pop (void) +{ + stack_pointer--; + return stack[stack_pointer]; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/stack-4.c b/20190121/stack-4.c new file mode 100644 index 0000000000000000000000000000000000000000..0d738f95ff81ce1701b4aa8a12df30094b723851 --- /dev/null +++ b/20190121/stack-4.c @@ -0,0 +1,27 @@ +#include <stdio.h> + +#define STACK_SIZE 10 + +int stack[STACK_SIZE]; +int stack_pointer = 0; + +void push (int x) +{ + stack[stack_pointer++] = x; +} + +int pop (void) +{ + return stack[--stack_pointer]; +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/stack-5.c b/20190121/stack-5.c new file mode 100644 index 0000000000000000000000000000000000000000..38a187208208488bdb8e988d93442d57730e421e --- /dev/null +++ b/20190121/stack-5.c @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <stdlib.h> + +#define STACK_SIZE 10 + +int stack[STACK_SIZE]; +int stack_pointer = 0; + +void push (int x) +{ + if (stack_pointer < STACK_SIZE) + stack[stack_pointer++] = x; + else + { + fprintf (stderr, "stack overflow\n"); + exit (1); + } +} + +int pop (void) +{ + if (stack_pointer > 0) + return stack[--stack_pointer]; + else + { + fprintf (stderr, "stack underflow\n"); + exit (1); + } +} + +int main (void) +{ + push (3); + push (7); + push (137); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/stack-6.c b/20190121/stack-6.c new file mode 100644 index 0000000000000000000000000000000000000000..be00e160384be5e4af05831547ed74b636c3bdf0 --- /dev/null +++ b/20190121/stack-6.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <stdlib.h> + +#define STACK_SIZE 10 + +int stack[STACK_SIZE]; +int stack_pointer = 0; + +void push (int x) +{ + if (stack_pointer < STACK_SIZE) + stack[stack_pointer++] = x; + else + { + fprintf (stderr, "stack overflow\n"); + exit (1); + } +} + +int pop (void) +{ + if (stack_pointer > 0) + return stack[--stack_pointer]; + else + { + fprintf (stderr, "stack underflow\n"); + exit (1); + } +} + +int main (void) +{ + for (int i = 0; i < 42; i++) + push (i); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + printf ("%d\n", pop ()); + return 0; +} diff --git a/20190121/stack-7.c b/20190121/stack-7.c new file mode 100644 index 0000000000000000000000000000000000000000..b583bc281f9ae3acd673ec9ea4de75720084fb50 --- /dev/null +++ b/20190121/stack-7.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <stdlib.h> + +#define STACK_SIZE 10 + +int stack[STACK_SIZE]; +int stack_pointer = 0; + +void push (int x) +{ + if (stack_pointer < STACK_SIZE) + stack[stack_pointer++] = x; + else + { + fprintf (stderr, "stack overflow\n"); + exit (1); + } +} + +int pop (void) +{ + if (stack_pointer > 0) + return stack[--stack_pointer]; + else + { + fprintf (stderr, "stack underflow\n"); + exit (1); + } +} + +int main (void) +{ + push (3); + push (7); + push (137); + for (int i = 0; i < 42; i++) + printf ("%d\n", pop ()); + return 0; +}