Seite 1 von 1

Letztes Byte aus einem String löschen

Verfasst: 31. Okt 2008 11:16
von ChRiZz88
Hi,

ich stehe gerade vor dem Problem nicht zu wissen, ob es möglich ist, das letzte Byte eines Strings zu löschen, sodass aus HalloWelt ein HalloWel wird.
Bislang lösche ich mit lb $t0, 0($a0) und anschließend mit addi $a0, $a0, 1.
Ich habe eben versucht einen Zähler zu implementieren, der herausfindet, dass mein Wort beispielsweise 9 Zeichen hat, dann die 9 in $t3 ablegt und dann mit lb $t0, $t3($a0) das 9. Zeichen heraus lädt, aber erstens habe ich damit dann ja noch nicht gelöscht, sondern nur herauskopiert (was ja nicht Sinn der Sache ist) und zweitens gibt's einen Error ;) (= "$t3": operand is of incorrect type)

Danke im Voraus (:

Re: Letztes Byte aus einem String löschen

Verfasst: 31. Okt 2008 11:54
von SebFreutel
ChRiZz88 hat geschrieben:...mit lb $t0, $t3($a0) [...] und zweitens gibt's einen Error ;) (= "$t3": operand is of incorrect type)...
Register (meistens Zähler) stehen bei den Lade-/Speicherbefehlen immer in den Klammern, vor der Klammer nur Label und Konstanten, siehe MIPS-Befehlsblatt.
Ich nehme an du hast die Adresse des Labels, an dem HalloWelt steht, in $a0 geladen - brauchst du nicht.

Re: Letztes Byte aus einem String löschen

Verfasst: 31. Okt 2008 14:23
von ChRiZz88
Oo Woher weiß er denn dann, was mein String ist?
Außerdem fehlt mir augenblicklich eine Möglichkeit, überhaupt einen String in ein Register zu schreiben, bislang mache ich das über helloworld: .asciiz "HalloWelt" im .data-Bereich und weiter unten mit la $a0, helloworld, aber das kann ich ja nich dauernd im Programm machen...

Edit: Mein Problem zentriert sich mittlerweile auf diese Frage: Wie kann ich in einem String auf einen bestimmten Wert zugreifen, den ich auch mit einem Register abfragen kann? Dazu muss ich ein Label im .data-Bereich definieren, das habe ich gemacht (helloworld: .asciiz "HalloWelt"). Allerdings funktioniert dann sowas hier nicht: lb $t0, helloworld(0) ("helloworld is of incorrect type")...
Wie also greife ich auf die verschiedenen Bytes eines Labels zu?

Re: Letztes Byte aus einem String löschen

Verfasst: 31. Okt 2008 14:51
von SebFreutel
Einen String kannst du auch nicht in ein Register laden, nur eine Speicheradresse, oder ein (bzw. maximal 4) Zeichen.

Deine Methode ist soweit richtig, nur brauchst du eben nicht immer die Adresse mit la laden, sondern kannst einfach den Namen des Labels bei lb verwenden.

la $t0, helloworld;
lb $t1, 0($t0);

ist dasselbe wie

lb $t1, helloworld;

ist dasselbe wie

lb $t1, helloworld + 0;

ist dasselbe wie

lb $t1, helloworld($zero);

ist dasselbe wie

li $t0, 0;
lb $t1, helloworld($t0);

und lädt das erste Zeichen des Strings in $t1, also "H" bzw. seinen ASCII-Wert natürlich.

das a von $a0-$a3 steht übrigens für Argument, nicht für Adresse, diese Register sollten (d.h. es ist reine Konvention) nur für Funktionsaufrufe und Syscalls verwendet werden. (vgl. Kap. 2, Teil 1, Folie 10)

Re: Letztes Byte aus einem String löschen

Verfasst: 31. Okt 2008 15:53
von ChRiZz88
Das hilft mir weiter, danke ;)

Re: Letztes Byte aus einem String löschen

Verfasst: 3. Nov 2008 21:43
von ivoch
SebFreutel hat geschrieben:Deine Methode ist soweit richtig, nur brauchst du eben nicht immer die Adresse mit la laden, sondern kannst einfach den Namen des Labels bei lb verwenden.
Das gilt aber nicht für Strings, die z.B.von der Konsole oder einer Datei ausgelesen wurden - die muss man mit la laden.

ChRiZz88, im Bezug auf deiner ursprünglichen Frage - du kannst das letzte Byte löschen, indem du es einfach auf 0 setzt (also ASCII Code 0, "null"). Also z.B.

sb $zero String($t0) #wobei das zu löschende Byte in Adresse $t0 steht. So kannst du auch Teile von Strings abschneiden:

Code: Alles auswählen

          .data
test:     .asciiz "This is a test"
          .text
          li $t0, 7
          sb $zero, test($t0)
          li $v0, 4
          la $a0, test
          syscall
liefert "This is" auf der Konsole.



Aber alles ohne Gewähr - ich lerne Assembler auch zum ersten mal. :lol: