2016-10-06 2 views
0

Ich versuche, ein Programm in MIPS-Assembly zu schreiben, das den Buchstaben einer gegebenen Zeichenfolge umkehrt. Ich denke, ich habe die Zeichenfolge im folgenden Code erfolgreich konvertiert, aber es wird nicht gedruckt. Ich glaube, ich habe es konvertiert, denn wenn ich eine Anweisung nach der anderen durchführe, durchläuft es die richtigen Schleifen in der richtigen Menge. Jede Hilfe zum Verständnis, wie man die neue Zeichenfolge druckt, würde sehr geschätzt werden. Der Code, den ich bereits geschrieben habe, ist unten, zusammen mit der Fehlermeldung, die ich erhalte. Vielen Dank an alle!MIPS Assembly - Briefkasten und Druckausgabe konvertieren

.data 

testString: .asciiz "TEST" 
revString: .space 32 
errorMessage: .asciiz "error, try again" 

.text 

la $t4, revString 
la $t0, testString 

checkCase: 
    lb $t1, ($t0) #assigns char of string to $t1 
    beqz $t1, end #ends loop 
    li $t2, 'a' 
    li $t3, 'A' 
    bge $t1, $t2, toUpper #confirms lowercase letter 
    bge $t1, $t3, toLower #confirms uppercase letter 
    j error #jumps to error if not a valid letter 

toLower: 
    addi $t1, $t1, 32 #converts upper to lowercase 
    sb $t1, ($t4) #stores letter in $t4 
    j continue #iterates both $t0 and $t4 

toUpper: 
    sub $t1, $t1, 32 #converts lower to uppercase 
    sb $t1, ($t4) #stores letter in $t4 
    j continue #iterates both $t0 and $t4 

continue: #jumps to next letter in testString and revString 
    add $t0, $t0, 1 
    add $t4, $t4, 1 
    j checkCase 

error: 
    la $a0, errorMessage #prints error message 
    li $v0, 4 
    syscall 

end: #prints reversed letter case string 
    #move $t4, revStr #assigns string in $t4 to revStr 
    la $a0, ($t4) 
    li $v0, 4 
    syscall 

Der Versuch, print $ t4 nicht funktioniert und wenn ich versuche, revStr gleich $ t4 den Wert zu machen, bekomme ich diese Fehlermeldung:

line 42 column 12: "revStr": operand is of incorrect type 
+0

Warum suchen Sie nicht zuerst in Ihrer Quelle nach "revStr" Definition? (Es gibt keine ... weil du es anders benannt hast). BTW * "Ich führe es eine Anweisung zu einer Zeit durch die richtigen Schleifen die richtige Anzahl von Malen" * .. das ist nicht so viel bedeutet, in der Regel ist es auch gut, einen Blick auf Register Werte, wenn es geht als erwartet. Und schließlich ist Ihr Fehler Kompilierzeit, also keine Notwendigkeit, überhaupt zu debuggen, mit Compiler-Fehler müssen Sie zuerst auf die Syntax konzentrieren (wie die Verwendung falscher Markenname oder Tippfehler in einem Buchstaben). – Ped7g

+0

Danke!Entschuldigung, ich habe diesen Tippfehler nicht bemerkt. Ich habe es behoben, bekomme aber immer noch den gleichen Fehler. Ich werde versuchen, die Registerwerte noch einmal durchzugehen. Ich denke, ich verstehe Bewegung nicht ganz. Ich poste ein Update, wenn ich etwas weiter teste. Danke für Ihre Hilfe! – Carl

+0

Sie wollen den Inhalt von revStr ('revString') anzeigen, richtig? Also müssen Sie '$ a0' mit der Pufferadresse laden, aber das ist genau das Symbol' revString' ist die Adresse dieses Raumes (keine "Variable" wie in der höheren Sprache). also 'la $ a0, revString'' li $ v0, 4' 'syscall' wird wahrscheinlich funktionieren. Aber versuchen Sie, etwas über Adressen/Speicher/etc zu lesen, um zu sehen, ob es nach dieser ersten Erfahrung mehr Sinn macht. Auch das erste Tippfehlerproblem ... beim Programmieren, glaube nie, dass du an der Quelle hast was du beabsichtigt hast. Versuchen Sie es beim Debuggen mit "frischen Augen" erneut zu lesen. – Ped7g

Antwort

0

(Zusammenfassung der Antworten aus den Kommentaren :)

Initial Problem war, Tippfehler in Symbolnamen (revStr statt revString) und unter Verwendung von falschen Anweisungen Adresse des Puffers zu laden das Ergebnis zu drucken, die so ausgesehen haben sollte:


Nach diesen Korrekturen immer noch mindestens einen Fehler im Code gibt es, die nach dem Austausch sichtbar werden revString: .space 32 mit:

# 16 bytes space initialized to 33 
revString: .byte 33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33 

(fix ist ganz offensichtlich, wenn Sie verstehen, wie asciiz Saiten im Speicher gespeichert, und wie der Speicher auf end: Etikett schaut, nur in Debugger einchecken).


Und einige erweiterte Hinweise:

Zurück in Ära des frühen CPUs die Leistung des Code sehr wichtig war, also vor allen Anweisungen Programmierer verbrachten in der Regel beträchtliche Zeit mit dem Schreiben zu denken, was er will wirklich erreichen und was ist die Optionen dafür.

In Ihrem Fall möchten Sie "A" (und ähnlich) in "a" und umgekehrt. 'A' ist der Wert 65 (ASCII-Definition), 'a' ist der Wert 97, also ist Ihre + -32-Idee richtig. Aber wenn Sie die ASCII-Tabelle sogar genau überprüfen und sich die binäre Darstellung der Werte von Groß- und Kleinbuchstaben vorstellen, werden Sie feststellen, dass jeder Buchstabenwert das gleiche Bitmuster außer dem fünften Bit (Wert 32) hat. Anstatt also + -32 zu verwenden, können Sie das Bit einfach um xor $t1,$t1,32 ohne Verzweigung umdrehen (oder bestätigen, dass der Wert mindestens> = 'A' ist).

Auch aktuelle Code in beiden Zweige haben die gleichen sb $t1, ($t4), nach dem ersten Version Look für solche Duplizitäten zu schreiben und den Code Refactoring durch diese beiden Schreiben an continue: Etikett zu bewegen. Wenn Sie häufig wiederverwendbare Codeteile suchen und sie umstrukturieren oder Gruppen von Anweisungen in aufrufbare Prozeduren umwandeln, weist Ihr Code weniger Duplikate auf und wird insgesamt wesentlich kürzer sein (für die Preise einer etwas komplexeren Ablauflogik) mit zusätzlichen Anrufen). Kürzerer Code = weniger Debugging (normalerweise nicht garantiert).