2016-05-05 15 views
0

Ich muss eine bestimmte Anzahl von Zeichen (sagen wir 3) vom Ende einer Zeichenkette entfernen. Für diesen speziellen String funktioniert es, wenn ich 'Z' finde, und dann zeige ich es auf W by sub edi, 3, und speichere dann den Rest der Zeichenkette mit Nullen.Wie kann man Zeichen vom Ende eines Strings entfernen?

INCLUDE Irvine32.inc 

.data 
source BYTE "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 

.code 
main PROC 

mov edi, OFFSET source 
mov al, 'Z'     ; search for Z 
mov ecx, LENGTHOF source 
cld 
repne scasb  ; repeat while not equal 
sub edi, 3   ; now points to W 

mov al, 0   
rep stosb  ; stores all characters after W with 0. 

mov edx, OFFSET source 
call WriteString 
call CrlF 

exit 
main ENDP 
end main 

Allerdings möchte ich diesen Code mit verschiedenen null abgeschlossene Zeichenfolgen arbeiten lassen. Zu diesem Zweck habe ich versucht, 0 (das Ende der Zeichenfolge) zu finden, wie mein Code unten zeigt. Aber es funktioniert nicht, Es gibt nur die ganze Zeichenfolge aus.

Was muss ich tun, um sicherzustellen, dass der Code auch dann noch funktioniert, wenn die Zeichenfolge geändert wird, ohne dass jedes Mal die Suche nach dem Ende der Zeichenfolge geändert werden muss?

INCLUDE Irvine32.inc 

.data 
source BYTE "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 

.code 
main PROC 

mov edi, OFFSET source 
mov al, '0'     ; search for end of string 
mov ecx, LENGTHOF source 
cld 
repne scasb  ; repeat while not equal 
sub edi, 3   ; now points to W ?? 

mov al, 0   
rep stosb  ; stores all characters after W with 0. 

mov edx, OFFSET source 
call WriteString 
call CrlF 

exit 
main ENDP 
end main 
+3

Sie brauchen nicht mit Nullen zu füllen, die Sie gerade brauchen. Zur Kompilierung von konstanten Strings können Sie einfach 'LENGTHOF' verwenden, da Sie keine Suche durchführen müssen. Beachten Sie auch, dass "0" der ASCII-Code von "0" ist, der nicht "0", sondern "48" ist, also ist das nicht das, was Sie wollen. – Jester

+0

Mindestens einer Ihrer drei Versuche, diese Frage zu beantworten, wurde nicht geschlossen. :) –

+0

Mein Vergnügen. Es scheint, dass dieses eine mehr genau widerspiegelt, was das "wie man eine Frage stellt" Wiki sagt, um zu tun. –

Antwort

2

Der Fehler ist, dass Sie ECX mit keinem Wert zurücksetzen.

Sie setzten ECX auf die Länge der Daten, in diesem Fall 27. Sie dann Z finden, die der 26. Wert ist, so dass am Ende ECX Wert haben wird 1 und Ihre rep stosb wird eine 0 im String schreiben. Dann drucken Sie es und das erste Nul wird aufhören zu drucken. In der zweiten suchen Sie nach 0 welches das letzte Byte ist. Das Verlassen der repne scasbECX ist Null, also schreibt rep stosb nichts.

dies beheben Sie

mov edi, OFFSET source 
mov al, 0     ; search for end of string 
mov ecx, LENGTHOF source 
cld 
repne scasb  ; repeat while not equal 
sub edi, 3   ; now points to W ?? 

mov byte ptr [edi], 0  ; store a single nul since that's enough 

Sie beachten Sie, dass in den ersten ein „speichert alle Zeichen nach W mit 0“ ist nicht wahr, nutzen können. Sie müssten dazu ADD ECX, 3 nach SUB EDI, 3 tun.

Zu beachten ist außerdem, dass '0' ist das Zeichen 0, nicht der Wert 0

+0

Für den zweiten Teil, der das Mov al ersetzt, 0 mit mov edi, druckt 0 immer noch den ganzen String aus. – kc9552

+1

@JoeDoe Es ist 'MOV [EDI], 0', nicht' MOV EDI, 0'. Eigentlich sollte es auch die Datengröße geben. Also 'MOV BYTE PTR [EDI], 0 ', also speichert es die Nullstelle in den Speicher, auf den" EDI "zeigt, nicht auf" EDI ". –

+0

Es funktioniert jetzt. Vielen Dank. Danke für die Erklärung in Ihrer Antwort auch. – kc9552