2016-07-20 20 views
0

Ich bin neu in Assembly-Codierung und ich stieß auf ein Problem, das besagt, den folgenden C-Code zu MIPS-Assembly zu übertragen.C zu MIPS Assembly Verwirrung

b[8] = b[i-j] + x ; 

und Variablen i, j, x sind in den Registern 7,4 und 15 und die Basisadresse des Arrays B ist in 2.870.220 Dezimal.

kam ich mit der folgenden Lösung bis

lui $2, 0x002B 
ori $2, $2, 0xCBCC 
sub $3, $7, $4 
add $3, $2, $3 
lw $12, 0($3) 
addu $12, $12, $15 
sw $12, 32($2) 

aber wenn ich die Antwort überprüft, gab es eine zusätzliche Zeile von

sll $3, $3, 2 

nach der subtrahieren Anweisung.

Könnte jemand bitte erklären, warum wir den Inhalt von Register $ 3 mit 4 multiplizieren müssen?

+0

das Array ist Wort (32 Bit) Größe nicht Byte-Größe? –

+0

Das Problem gibt nichts über das Array an. –

+1

ist es wahrscheinlich Wortgröße. eigentlich vergesse ich die Syntax für Mips, lw ist Ladewort ja? eine 32-Bit-Sache? Was ist Ladebyte? Pfund? Wenn lw eine 32-Bit-Last ist, dann müssen Sie den Offset auf ein Wort ausrichten, also die Multiplikation mit 4, um den Offset auf die Adresse und nicht den Index zu bekommen –

Antwort

0

Ich gebe eine Illustration.

Lassen Sie uns sagen, wir haben diese 5 Bytes in Speicherplätzen 0x00000000 zu 0x00000004 gespeichert (als Beispiel I-Speicherkarten bin hier nicht berücksichtigt):

| 0x27 | 0x82 | 0x97 | 0x42 | 0x11 |

Wenn Sie ein Wort an die Speicheradresse 0x00000000 laden, erhalten Sie das 32-Bit-Wort 0x27829742, weil es die nächsten 4 Bytes von der Basisadresse enthält.

Bei Speicheradresse 0x00000001 erhalten Sie jedoch 0x82974211.


Ich denke, dass dieses Missverständnis kommt von wie Operator [] in Arrays implementiert ist, so werde ich versuchen, darauf zu erweitern. Betrachten Sie den folgenden C-Code:

int arr[3] = { 1, 3, 5 }; 
printf("%d\n", arr[2]); // print third element 

Wenn arr Zugriff auf [2], hat es zu berücksichtigen, die Größe der Elemente des Arrays. Unter der Annahme, dass der int-Standard 32-Bit (4 Byte), würden Sie den folgenden Code während der Kompilierung erhalten:

int arr[3] = { 1, 3, 5 }; 
printf("%d\n", *(arr + (2 * sizeof(int)))); // print third element 

In diesem Fall ist es verschiebt den Basiszeiger des Arrays durch eine im Wert ganzen Zahl von Bytes durch den Index multipliziert auf sie zugegriffen wird, und dann dereferenziert wird, um das spezifizierte Element zu erhalten.

Fazit:

Speicherblöcke werden in 8-Bit-Byte ausgerichtet sind, nicht 32-Bit-Wörter.

+0

Eine bessere Möglichkeit, Ihren letzten Punkt anzugeben: Speicheradressen beziehen sich auf Bytes, nicht auf ganze 32-Bit-Wörter. Also zwei benachbarte Wörter unterscheiden sich in der Adresse um 4. Außerdem weiß ich, was Sie mit Ihrer "Wie kompiliert" Version des C zu sagen versuchen, aber der Code, den Sie gezeigt haben, ist immer noch gültig C, der den Index zweimal skaliert! Vielleicht laden Sie ein 4-Byte-Wort von '((char *) arr) + 2 * sizeof (int)'. –