Program geht nicht wegen db



  • Hi, ich habe gerade ein unerklaerliches Problem:

    Erstmal der Code:

    .model tiny
    
    data segment
    
    filename db 'message.txt', '$'
    ;decode db 'message.dec', '$'
    buffer db ''
    
    data ends
    
    code segment
    assume cs:code,ds:data
    
    _start:
    
    push data
    pop ds
    
    OEFFNEN:
    mov ah, 3dh			;oeffnen
    xor al, al			;read
    mov dx, ds:[offset filename]
    int 21h
    
    mov bx, ax			;Dateihandle von ax in bx
    
    mov ah, 42h			;Set Filepointer
    xor cx, cx			;auf den Anfang der Datei
    int 21h
    
    LESEN:
    mov ah, 3fh			;Zeichen einlesen
    mov cx, 1h			;1 Zeichen einlesen
    mov dx, ds:[offset buffer]
    int 21h
    cmp ax, cx
    jne SCHLIESSEN
    
    mov ah, 02h					;1 Zeichen ausgeben
    mov dl, byte ptr ds:[offset buffer]	;aus dem buffer
    int 21h
    
    SCHLIESSEN:
    mov ah, 3eh			;schliessen
    int 21h
    
    ENDE:
    mov ah, 4ch			;Ende
    int 21h
    
    code ends
    END _start
    

    Soweit funktioniert dieser Code auch.
    Aber wie ihr ja in der Datensektion sehen koennt, ist da ein Kommentar.
    Sobald ich also noch einen weiteren String definiere, funktioniert der Code nicht mehr, er gibt nicht das gelesene Zeichen aus, wieso nicht?
    Ich verstehe es nicht.

    Kann man das eigentlich so machen mit dem buffer?
    Also ihn einfach als

    buffer db ''
    

    deklarieren?
    Ich will ja keine Daten am Anfang drinn haben, deshalb dachte ich, lasse ich ihn leer.
    Aber ich muss ihn dann immer am Ende deklarieren, oder? Er ist ja sozusagen offen und koennte nachfolgende Strings ueberschreiben, oder?
    Oder gibt es noch eine bessere Moeglichkeit?

    Thx wie immer im Voraus 🙂 .

    /e: Die Kommentare verbessert und noch eine Frage gestellt 😛 .



  • Hi.

    Dein Problem ist nicht direkt unerklaerlich (obwohl ich mich schon frage, warum es ueberhaupt beim Auskommentieren funktioniert - welchen Assembler benutzt du?), noch hat der auskommentierte Stringdamit etwas zu tun. Der Fehler liegt eher beim Terminierungszeichen fuer den Dateinamen.
    int 21h, Funktion erwartet in ds:dx einen Zeiger auf einen 0-terminierten String, dh. das byte nach dem Dateinamen muss den Wert 0 haben.

    Fuer die Zukunft kannst du dir daher merken: Nur int 21h, Funktion 9 erwartet einen mit "$" terminierten String (warum auch immer). Ansonsten wird meist ein 0-terminierter String erwartet.

    So, und nun zu deinem Code allgemein:

    XFame schrieb:

    .model tiny
    
    data segment
    
    filename db 'message.txt', 0 ; '$' <- 0 statt '$'
    decode db 'message.dec', 0
    ;buffer db '' ;scheint so zwar auch zu funktioniereb, besser waere es aber, einen festen Bereich zu reservieren - gibt schliesslich nicht unendlich viel Speicher:
    buffer db 16 dup (?) ;reserviert 16 byte freien Speicher - zumindest, wenn das Segment hinten ans Programm angefuegt wird. Kommen dahinter jedoch noch fixe Daten, fuellt der Assembler hier mit 0 auf.
    
    data ends
    
    code segment
    assume cs:code,ds:data
    
    _start:
    
    ;push data  ;nicht so gut.
    ;pop ds
    mov ax, data
    mov ds, ax
    
    OEFFNEN:
    ;ganz boese: 2mal direkt hintereinander an Teilen desselben Registers rumbasteln
    ;mov ah, 3dh			;oeffnen
    ;xor al, al			;read
    ;In einem Abwasch geht's nicht nur sehr viel eleganter, sondern auch schneller:
    mov ax, 3d00h
    
    ;Ich hasse den MASM und seinen laschen Umgang mit eckigen Klammern.
    ;Die sollten allgemein allein fuer Speicherzugriffe verwendet werden, und
    ;nicht, um ein offset zu holen.
    ;mov dx, ds:[offset filename]
    mov dx, offset filename
    int 21h
    ;Verwende assume, wenn du dich auf ein anderes Segment beziehen willst.
    
    mov bx, ax			;Dateihandle von ax in bx
    
    ;1. nicht noetig, da beim Oeffnen der Dateizeiger bereits zurueckgesetzt ist
    ;2. wuerde filename nicht zufaellig das offset 0 haben, wuerdest du hier
    ; hoechst wahrscheinlich sonstwo in der Datei landen, aber nicht am Anfang.
    ;mov ah, 42h			;Set Filepointer
    ;xor cx, cx			;auf den Anfang der Datei
    ;int 21h
    
    LESEN:
    mov ah, 3fh			;Zeichen einlesen
    mov cx, 1h			;1 Zeichen einlesen
    ;mov dx, ds:[offset buffer] ;schon wieder - so.
    mov dx, offset buffer
    int 21h
    cmp ax, cx
    jne SCHLIESSEN
    
    mov ah, 02h					;1 Zeichen ausgeben
    ;mov dl, byte ptr ds:[offset buffer]	;aus dem buffer
    ;darauf wollte ich oben hinaus - faellt dir eine Gewisse Aehnlichkeit auf?
    ;besser:
    mov dl, byte ptr ds:[buffer]
    int 21h
    
    SCHLIESSEN:
    mov ah, 3eh			;schliessen
    int 21h
    
    ENDE:
    mov ah, 4ch			;Ende
    int 21h
    
    code ends
    END _start
    

    Weiter:
    Du deklarierst das ganze als ".model tiny", benutzt aber mehrere feste Segmente (wiederspricht 1. AFAIK dem Model und 2. kannst du so hieraus keine .com-Datei mehr erstellen) und definierst auf der anderen Seite aber keinen Stack (wird fuer .exe-Dateien gebraucht).
    Also bitte fuer eins entscheiden.

    Hinweis auf die Schluesselwoerter ".data" und ".code". 🙂


  • Mod

    mov dl, byte ptr ds:[buffer]
    

    naja, sich über den umgang mit klammern von masm beschweren (ich hab das immer sehr nützlich gefunden, es erleichtert das schreiben von macros), aber dann etwas nicht weniger umständliches benutzen... 😉
    wenn

    mov dx, offset buffer
    

    ok ist, wird

    mov dl, buffer
    

    , bzw.

    mov dl, [buffer]
    

    (wenn du auf den unnötigen klammern bestehst) es wohl auch sein. wozu assume, wenn du dann doch mit overrides arbeitest.



  • *lol* Hey, ich hab' nur verschiedene Moeglichkeiten aufgezeigt und mal wieder die Gelegenheit genutzt, darauf hinzuweisen, dass MASM IMHO Mist ist. 😉



  • Hi, dan ke fuer die Antworten, aber ich habe noch ein paar Fragen *g* .

    Vorab, ich nutze TASM und nicht MASM .

    Wie ist das bei TASM mit den eckigen Klammern?
    Ich dachte, wenn ich auf ein anderes Segment zugreife, muss das in eckigen Klammern geschehen.
    Nun zu den Models: Wann muss ich einen Stack deklarieren und wann nicht? Ich finde dazu nichts in meinem Tutorial.
    Zum Buffer: Was genau heißt "dup" ? Also steckt da ein Wort hinter und wozu dieses Fragezeichen in Klammern?
    Wann nutze ich ".code", ".data" etc. und wann code segment, data segment?

    Kann mir einer noch das hier erklären?
    Warum lande ich irgendwo in der Datei und warum ist der Zeiger zurückgesetzt?

    ;1. nicht noetig, da beim Oeffnen der Dateizeiger bereits zurueckgesetzt ist 
    ;2. wuerde filename nicht zufaellig das offset 0 haben, wuerdest du hier 
    ; hoechst wahrscheinlich sonstwo in der Datei landen, aber nicht am Anfang. 
    ;mov ah, 42h            ;Set Filepointer 
    ;xor cx, cx            ;auf den Anfang der Datei 
    ;int 21h
    

    Zum Schluss noch das hier (wieder die eckigen Klammern):

    ;mov dl, byte ptr ds:[offset buffer]    ;aus dem buffer 
    ;darauf wollte ich oben hinaus - faellt dir eine Gewisse Aehnlichkeit auf? 
    ;besser: 
    mov dl, byte ptr ds:[buffer]
    

    Tut mir Leid für die vielen Fragen 😞 .



  • XFame_logged_out schrieb:

    Vorab, ich nutze TASM und nicht MASM .

    Tja, "ungluecklicherweise" 😉 unterstuetzt TASM auch die MASM-Syntax. Und was du da verwendest ist MASM-Syntax und nicht TASMs "Ideal"-Syntax.

    XFame_logged_out schrieb:

    Ich dachte, wenn ich auf ein anderes Segment zugreife, muss das in eckigen Klammern geschehen.

    Tja, schau dir das da oben doch mal an... Beim MASM ist das mit den Klammern eben Glueckssache 😃 - meistens kannst du sie weglassen, aber in seltenen Faellen muessen sie eben doch stehen -> ausprobieren, wann der Assembler meckert. :p Irgendwann hast du dich dann an einen gewissen "Style" im Umgang mit den Klammern gewoehnt.

    XFame_logged_out schrieb:

    Nun zu den Models: Wann muss ich einen Stack deklarieren und wann nicht?

    In .exe-Dateien solltest du einen Stack definieren - in .com-Dateien brauchst du das nicht.
    Praktisch funktioniert das in deinem Fall auch trotz Warnung als .exe-Datei ohne Stack, aber waeren deine Segmente Groesser, wuerde es da ein Durcheinander geben.

    XFame_logged_out schrieb:

    Zum Buffer: Was genau heißt "dup" ? Also steckt da ein Wort hinter und wozu dieses Fragezeichen in Klammern?

    dup(licate) - das Fragezeichen gibt an, dass in diesem Bereich undefinierte Daten liegen. Der Assembler merkt sich also nur die Adresse und Groesse des Datums, schreibt aber nichts rein.

    XFame_logged_out schrieb:

    Wann nutze ich ".code", ".data" etc. und wann code segment, data segment?

    ".code/codeseg)"/".data/dataseg" kannst du zusammen mit der (.)model-Direktive verwenden. Dann definiert es den Anfang eines Code-/Datensegments. Diese Direktiven muessen uebrigens nicht mit "ends" abgeschlossen werden. Weiterer Vorteil: Zusammen mit dem model tiny definieren diese Direktiven nicht wirklich neue Segmente, sondern eher neue Abschnitte des selben Segments - so kannst du .com-Dateien erstellen.
    Ohne .model-Direktive musst du "[name] segment" verwenden.

    XFame_logged_out schrieb:

    Warum lande ich irgendwo in der Datei und warum ist der Zeiger zurückgesetzt?

    ;1. nicht noetig, da beim Oeffnen der Dateizeiger bereits zurueckgesetzt ist 
    ;2. wuerde filename nicht zufaellig das offset 0 haben, wuerdest du hier 
    ; hoechst wahrscheinlich sonstwo in der Datei landen, aber nicht am Anfang. 
    ;mov ah, 42h            ;Set Filepointer 
    ;xor cx, cx            ;auf den Anfang der Datei 
    ;int 21h
    

    Wenn du eine Datei unter DOS neu oeffnest, wird der Dateizeiger AFAIK immer auf den Anfang der Datei gesetzt.

    Ralf Browns Interrupt Liste schrieb:

    DOS 2+ - LSEEK - SET CURRENT FILE POSITION
    AH = 42h
    AL = origin of move
    00h start of file
    01h current file position
    02h end of file
    BX = file handle
    CX:DX = (signed) offset from origin of new file position

    Nun sehe ich aber nirgendwo in deinem Code, dass du dx vor dem int 21h setzt, deshalb muesste dx hier noch den Wert des Offsets von "filename" haben => Sprung ins Blaue.

    XFame_logged_out schrieb:

    Zum Schluss noch das hier (wieder die eckigen Klammern):

    ;mov dl, byte ptr ds:[offset buffer]    ;aus dem buffer 
    ;darauf wollte ich oben hinaus - faellt dir eine Gewisse Aehnlichkeit auf? 
    ;besser: 
    mov dl, byte ptr ds:[buffer]
    

    Wie gesagt: mit MASM fuehren viele Wege nach Rom. 👎
    Darum: Aktiviere mit "ideal" TASMs IDEAL-Mode - der ist viel klarer und sowieso besser (IMHO). 😋 😉



  • Hey cool, danke 🙂 .

    Eine letzte Frage, wie aktiviere ich den IDEAL Mode?



  • Genauer lesen... 😕
    Steht doch schon da: Der IDEAL-Modus wird durch das Schluesselwort "IDEAL" aktiviert. Idealerweise (;)) schreibst du das also gleich als Erstes in deinen Code.



  • Nobuo T schrieb:

    Genauer lesen... 😕
    Steht doch schon da: Der IDEAL-Modus wird durch das Schluesselwort "IDEAL" aktiviert. Idealerweise

    Hehe ;), hätte ja auch sein können, das man vielleicht dem TASM-Assembler (Also dem "Compiler") den Parameter "IDEAL" oder so übergibt 😉 .

    Vielen dank, vor allem für deine Geduld :), hast mir sehr geholfen 🙂 .


Anmelden zum Antworten