2017-09-30 2 views
1

Wenn Sie angegeben:Convert C++ Funktion MIPS

calc (int b) { 
return b - 2; 
} 

Wie wäre es zu MIPS umgewandelt werden?

addi $v0, $a0, -2 
jr $ra 
*********************** 
jr $ra 
addi $v0, $a0, -2 
*********************** 
addi $v0, $a0, 2 
jr $ra 
*********************** 
lw $v0, 0($a0) 
addi $v0, $v0, -2 
jr $ra 

Ich bin nur Funktionen in MIPS Lernen und würde Beratung schätzen:

Ich habe Folgendes in Betracht gezogen. Ist es sinnvoll, in diesem Fall die Anweisung 'lw' zu verwenden?

+4

Andre, Wie werden Parameter in Ihrer ABI-Variante übergeben, in der die Rücksendeadresse gespeichert ist? Was ist die Version von MIPS? Hat es "Verzweigung [Delay Slot] (https://en.wikipedia.org/wiki/Delay_slot)"? LW ist zum Laden von Daten aus dem RAM-Speicher: https://en.wikipedia.org/wiki/MIPS_architecture#Loads_and_stores – osgx

Antwort

1

Ihre Ergebnisse sind korrekt, zumindest die erste. Nach here Ihrer ersten Antwort von:

addi $v0, $a0, -2 
jr $ra 

ist richtig. Es verwendet die geringste Menge an Anweisungen, die die Ausführungsgeschwindigkeit erhöhen, ganz zu schweigen davon, dass die Verwendung von Sofortinstruktionen die Abrufe aus dem Speicher reduziert. Schauen Sie sich die Tabelle in der Verbindung und wird Ihnen sagen, dass:

  • $v0 ist das Register, wo der erste Rückgabewert einer Funktion gehen sollte.
  • $a0 ist das Register des ersten Eingabeparameters, der beim Aufrufen von Funktionen verwendet wird.
  • $ra ist das Register, das die Rücksprungadresse von einer vorherigen Sprunganweisung enthält.

So wollte jemand die Assembly-Funktion aufrufen es aussehen würde:

li $a0, 5 # Load immediate the value 5 into register $a0. 
jal __calC# Jump to the sub routine '__calc' and store return address in $ra. 
      # Result will now be in $v0. 
... 

__calc: 
    addi $v0, $a0, -2 
    jr $ra 

Versuchen Sie, bleiben Sie weg von Anweisungen wie lw, wenn Sie können

:

int x = calc(5); // This line is the `C` equivalent and not part of assembly code. 

Versammlung wäre. Sie gehen in den RAM und holen Speicher, der sehr langsam ist, verglichen mit Werten in den Registern der CPU.

+0

Ich habe festgestellt, dass einige der Funktionen, die ich versuche, in MIPS zu schreiben, einschließlich dieser, dass, wenn ich benutze Anweisungen wie 'lw' oder 'sw', dass ich einen Fehler erhalte. Normalerweise lautet die Fehlermeldung: "Abrufadresse nicht auf Wortgrenze ausgerichtet". Bedeutet das etwas in Bezug auf Sie, Werte aus dem RAM zu holen? Denken Sie daran, ich verwende: ori $ a0, $ 0, 5 zu $ ​​a0 bis 5 zu Testzwecken zu initialisieren. Wenn ich den Wert von $ a0 nicht einschränke, denkst du, dass ich Fehler mit einer 'lw'-Anweisung vermeiden kann? Das ist nur aus Neugier, ich bin schon mit deiner Antwort zufrieden. – Andre

+1

Wenn Sie einen Wert in einem Register wie '5' im Register' $ a0' wollen, können Sie einfach den 'load instant' Befehl 'li' verwenden. 'li $ a0, 5' ist das gleiche wie $ a0 = 5. Wenn Anweisungen wie' lw' und 'sw' verwendet werden, benötigen Sie ein Register und eine RAM-Adresse. Wenn Sie 'lw $ a0, 5' verwenden, was bedeutet, dass Sie den Inhalt von RAM an Adresse' 5' in '$ a0' laden, kann der Inhalt im RAM alles Mögliche sein. Die RAM-Adresse "5" kann für die Kernel-Verwendung eingeschränkt sein, der User-Space-Speicher beginnt bei RAM-Adressen höher, was zu Abruffehlern führen würde. – user2205930

+1

Das Problem, dass die Abrufadresse nicht an Wortgrenzen ausgerichtet ist, ist ein anderes Problem.Ein WORD ist die Registergröße der CPU, in Ihrem Fall 32 Bit. Dies bedeutet, dass beim Lesen und Schreiben in den RAM die von Ihnen angegebene Adresse 32-Bit-ausgerichtet sein muss. Ohne die genauen Details Ihres Setups zu kennen, ist dies die beste Antwort, die ich geben kann. Normalerweise ist jede RAM-Adresse gültig. – user2205930