Frage zu Beispiel Code aus Assembler Buch



  • Hallo ich habe mir letzdens ein Assembler Buch gekauft.

    Dort wird erklärt wie man Eingabe abfragen kann.

    Aner wofür ist das hier?

    mov bx,dx ;Offset nach bx f. später Und wieso ??
    add bx, 2 ; Wieso 2 ???

    Der Quelltext ist in dem Buch nur durch diese Kommentare erklärt.

    Ok add bx,2 ich kann mir jetzt einfach denken ja toll das ist halt so -.-

    Aber das ist ja nicht der Sinn ich will es ja verstehen.

    Gibt es irgendeine Referenz wo z.b. die Funktion mov ah,0ah genau erklärt wird ?

    Für die WIN API in C z.b. da gibt es ja die MSDN gibt es sowas auch für Assembler ?

    Ich benutze den TASM Assembler von Borland der wird auch in dem Buch benutzt.

    .MODEL Small    ;EXE Datei
             .STACK 100h     ;Stackgröße
             .DATA           ;Datensegment
    
    Msg1     DB  "Geben Sie den Text ein: $" 
    CR_LF    DB  10,13,"$"   
    
    Puffer   STRUC           ;Struktur f. Puffer
        Max  DB 50           ;Max. 50 Zeichen
        Anz  DB ?            ;Reserv. f. Anzahl
        Txt  DB 53 DUP (?)   ;3 mehr weil + CR-LF und $
    Puffer   ENDS            ;Ende Puffer
    Buffer   Puffer <>       ;Speicherplatz f. Puffer
    
             .CODE           ;Codesegmet
    Start:   
    
    	mov  ax,@data   ;DS initialisieren
            mov  ds,ax
    
            mov  dx,OFFSET Msg1
            mov  ah,09h
            int  21h        ;Msg1 ausgeben
    
    	mov  dx,OFFSET Buffer
            mov  ah,0Ah     
            int  21h        ;Text einlesen
    
      	mov  bx,dx      ;Offset nach bx f. später
    
    	add  bx, 2            ;bx auf Textanfang (+Max+Anz)
            add  bl,Buffer.Anz    ;bx auf Pufferende
    
             mov  word ptr [bx],0D0Ah ;CRLF ans Ende
    	 mov  byte ptr [bx+2],"$" ;$ ans Ende
    
    	mov  dx,OFFSET CR_LF
     	mov  ah,09h
            int  21h    
    
            mov  dx,OFFSET Buffer.Txt
     	mov  ah,09h
            int  21h        ;Eingeg. Text ausgeben
    
    	mov  ah,4Ch
            int  21h        ;Programm beenden!
    
             END  Start
    


  • In dx steht das offset des Eingabepuffers. Das wird in Zeile 31 nach dx kopiert und durch den interrupt-Aufruf nicht veraendert.
    Das wird nun nach bx kopiert, da ueber dx einfach kein Zugriff auf den Speicher moeglich ist. 2 wird zum Offset der Buffer struct addiert, um auf das Element Txt zu kommen (davor liegen 2 Byte).

    Eine Referenz der DOS-API gibt es zB. in Ralph Browns Interrupt List: http://www.ctyme.com/intr/int-21.htm (hat natuerlich genau so wenig Gueltigkeit fuer Assembler allgemein wie die MSDN fuer C ;)).



  • Hallo danke erst mal für den Link von der DOS API.

    Eine Frage habe ich noch.

    Teil 1:
    
    add  bx, 2            ;bx auf Textanfang (+Max+Anz)
    add  bl,Buffer.Anz    ;bx auf Pufferende
    
    Teil 2:
    
    mov  word ptr [bx],0D0Ah ;CRLF ans Ende
    mov  byte ptr [bx+2],"$" ;$ ans Ende
    

    In Teil 1 ist ja bx,2 ja der Anfang.

    Und in Teil 2 soll das hier das enden sein: mov word ptr [bx],0D0Ah
    Ist das dass ende weil das ganze hier im Little Endian abgespeichert wird oder wieso wird da jetzt auf einmal gesagt das da das ende von dem Buffer ist.

    Hier setzt man ja auch den Null Terminator an das Ende des Puffers:
    mov byte ptr [bx+2],"$"

    Das finde ich jetzt etwas verwirrend.

    Und nochmal kurz zu Teil 1

    add bl,Buffer.Anz ;bx auf Pufferende <-- Wieso steht da bx auf Pufferende ?

    Man Addiert zu dem bl register doch den Buffer.Anz



  • Mit der Bytereihenfolge hat das nichts zu tun. bx ist im Prinzip eine Variable und entsprechend kann bx+2, je nachdem was in bx steht, auch auf unterschiedliche Adressen zeigen.
    Nach der Addition von 2 zeigt bx in Zeile 39 auf den Pufferanfang, bzw. das erste eingelesene Zeichen.
    In Zeile 40 wird dann die Anzahl der eingelesenen Zeichen auf bl addiert, wobei bl die unteren 8 bit von bx darstellt. Siehe EAX ... AX
    Hier ist natuerlich darauf zu achten, dass kein Ueberlauf auftritt.
    Damit zeigt bx also nach Zeile 40 auf das Ende des eingelesenen Strings, bzw. das letzte Zeichen + 1. Das wird hier "Pufferende" genannt. Kann man IMHO so sagen, auch wenn es offensichtlich missverstaendlich ist.

    Btw ist "$" nicht Null. 😉



  • Das hört sich auch sehr Missverständlich an. ^^

    Also bx + 2 = Anfang bzw. erstes eingelesenes Zeichen..

    bx = Ende ?

    Gibt es vielleicht irgendwo so Grafiken wo man mal sehen kann wie sich das ganze so im Speicher bewegt ?

    Oder wie kann ich eine TASM Anwendung Debuggen ich hab das mal mit dem OllyDebugger probiert aber der kann leider nur 32 Bit Anwendungen Debugge 😞

    Und der Windows Debugger ( debug Befehl in cmd ) da sieht man ja net so viel wie in Olly z.b. ...



  • Alternative wäre GNU gdb...



  • Wie gesagt: bx ist quasi eine Variable.
    Falls dir das Prinzip einer Variable in Mathematik oder Informatik nicht ganz klar sein sollte, mach dir nochmal klar, dass eine wesentliche Eigenschaft einer Variablen ist, dass sie einen beliebigen Wert aus einem bestimmten Wertebereich annehmen kann.
    Du kannst deshalb in aller Regel nicht einfach pauschal sagen "bx + 2 = Anfang" oder "bx = Ende", sondern musst jeweils unterscheiden, was fuer einen Wert diese "Variable" bx aktuell an einer bestimmten Stelle im Programm hat, bzw. wie sie im vorangegangenen Programmverlauf veraendert wurde.

    zB. nochmal:
    In Zeile 36 ist bx = das Offset des struct "Puffer" (in Zeile 35 aus dx kopiert)
    In Zeile 40 ist bx zunaechst das Offset des struct + 2 (zu bx wird in Zeile 39 2 addiert).
    In Zeile 41 ist bx = offset Puffer + 2 + Puffer.Anz (zu bl und damit zu bx wird in Zeile 40 Puffer.Anz addiert)

    TASM bringt den Turbo Debugger (td.exe fuer 16Bit DOS) mit. Der funktioniert fuer 16-32Bit Anwendungen fuer DOS, DPMI und Windows und bringt eine sehr uebersichtliche und praktische GUI mit. IMHO wesentlich komfortabler zum Debuggen als der nackte gdb.



  • Bei DS:DX steht nach Int 21 Funktion 0A und einem Speicherdump mit debug u.a.:

    32??tollerEingabetext0D0000000usw.

    Sowohl beiden Bytes für Max und Anz(abhängig von der Anzahl eingegebener Zeichen) als auch die eingegebene Zeichenkette müssen übersprungen werden, um den Zeilenumbruch + $ (in Hex 0D0A24) für die Funktion 09 an das Ende der eingegebenen Zeichenkette zu kleben. Ohne $ findet Funktion 09 das Ende der Zeichenkette nich.

    p.s.:0D0A24h läßt sich nicht per Hexeditor nachträglich ankleben, weil die tatsächlich eingegebene Anzahl der Buchstaben nicht bekannt ist.
    p.p.s: lea bx,Buffer.Txt
    add bl,Buffer.Anz
    würde zum Endeanpeilen reichen, hier geht es wohl in erster Linie um den Anschauungseffekt.
    Aber aus welchem Assemblerbuch? Keine Interrupts erklärt??
    p.p.p.s.: debug erklärt solcherlei Fragen wirklich super. 😉



  • Ich hab noch eine Frage^^

    anstatt :

    1.Möglichkeit
    mov word ptr [bx],0d0ah
    mov byte ptr [bx+2],"$"

    Kann man ja auch schreiben:

    2.Möglichkeit
    mov [bx] , 0d0ah
    mov [bx+2],"$"

    Hat die 2. Möglichkeit irgendwelche Nachteile im gegensatz zur 2ten ?

    .MODEL Small   
             .STACK 100h   
             .DATA     
    
    Msg1     DB  "Geben Sie den Text ein: $" 
    
    CR_LF    DB  10,13,"$"  
    
    Puffer   STRUC           
        Max  DB 4        
        Anz  DB ?         
        Txt  DB 53 DUP (?)  
    Puffer   ENDS   
    
    Buffer   Puffer <>      
    
             .CODE           
    Start:   mov  ax,@data   
             mov  ds,ax
    
             mov  dx,OFFSET Msg1 
    		 mov  ah,09h
             int  21h   
    
    	mov  dx,OFFSET Buffer
    	mov  ah,0ah     
            int  21h    
    
            mov  bx,dx 
    
    	mov  dx,OFFSET CR_LF
            mov  ah,09h
            int  21h       
    
    	add  bx,2
    
            add  bl,Buffer.Anz 
    
    	mov  [bx] , 0d0ah
    	mov   [bx+2],"$" 
    
            mov  dx,OFFSET Buffer.Txt
    
    	mov  ah,09h
            int  21h       
    
      	 mov  ah,4Ch
             int  21h        
    
             END  Start
    


  • Zuerst eine Gegenfrage :
    Was ist denn das für ein Assemblerbuch, welches dich hier scheinbar NICHT über diese grundlegenden Unterschiede aufklärt?



  • Und welchen Editor benutzt Du? Warum ist alles so schief eingerückt 😕


Anmelden zum Antworten