Was Ihr Code macht:
Eingänge String in 20-Byte-Pufferspeicher an der Adresse inputString
(die 268501027
unter MARS passiert zu sein, die wie Sie beim Laufen genau gleiche Zuweisung aussieht).
Wenn der Benutzer "X123" eingibt, dann sehen die Bytes im Speicher so aus: 58 31 32 33 0A 00 00 00 ...
(hat nicht herausgefunden, wie man Speicher pro Byte in MARS anzeigt, also muss man verstehen, wie Little-Endian funktioniert, und wie diese in MARS angezeigten Wortwerte auf bestimmte einzelne Bytes reduziert werden können), 0x58 ist der ASCII-Code für den Buchstaben X, 0x31 ist der ASCII-Code für Buchstabe/Ziffer 1 usw. ... 0x0A ist das Newline-Zeichen (Teil der Eingabe!), Die verbleibenden Nullen sind Ihr Glück, dass MARS Ihnen am Anfang der Ausführung des Codes das zero .data-Segment zur Verfügung stellt, so dass Ihre nächste Ausgabe der Benutzerzeichenfolge korrekt null-terminiert ist (und auch newline).
Dann Sie Ausgabezeichenfolge von Adresse inputString+1
, die, dass die Punkte auf 0x31
= ASCII-Code für digit '1'
, und die restlichen von Benutzereingabe folgt, so dass die erwartete (?) String "123 \ n" ausgegeben wird. Beachten Sie, dass "ersten Buchstaben entfernen" nichts vom Gerät entfernt, sondern nur den Zeiger anpasst, der dann als "Anfang" der Zeichenfolge verwendet wird. Wenn Sie den Brief im selben Speicherbereich tatsächlich entfernen, müssen Sie Byte für Byte den gesamten Buchstaben an die vorherige Adresse kopieren, was eine wesentlich teurere Operation ist, und dann den einzelnen Zeiger um eins anpassen.
sw $a0, outInt #store new word in outInt
Diese speichert die Adresse outInt
268501028
in Speicherwort bei der Adresse eingestellt. Es speichert das Wort nicht selbst. Auch hier findet keine Umwandlung von String in int statt. Alles, was Sie tun, ist nur speichern Sie den Zeiger (Speicheradresse), die 268501028. 32b unsigned integer ist
Dann Sie ohne v0
Argument ausdrücklich besagt, neben syscall
nennen so 4
der vorherige Wert wird wiederverwendet, wieder zur Ausgabe string, von der gleichen Adresse, so wieder erhalten Sie die gleiche Ausgabe "123\n"
. Ich würde empfehlen, immer die v0
vor jeder syscall
explizit festzulegen, auch wenn es der gleiche Wert ist, der bereits in Register ist, erleichtert das Lesen der Quelle beim Debuggen im Kopf und Überprüfen.
Schließlich laden Sie Wert 5 in t1
und daß 268501028
zu dieser Adresse hinzuzufügen, die in ganzzahligen 268501033
führt, und zu speichern, dass in dem Speicher an der Adresse addedInt
. Dann drucken Sie das Label +5 aus und laden diesen Wert zurück in a0
und drucken es aus.
Sie sollten den eingebauten Debugger des MARS/SPIM-Familiensimulators, den Sie verwenden, verwenden, um die Anweisungen zu übergehen und die Registerwerte und den Speicherinhalt zu sehen und diese mit meiner Beschreibung zu vergleichen, um zu verstehen, was diese Anweisungen tatsächlich bedeuten machen.
fix:
„zu breit“, im Grunde müssen Sie entweder:
a) das Benutzer-String in Integer-Wert zu konvertieren: mit Schreiben der Eingangslade Buchstaben, bis Sie entweder Newline-Zeichen oder Null-Terminators erreichen Umwandeln von Ziffern in Werte (ASCII_code - '0') == digit_value
, dann Berechnen der temporären Summe, wie sum = sum*10 + digit_value
, beginnend mit sum = 0
. Am Ende der Schleife enthält sum
den Wert 123
(aus der Zeichenfolge "123"
). Dann können Sie 5
als Ganzzahl hinzufügen (Wert 128
erhalten) und syscall, v0=1
verwenden, um es auszugeben.
b) Addieren Sie den Wert 5 über die Zeichenfolge, dh die Adresse von Newline/Zero-Terminator, dann um 1 zurück. Sie haben die Adresse der letzten Ziffer (wenn die Eingabe gültig ist!) Um Adresse inputString
zu adressieren, und wenn Adresse gültig ist, können Sie auch überprüfen, Inhalt in Bereich '0' = 0x30
.. '9' = 0x39
, dh, dass der Inhalt ASCII-Ziffer-Brief ist Dann Schleife: 1) 5 zum aktuellen Buchstaben hinzufügen 2) wenn Ergebnis <= '9'
ist , dann sieht die Zeichenfolge wie Zahl aus und Sie können sie ausgeben (Verzweigung zur Ausgabe mit inputString+1
Adresse zur Anzeige). 3) subtrahiere 10 davon (d. H. '7'+5 = 60 = '<'
, dann 60 - 10 = 50 = digit-letter '2'
) 4) dekrementiere die Adresse um 1 (Bewegung um eine Position nach links) 5) bestätige die Adresse. 6) check Inhalt: Wenn nicht Ziffer, überschreiben Sie es mit dem Buchstaben '1'
und zum Ausgang von Adresse dieser '1'
(mit gültiger Eingabe wie "X99"
, die gleich inputString
sein wird, und der Speicher wird modifizierte Zeichenfolge enthalten "104"
), wenn Ziffer, hinzufügen Eins dazu und zu Schritt 2 springen) - prüfen, ob der resultierende Wert <= '9'
ist.
Und das ist es, das ist "Hinzufügen von 5", wenn Sie nicht über ganzzahlige Werte, sondern über ASCII-Zeichen im Speicher arbeiten. Das hört sich vielleicht nach viel Arbeit an, aber in Variante a) ist es möglicherweise einfacher zu schreiben und zu debuggen als die Konvertierung von String zu Int.
Schließlich sollten Sie wahrscheinlich versuchen, beide Varianten zu schreiben, nur um zu verstehen, wie grundlegende Datentypen in Assembly funktioniert, und was ist der Unterschied zwischen "Zeichenfolgen" und Ganzzahlen (und Byte- und Wortwerte) und wie Speicheradressierung funktioniert .
Was * sollte * die Ausgabe sein, und warum? –
Die Ausgabe sollte 128 sein (weil 123 + 5 = 128). Es ist für eine Aufgabe. –
Was sehen Sie in Registern, wenn Sie den Debugger verwenden, um den Code in einem Schritt zu bearbeiten? –