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:

    1. 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.

    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^^)

    ;****************************
    ;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:

    1. 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.

    2. 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:

    1. ".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.

    2. "include macros.mac" kannst Du weglassen, weil Du in diesem Programm keine Makros benutzt. Es verwirrt nur den geneigten Leser.

    3. "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
    ralph

    Und 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.


Anmelden zum Antworten