Der Martin: Zwei Zahlen mit Assembler addieren und ausgeben

Beitrag lesen

Hallo Markus,

Danke, aber mein Verständnisproblem ist hier begründet:
[...]
Ich verstehe den Zusammenhang zwischen den Registern eigentlich überhaupt nicht und wann ich welches wofür benutzen muss.

Aha, jetzt kommen wir zum Problem.
Betrachten wir's mal von der Hochsprache wie beispielsweise C. Jemand schreibt eine Funkion, die eine bestimmte Aufgabe erledigt, dafür aber ein paar Parameter braucht. In C ist das Aufrufen einer Funktion und die Übergabe der Parameter nur _eine einzige_ Anweisung.

In Assembler sind dazu mehrere Schritte nötig. Du musst erst die Parameter da hinschieben, wo die Funktion sie erwartet. Wo genau das ist, hat der Programmierer dieser Funktion zu verantworten.
In Assembler ist es gängige Praxis, Parameter in Prozessorregistern zu übergeben. Derjenige, der die Funktion mal geschrieben hat, hat sich entschieden, bestimmte Register zu verwenden. Welche das sind, und welchen Parameter er da erwartet, muss irgendwo dokumentiert sein.

Beim System Call mit int 0x80 (das ist auch eine Art Unterprogrammaufruf) ist die Sache insofern komplizierter, weil für sehr viele Aufgaben dieselbe Funktion aufgerufen wird. Der Inhalt von EAX entscheidet, welche konkrete Aufgabe das sein soll - das haben die Linux-Programmierer offensichtlich so festgelegt.

In Pseudocode formuliert, ist die Funktion, die sich hinter dem int 0x80 verbirgt, wahrscheinlich etwa so realisiert:

switch (EAX)
  { case 0:
       // Programmcode für System Call #0
       return;
    case 1:
       // Programmcode für System Call #1 (Programm beenden)
       exit();
    case 2:
       // Programmcode für System Call #2
       ...
       return;
    case 3:
       // Programmcode für System Call #3
       ...
       return;
    case 4:
       // Programmcode für System Call #4 (String ausgeben)
       write( (FILE*)EBX, (char *)ECX, (int)EDX);
       return;
    case 5:
       // Programmcode für System Call #5
       ...
       return;

Du musst die nötigen Parameter also in den Registern übergeben, die die Linux Kernel-Programmierer sich dafür herausgesucht haben. Und genau diese Übersicht (welche Funktionen kann man mit int 0x80 auslösen, welche Parameter brauchen sie, in welchen Registern werden die erwartet, und welche Information gibt die Funktion eventuell zurück) muss als "Linux Kernel API" irgendwo verfügbar sein. Na gut, vielleicht heißt es auch anders, ändert aber nichts am Prinzip. Diese API-Referenz ist bei der Assembler-Programmierung noch nötiger als in höheren Programmiersprachen, weil sich kaum jemand das alles merken kann.

Schönen Abend noch,

Martin

--
Viele Fachleute vertreten die Ansicht, jedes Feature eines Programms, das sich nicht auf Wunsch abstellen lässt, sei ein Bug.
Außer bei Microsoft. Da ist es umgekehrt.