Länge eines Strings (db) erfahren, wie?
-
supernicky2 schrieb:
Hallo,
Windows verwendet überlicherweise einen Null-terminierten String
text db "supernicky",0
DOS das "$" Zeichen als Ende.
Du brauchst nur den String byteweise von vorn einlesen (bis zum NULL-Zeichen)
und mitzählen.Nicky
jo, die einzelnen elemente heraus gelesen bis er eine 0 gelesen hat.
Habe jedes Element einzeln gelesen, mit der Index-Adressierung (müsste das heißen). Dann habe ich das sofort gepushed. Dann den nächsten, ebenfalls gepushed. Das ganze solange bis er eine 0 gelesen hat.Dann habe ich ihn solange poppen lassen, wieviele Elemente der am Anfang gelesen hat. Und dann habe ich das ganze Rückwärts^^
Irgendwie ist das erste Zeichen was ausgegeben wird irgendwie ein Sonderzeichen, muss schauen warum das so ist :S
-
Es klappt.
Aber zwei Probleme:-
wenn ich start_txt mit hineinnehme, nimmt er den Text auch mit. Also reversed er eben auch, warum? ich habe doch nur "palin" unten reversen lassen. Warum wird er auch reversed ^^ Momentan ist ein ; vor start_txt - aber wenn ihr das mal weglässt, dann seht ihr das.
-
bei der ausgabe gibts janz vorne ein sonderzeichen - weshalb kann das sein?
(ich glaub ich weiß warum, fällt mir gerade eben so ein^^)
;**************************** ;Verfasser: BunterVogel ;Aufgabe: ;**************************** .model small .stack 100h .data palin db "Juhu, der Code klappt!",0 ; start_txt db "Palindrom wird gestartet",0 i dw 0 ; Anzahl der Elemente im Satz include macros.mac JUMPS .code start: mov ax,@data mov ds,ax again: mov di,i ; i wird in di-Reg. geschrieben mov ah,palin3[di] ; ah, bekommt den i.ten Wert von di cmp ah,0 ; wenn ah 0 ist, also der Satz zu Ende ist je ende2 ; dann ist sense, i soll NICHT mehr +1 werden! add i,1 ; wenn das aber nicht der Fall ist, also das letzte Elemen ; also das letzte Element nicht erreicht ist push ax ; dann i+1 und pushe ax jmp again ; gehe zu again ende2: ;Ausgabe mov cx,i ; cx bekommt i-Wert (Dient für Anzahl der Wiederholung des Poppens) xor bx,bx ; bx = 0 loopstart: mov bx,ax ; bx bekommt ax (sicherung von ax) pop ax ; ax wird gepoppt mov dl,ah ; dl bekommt ah mov ah,2h ; Ausgabe (ah-Wert wird manipuliert) int 21h mov ax,bx ; ax wird wiederhergestellt loop loopstart ende: mov ax, 04c00h int 21h end start
-
-
Zu meiner Frage:
"2) bei der ausgabe gibts janz vorne ein sonderzeichen - weshalb kann das sein?
(ich glaub ich weiß warum, fällt mir gerade eben so ein^^) "Hab den Fehler jetzt umgangen. Jedoch frage ich mich warum der am Ende des Strings einen andren Zeichen abließt.
Er übersetzt Quasi Haus_ -> _Haus Obwohl da kein _ ist^^
Bei anderen Sätzen und Worten sind andere Sonderzeichen da
-
So wie "Nachtfeuer" es schon geschrieben hat ist die Methode mit dem aktuellen Programmcounter "$" am einfachsten umzusetzen.
Hier ein Beispiel zur Verwendung:Satz db "Das ist ein Satz" SLen = ($-Satz) mov bx, Satz mov di, SLen mov ah, 2 P1: mov dl, [bx+di] int 21h dec di jnz P1
Dirk
-
Huch, es hat sich ein kleiner Fehler eingeschlichen.
Satz db "Das ist ein Satz"
SLen = ($-Satz)mov bx, Satz
mov di, SLen
mov ah, 2
P1:
mov dl, [bx+di]
int 21h
dec di<--- Hier fehlt noch ein "cmp di,-1"
jnz P1
Dirk
-
BunterVogel schrieb:
Es klappt.
Aber zwei Probleme:-
wenn ich start_txt mit hineinnehme, nimmt er den Text auch mit. Also reversed er eben auch, warum? ich habe doch nur "palin" unten reversen lassen. Warum wird er auch reversed ^^ Momentan ist ein ; vor start_txt - aber wenn ihr das mal weglässt, dann seht ihr das.
-
bei der ausgabe gibts janz vorne ein sonderzeichen - weshalb kann das sein?
;**************************** ;Verfasser: BunterVogel ;Aufgabe: ;**************************** .model small .stack 100h .data palin db "Juhu, der Code klappt!",0 ; start_txt db "Palindrom wird gestartet",0 i dw 0 ; Anzahl der Elemente im Satz include macros.mac JUMPS .code start: mov ax,@data mov ds,ax again: mov di,i ; i wird in di-Reg. geschrieben mov ah,palin3[di] ; ah, bekommt den i.ten Wert von di ...
Der Code funktioniert, wenn man in Zeile 29 aus "palin3" ein "palin" macht. Bei mir wird auch start_txt nicht mitgenommen und es gibt auch keine Sonderzeichen am Anfang.
Drei Tipps:
-
".stack 100h" ist ein bisschen klein, insbesondere wenn Du intensiv mit dem Stack arbeitest. Eventuell haben Deine Sonderzeichen mit einem Stacküberlauf zu tun. ".stack 8000h" tut keinem weh.
-
"include macros.mac" kannst Du weglassen, weil Du in diesem Programm keine Makros benutzt. Es verwirrt nur den geneigten Leser.
-
"JUMPS" verändert Dir unter Umständen Deinen Sprung und verändert das Laufzeitverhalten. Lasse es weg. Wenn Du einen Fehler bekommst, dass die Sprungadresse nicht erreichbar ist, kannst Du Dir immer noch überlegen, ob Du mit JUMPS den Assembler einen Workaround basteln lässt, oder die Programmlogik verbesserst.
viele grüße
ralph
-
-
Vielen Dank!
-
Ich habe die Veränderungen mal vorgenommen, aber da besteht immer noch ein Problem:
;**************************** ;Verfasser: H.A.I (BunterVogel) ;Aufgabe: ;**************************** .model small .stack 8000h include macros.mac .data palin db "Ein Esel lese nie",0 startmsg db "Palindrom wird gestartet",0 i dw 0 .code start: writes startmsg xor dx,dx xor ax,ax mov ax,@data ;Datensegment laden (DS-Register) mov ds,ax again: ;STACK segment zuweisen ;DI REGISTER cmp ah,0 je ende2 mov di,i mov ah,palin[di] add i,1 push ax jmp again ende2: ;Ausgabe sub i,1 mov cx,i xor bx,bx pop ax loopstart: mov bx,ax pop ax mov dl,ah mov ah,2h int 21h mov ax,bx loop loopstart ende: mov ax, 04c00h int 21h end start
Wenn ich
include macros.mac
herausnehme gibt'sn Fehler.
Wenn ich es drinnn lasse, startet es das Programm zwar, jedoch kommt da ein Durcheinander dabei raus..
-
BunterVogel schrieb:
Wenn ich
include macros.mac
herausnehme gibt'sn Fehler.
Da Du das Makro 'writes' benutzt, brauchst Du auch die macros.mac.
Tipp: Einen Zeilenvorschub bekommst Du mit '13,10', also: '*
startmsg db "Palindrom wird gestartet",13,10,0
*'.Wenn ich es drinnn lasse, startet es das Programm zwar, jedoch kommt da ein Durcheinander dabei raus..
Wenn das Programm geladen wird, zeigt das DS-Register nicht auf .DATA. Um an die Daten in .DATA zu kommen, muss als allererstes das DS-Register initialisiert werden:
mov ax, @data mov ds, ax
Erst danach kann ein Zugriff wie 'writes startmsg' klappen. Verschiebe also Zeile 21 nach Zeile 30 (bzw. hinter Zeile 29). Zeile 24 und 25 sind überflüssig, entferne sie.
viele grüße
ralph
-
rkhb schrieb:
mov ax, @data mov ds, ax
Erst danach kann ein Zugriff wie 'writes startmsg' klappen. Verschiebe also Zeile 21 nach Zeile 30 (bzw. hinter Zeile 29). Zeile 24 und 25 sind überflüssig, entferne sie.
viele grüße
ralphUnd bei genauer Betrachtung ist das sowieso ziemlicher Quatsch, das so handzuhaben, ein einziges Segment reicht völlig weil dieser Punkt eher verwirrend ist für Anfänger und man irgendwo später auch lernen sollte, wie man das eh von Hand macht und das ganze unter Windows erst recht total egal ist.
Und ehrlich gesagt ist mir noch nicht mal klar, wieso das Macrobenutzen bei dieser Art von Aufgaben sinnvoll sein soll. Stiftet nur noch mehr unnötige Fehlersuche und hält so das Lernen unnötig auf.