Wie sind die Registerkonvention im Assembler zu verstehen?

2 Antworten

Guten Morgen zurück :)

Ich nehme diese zwei Punkte einmal zusammen, denn hier beginnt das böse Übel.
Wie ist das denn eigentlich gemeint ? Ich persönlich verstehe es so, dass die $si Register vor dem Aufruf in den Stack geladen werden müssen, wenn sie in der aufzurufenden Funktion auch vorhanden sind. Und durch das Speichern wird der Wert nicht überschrieben. Die Frage wäre nun, wenn ich ein Register (z.b für einen Counter) benötige, dass nicht in der aufzurufenden Funktion vorkommt, ich es auch auf den Stack speichern muss, oder ob es dann ein t Register wird, statt ein s?

Du machst soviel Platz im Stack frei wie Du $s-Register in Deiner aufzurufenden Funktion (Subroutine) brauchst + 4 Bytes für $ra und schreibst den gesicherten, ursprünglichen Inhalt beim Verlassen wieder zurück.

  • Sinn und Zweck ist, dass die ursprüngliche Funktion 'nicht mitbekommt' dass zwischenzeitlich mit dem $s-Registern gearbeitet wurde in der Subroutine.
  • Das ist auch die Antwort auf Deine Frage hier, nämlich dass Du dadurch nichts machen musst mit dem $s-Register, wenn sie nicht in deiner Subroutine vorkommt

Kannst natürlich auch ein $t-Register nehmen sofern die Subroutine keine weiteren Funktionen aufruft, die mit dem Register arbeitet. Dadurch sparst Du auch noch ein wenig Platz auf dem Stack. Technisch gibt es keinen Unterschied zwischen $t und $s Register - Du als Programmierer 'garantierst' mit Einhaltung der Konvention nur dass $s-Inhalte auch nach Funktionsaufrufe unverändert bleiben, bei $t-Registern musst Du es nicht garantieren.

kopiere Argumente ($ai) , die nach einem Aufruf benötigt werden, in ein $si-Register und sichere zuvor $si auf dem
  • Damit ist gemeint: Wenn Du z.B. 2 Argumente hast, in $a0 und $a1, dann...
  • machst Du Platz auf dem Stack frei für $ra und z.B. $s0 und $s1
  • speicherst (sicherst) den alten Inhalt von $s0 und $s1 auf dem Stack
  • und kopierst anschließend $a0 -> $s0, $a1 -> $s1

Jetzt konkret anhand eines Beispiels.

---

LG. Kesselwagen

Woher ich das weiß:Studium / Ausbildung

Luisa116 
Fragesteller
 07.01.2019, 12:30

Hallo,
danke für deine Antwort und tut mir leid für meine verspätete Antwort, habe bis früh um 5 daran gesessen und jetzt erst aufgewacht.

"Kannst natürlich auch ein $t-Register nehmen sofern die Subroutine keine weiteren Funktionen aufruft, die mit dem Register arbeitet. Dadurch sparst Du auch noch ein wenig Platz auf dem Stack. Technisch gibt es keinen Unterschied zwischen $t und $s Register - Du als Programmierer 'garantierst' mit Einhaltung der Konvention nur dass $s-Inhalte auch nach Funktionsaufrufe unverändert bleiben, bei $t-Registern musst Du es nicht garantieren."

Also wenn ich eine Funktion habe die eine andere Aufruft, sollte man immer s Register nutzen? Die t Register dann lieber in der Funktion die Aufgerufen werden soll, richtig?

Wenn ich nun einen Counter habe, der einfach nur hochzählt, sollte er dann auch ein s Register sein? Nutzt man dann t Register überhaupt in einer nicht Blattfunktion also einer Funktion die andere Funktionen aufruft?

0
Kesselwagen  07.01.2019, 17:19
@Luisa116

Hello again,

oha alles gut :O Lag noch selbst ebenfalls bis 5 - Schlafrhythmus umstellen für den Unialltag läuft! 😅

Also wenn ich eine Funktion habe die eine andere Aufruft, sollte man immer s Register nutzen? Die t Register dann lieber in der Funktion die Aufgerufen werden soll, richtig?

Verwende $s-Register wenn Dir wichtig ist, dass der Wert im Register nach dem Funktionsaufruf unberührt bleibt. Ansonsten steht es Dir auch frei, $t-Register zu benutzen, Beispiel unten:

Wenn ich nun einen Counter habe, der einfach nur hochzählt, sollte er dann auch ein s Register sein? Nutzt man dann t Register überhaupt in einer nicht Blattfunktion also einer Funktion die andere Funktionen aufruft?

Nicht unbedingt. Du hast eine Nicht-Blattfunktion, die mit einem $t-Register zählt. Nachdem sie fertig gezählt hat (vorausgesetzt keine anderen Funktionen werden währenddessen aufgerufen), hat sie ihre Aufgabe getan und speichert den Wert in ein Ergebnisregister, z.B. $v0. Was danach passiert mit dem $t-Register ist jetzt egal - es interessiert uns ja nicht mehr was $t0 noch so für Werte annimmt z.B. durch weitere Funktionsaufrufe.

Hoffe das Beispiel hat alle Klarheiten beseitigt 😆. Würde aber Dir raten einfach mal paar Kleinigkeiten zu programmieren und durch Trial and Error Dir klarzumachen wofür was gut ist. Mir hat es damals geholfen Code von anderen versuchen zu nachvollziehen, warum der Programmierer es genau so gemacht hat.

Was musst Du denn programmieren?

0
Luisa116 
Fragesteller
 07.01.2019, 17:30
@Kesselwagen

Ach ok, also alles was vor dem Aufruf passiert und danach nicht mehr benötigt wird, ist ein t Register genau wie alles was nur danach benötigt wird und davor nie angefasst wurde. Und alles was vor und nachher wichtig ist, wird in einem s Register festgehalten?

"Was musst Du denn programmieren?"

Ein Taschenrechner, der multiplizieren, addieren, subtrahieren logarithmieren etc kann

0
Kesselwagen  07.01.2019, 19:43
@Luisa116

So ungefähr, nicht umsonst werden $t-Register auch als temporäre Register bezeichnet - um mal 'eben schnell' was zwischenzuspeichern, was man sich dann wieder woanders hinspeichert oder verrechnet und das Register 'verwahrlosen' lässt.

Wenn ihr mul und div als Befehl nicht verwenden dürft dann ist es eine gute Übung. Logarithmieren? Kann ich mir nicht vorstellen. Da muss man doch mit Gleitkommazahlen rechnen... Oder ganzzahlig zur Basis 2?

0

Wie es der Begriff Konvention bereits ausdrückt, handelt es sich um eine Regel und nichts, was irgendwie fest implementiert wäre.

t-Registern sind technisch nicht anders als zB. s-Regs verschaltet. Die Konvention legt lediglich fest, das eine aufgerufenen Funktion s-Reg auf dem Stack speichern sollte. Bei t-Regs ist dies nicht vorgeschrieben, da der Programmierer die enthaltenen Daten als obsolet betrachtet.

Es gibt jedoch keinen technischen Grund ein t-Register nicht wie ein s-Register zu benutzen und dessen Daten ebenfalls auf dem Stack abzulegen und nach Ausführung der Funktion wieder zu laden.

https://stackoverflow.com/questions/20111326/mips-assembly-language-temporary-register-vs-saved-registers

http://courses.cs.washington.edu/courses/cse410/09sp/examples/MIPSCallingConventionsSummary.pdf

Die Registerkonventionen sind einfach nur Regeln an welche man sich halten sollte. Wenn Du genau weißt was Du tust kannst Du diese auch mal ignorieren.