1 SysProg Inhalt

1.1 Willkommen

  • Warum das Ganze?

  • Früher hiess die Vorlesung Maschinennahe Programmierung (MNP)

    Begleitende Literatur war damals das Buch von Paul Carter PC Assembly Language, http://pacman128.github.io/pcasm

    • nasm Assembler

    • C wurde vorausgesetzt

  • Jetzt (fast) C-freies Studium, deshalb geht nun der Weg von Assembler nach C.

1.2 Literatur

Jonathan Bartlett, Programming from the Ground Up (PGU), 2004.

http://savannah.nongnu.org/projects/pgubook (frei, unter GFDL)

1.3 PGU, Kap. 1

  • Assemblersprache des x86 Prozessors

  • GNU/Linux Betriebssystem

  • Standard GCC („GNU Compiler Collection“):

    • gas (Assembler)

    • gcc (C Compiler)

    • gdb (GNU Debugger)

  • Linux Neulinge

  • Welches Linux?

    • Ubuntu, Debian, Redhat (Fedora), Gentoo, …

  • GNU Projekt

    • Projekt der Free Software Foundation: freies Betriebssystem

    • http://www.gnu.org

    • GNU/Linux = GNU Software + Linux Kern

  • Sprachen, geordnet von geringem zu hohem Abstraktionsgrad

    • Maschinensprache

    • Assemblersprache

    • Hochsprache bzw. Systemprogrammiersprache (C, Java)

    • „Sehr hohe“ Hochsprachen (Lisp, Python und andere)

1.4 PGU, Kap. 2 (Rechnergrundlagen)

  • Struktur des Arbeitsspeichers

  • Programme und Daten sind im gleichen Speicher (von-Neumann Architektur)

  • CPU

    • Program Counter, Instruction Pointer (PC, IP)

    • Adress- und Datenbus

    • Instruktionsdekoder

    • Register

    • Arithmetische Einheit (ALU)

  • Mittel zur Leistungssteigerung (Optimierungen) ändern nichts am Grundprinzip:

    Cache Hierarchie, superskalare Prozessoren, Pipelining, Branch Prediction, out-of-order execution, Microcode Übersetzung, Koprozessoren und so weiter können bei dieser Vorlesung ignoriert werden - nicht bei Prof. Märtin :-)

  • Begriffe

    • Adresse (4 Byte)

    • Byte

    • ASCII (PGU, Anhang D)

    • Word (4 Byte)

    • Zeiger (pointer): Daten werden als Adresse verstanden

  • Beispiel Kundendaten (customer record)

    • Feste Felder: Name (50), Adresse (50), Alter (4), Id (4)

    • Zeiger: Name (4), Adresse (4), Alter (4), Id (4)

  • Methoden des Datenzugriffs

    In PGU heissen die Adressierungsarten:

    • immediate

    • register

    • direct

    • indexed

    • indirect

    • base pointer

    Die Erläuterung dazu in PGU finde ich nicht sehr verständlich. Besser ist es, wenn man sich direkt an das originale, gut lesbare Intel Handbuch Vol 1: Basic Architecture hält (Kapitel 3, Basic Execution Environment, S. 71-103):

    Allgemein gilt für die Adressangabe:

    Base +  [Index * Scale] + [Displacement]
    EAX     EAX       1            8-Bit
    EBX     EBX       2           16-Bit
    ECX     ECX       3           32-Bit
    EDX     EDX       4
    ...     ...
    

    Base und Index ist immer ein Register. Displacement ist eine Konstante.

    Varianten:

    • Base

    • Base + Displacement

    • (Index * Scale) + Displacement

    • Base + Index + Displacement

    • Base + (Index * Scale) + Displacement

    Beim GNU Assembler schreibt man:

    Displacement(Base, Index, Scale)
    

    Siehe auch MNP Foliensatz zu Adressierungsarten.

1.5 PGU, Kap. 3 (Erste Programme)

  • Assembler und Linker: as, ld

  • Sektionen: .text, .data

  • Symbol _start

  • Beispielprogramm sysprog/pgu/prog-3-1/ (Exitcode)

  • movl $1, %eax

    Im Klartext: move long von Quelle (Konstante 1) nach Ziel (Register eax)“. Das Dollar Zeichen vor der 1 markiert eine immediate Konstante.

  • Allgemeine Register: %eax, %ebx, %ecx, %edx

  • Spezialregister: %ebp, %esp, %eip, %eflags

  • Beispielprogramm prog-2: Hello World (aus Moritz Hoeppner’s Tutorial)

  • Beispielprogramm sysprog/pgu/prog-3-2/ (Maximum-Suche)

    • Programmstruktur

    • Adressierungsarten

    • %eax -> %ax -> %ah/%al

    • Ihre Hausaufgabe: Review, Use the concents

1.6 PGU, Kap. 4 (Funktionen - mit Komplexität umgehen)

  • Einteilung eines Programm in unabhängige Einheiten: Funktionen.

    • Funktionsname

    • Funktionsparameter

    • Lokale Variable

    • Statische Variable

    • Globale Variable

    • Rückkehradresse

    • Rückgabewert

  • „Calling Conventions“ (wir verwenden Konventionen der Sprache C)

  • Der Stack

    • pushl

    • popl

    Beispiele:

    • movl (%esp), %eax

    • movl %esp, %eax

    • movl 4(%esp), %eax

  • Die call Instruktion

    1. Adresse der nächsten Instruktion auf Stack

    2. EIP zeigt auf die aufzurufende Funktion

  • Stack beim Aufruf einer Funktion

    • Parameter (von rechts nach links!)

    • Rückkehradresse

    In der Funktion wird am Anfang EBP gesichert durch pushl %ebp.

    Danach wird EBP auf den aktuellen Stack Pointer gesetzt durch movl %esp, %ebp.

    Nun wird Platz für die lokalen Variablen in der Funktion gemacht durch subl $8, %esp (die 8 steht für die Anzahl Bytes).

    Zusammengefasster „Funktions-Prolog“:

    pushl %ebp
    movl  %esp, %ebp
    subl  #8, %esp
    
  • Am Ende der Funktion

    1. Resultatwert in %eax

    2. Zurücksetzen des Stack

    3. Funktion kehrt durch ret Anweisung zurück

    „Funktions-Epilog“:

    movl  %ebp, %esp
    popl  %ebp
    ret
    

    Danach sind die lokalen Variablen frei. Zukünftige push Operationen überschreiben die früheren Variablen. Niemals einen Zeiger auf diesen Bereich zurückgeben.

  • Der Aufrufer muss die Parameter entfernen

  • Verwendung der Register bei Funktionsaufruf

    • Man sollte sich nicht darauf verlassen, dass ein Register in der Funktion zufällig nicht überschrieben wird.

    • Register vor den Parametern auf Stack sichern, falls man diese später wieder braucht.

    • Details stehen im C ABI (ABI = Application Binary Interface). Das ist Teil von „Linux Standard Base Core Specification for IA32 3.2“, das man findet unter: https://refspecs.linuxfoundation.org/elf/x86_64-abi-0.95.pdf

  • Beispiel sysprog/pgu/prog-4/power.s

    Aufrufsequenz

    Stack Diagramm

  • Beispiel (Rekursion) sysprog/pgu/prog-4/factorial.s

1.7 PGU, Kap. 5 (Dateien öffnen, lesen und schreiben)

1.8 PGU, Kap. 6 (Module)

Programm in mehrere Dateien zerlegen und separat in .o Dateien umwandeln und linken.

  • Beispiel: sysprog/pgu/prog-6/

1.9 PGU, Kap. 7 (Robuste Programme)

Robuste Programme.

  • Beispiel: sysprog/pgu/prog-7/

1.10 PGU, Kap. 8 (Bibliotheken)

Bibliotheken und Dynamisches Linken.

  • Beispiel: sysprog/pgu/prog-8/

1.11 PGU, Kap. 9 (Dynamische Speicherverwaltung)

Dynamische Speicherverwaltung.

  • Beispiel: sysprog/pgu/prog-9/

1.12 PGU, Kap.10 (Arithmetik)

Computerarithmetik, boolsche Operationen, Programmstatus-Register, Gleitkommazahlen, negative Zahlen, oktale und hexadezimale Darstellung, Byteordnung (little/big), Zahlen für die Ausgabe in Strings umwandeln.

  • Beispiel: sysprog/pgu/prog-10/

1.13 PGU, Kap.11 (Hochsprachen)

Hochsprachen (C, Perl, Python)

1.14 PGU, Kap.12 (Optimierung)

Optimierung