Ausgabe



  • Wieso werden Strings mit mov dx,offset FOO ausgegeben? wieso mit DX und nicht z.b AX?



  • ganz einfach, weil in AX meistens die Funktionsnummer angegeben wird.
    außerdem ist DX das Datenregister (NICHT Datensegmentregister)

    cu todo



  • Ich habe eine einfache Addition. Das Ergbenis steht in AX. Wie bekomme ich das Ergenis jetzt auf den Monitor?
    Wie man konstante Zeichenketen ausgibt weiß ich. Und wie kann ich vor und hinter dem Ergenis noch Text ausgeben?



  • du meinst ergebnis nach dem text anzeigen oder was??? da gibts fertige algorithmen, hab aber gerade keinen zur hand... das prinzip ist, dasss du die zahl die du anzeigen willst, immer durch 10 dividierst und den rest (steht in DL/DX (kommt auf die "bittigkeit" der division an)) als index für ein array nimmst, in dem die zahlen von 0...9 (als ascii-zeichen, also DB "0", "1" usw., kann man unter DOS mit Fkt. 3h (zeichen ausgeben) realisieren)



  • OK. Beschränken wir uns erstmal auf Frage eins. Es muß doch möglich sein das Ergbnis einer Addition einfach auf dem Monitor auszugeben.



  • Dieses Programm ist von meinem Dozenten, es sorgt für eine Dezimalzahlenausgabe:

    DEZI  PROC
          PUSH AX
          PUSH BX
          PUSH CX
          PUSH DX
          MOV  BX,10
          MOV  CX,0
    DIVI: INC  CX
          MOV  DX,0
          DIV  BX
          PUSH DX
          CMP  AX,0
          JNE  DIVI
          MOV  AH,2
    DIGIT:POP  DX
          ADD  DL,'0'
          INT  21h
          LOOP DIGIT
          POP  DX
          POP  CX
          POP  BX
          POP  AX
          RET
    DEZI  ENDP
    

    Natürlich ohne die ";"

    Code-Hacker



  • Hm, ich fange gerade erst mit ASM an. Wo müßte denn hier dein Code hin:

    ;@goto build 
    
    code segment 
    Start: 
      mov  ax, 5
      add  ax, 2 
      ; hier soll die Ausgabe erfolgen
      mov  ax, 4C00h 
      int  21h
    code ends 
    
    end Start 
    
    :build 
    @echo off 
    set PATH=C:\Programme\TASM\BIN;%PATH%
    tasm /m3 /ml /q /t /w2 /z build.bat, %1.obj 
    tlink /c /k /Tde /x %1.obj, %1.exe 
    del %1.obj 
    %1.exe 
    pause
    


  • ;@goto build  
    
    code segment  
    Start:  
      mov  ax, 5 
      add  ax, 2  
      call DEZI ; hier soll die Ausgabe erfolgen 
      mov  ax, 4C00h  
      int  21h 
    code ends
    
    DEZI  PROC 
          PUSH AX 
          PUSH BX 
          PUSH CX 
          PUSH DX 
          MOV  BX,10 
          MOV  CX,0 
    DIVI: INC  CX 
          MOV  DX,0 
          DIV  BX 
          PUSH DX 
          CMP  AX,0 
          JNE  DIVI 
          MOV  AH,2 
    DIGIT:POP  DX 
          ADD  DL,'0' 
          INT  21h 
          LOOP DIGIT 
          POP  DX 
          POP  CX 
          POP  BX 
          POP  AX 
          RET 
    DEZI  ENDP  
    
    end Start  
    
    :build  
    @echo off  
    set PATH=C:\Programme\TASM\BIN;%PATH% 
    tasm /m3 /ml /q /t /w2 /z build.bat, %1.obj  
    tlink /c /k /Tde /x %1.obj, %1.exe  
    del %1.obj  
    %1.exe  
    pause
    

    Habe den Code einfach reingepackt und per Call aufgerufen. Dort gibt er dein Ergebnis aus. Das ergebnis muss vor Prozeduraufruf im AX-Register liegen, aber das ist bei dir ja bereits der Fall.

    Achja, vllt solltest du den Pfad in der Systemsteurung festlegen, dann brauchst du es nicht in deinem Programm machen.

    Ausgabe von Text, Beispiel:

    DOSSEG
    .MODEL SMALL           
    .STACK 250
    
    .DATA
     text DB "Hallo Welt","$"
     eingabe DB 30
             DB ?    
             DB 30 DUP (?)
    
    .CODE
    Anfang:
     MOV AX,@DATA
     MOV DS,AX
    
     MOV AH,09h
     MOV DX,OFFSET text
     INT 21h
     MOV AX,4C00h
     INT 21h
    
    END Anfang ;Hier wird der Einstiegspunkt der Anweisung festgelegt.
    

    Wichtig, eigentlich der DOS-Funktionscode 9, zur Zeichenkettenausgabe und natürlich das Laden des Datensegments.

    Code-Hacker



  • Hast du das mal assembliert und gelinkt? Ich bekomme mit meinem Turbo Assembler 4.1 diese Fehler:

    **Error** build.bat(7) Undefined symbol: DEZI
    PUSH AX
    **Error** build.bat(13) Code or data emission to undeclared segment
    PUSH BX
    **Error** build.bat(14) Code or data emission to undeclared segment
    PUSH CX
    **Error** build.bat(15) Code or data emission to undeclared segment
    PUSH DX
    **Error** build.bat(16) Code or data emission to undeclared segment
    MOV BX,10
    **Error** build.bat(17) Code or data emission to undeclared segment
    MOV CX,0
    **Error** build.bat(18) Code or data emission to undeclared segment
    DIVI: INC CX
    **Error** build.bat(19) Code or data emission to undeclared segment
    MOV DX,0
    **Error** build.bat(20) Code or data emission to undeclared segment
    DIV BX
    **Error** build.bat(21) Code or data emission to undeclared segment
    PUSH DX
    **Error** build.bat(22) Code or data emission to undeclared segment
    CMP AX,0
    **Error** build.bat(23) Code or data emission to undeclared segment
    JNE DIVI
    **Error** build.bat(24) Undefined symbol: DIVI
    MOV AH,2
    **Error** build.bat(25) Code or data emission to undeclared segment
    DIGIT:POP DX
    **Error** build.bat(26) Code or data emission to undeclared segment
    ADD DL,'0'
    **Error** build.bat(27) Code or data emission to undeclared segment
    INT 21h
    **Error** build.bat(28) Code or data emission to undeclared segment
    LOOP DIGIT
    **Error** build.bat(29) Undefined symbol: DIGIT
    POP DX
    **Error** build.bat(30) Code or data emission to undeclared segment
    POP CX
    **Error** build.bat(31) Code or data emission to undeclared segment
    POP BX
    **Error** build.bat(32) Code or data emission to undeclared segment
    POP AX
    **Error** build.bat(33) Code or data emission to undeclared segment
    RET
    **Error** build.bat(34) Code or data emission to undeclared segment

    Ich habe mal die Semikola rausgenommen. Aber auch mit bekomme ich diese und noch andere Fehlermeldungen. Ich bin ziemlich rat- und hilflos im Moment.

    Und bei deinem zweiten Code bekomme ich:
    MOV AX,@DATA
    **Error** build.bat(18) Undefined symbol: @DATA

    allerdings das:

    ;Template und build.bat für TASM
    
    ;@goto build 
    
    data segment 
      Hello db "Hello, World!", 0Dh, 0Ah, "$" 
    data ends 
    
    code segment 
    Start: 
      mov     ax, seg Hello 
      mov     ds, ax 
      mov     dx, offset Hello 
      mov     ah, 09h 
      int     21h 
      mov     ax, 4C00h 
      int     21h 
    code ends 
    
    end Start 
    
    :build 
    @echo off 
    set PATH=C:\Programme\TASM\BIN;%PATH%
    tasm /m3 /ml /q /t /w2 /z build.bat, %1.obj 
    tlink /c /k /Tde /x %1.obj, %1.exe 
    del %1.obj 
    %1.exe 
    pause
    

    funktioniert bei mir.



  • Klar habe ich den Code schon assembliert, da ich die Prozedur für ne Übung und auch so schon mal brauchte.
    Nebenbei kannst du das Datensegment nicht als Data bezeichnen da Data reserviert ist und hinter Segment eingesetzt werden kann bei machen Assemblern sogar muss, versuch mal folgendes:

    ;@goto build   
    
    DSEG segment
          Hello db "Hello, World!", 0Dh, 0Ah, "$"  
    DSEG ends
    
    SSEG Segment  ;hinter Segment eventuell noch folgendes hinschreiben: 'Stack'
         dw 128 dup(?)  ;265 Byte für den stack reservieren, ohne initiaisierung
    SSEG ends
    
    code segment   
         assume CS:Code,DS:DSEG ;hier evtl. noch durch ein komma getrennt folgendes schreiben: SS:SSEG
    Start:
      mov  ax,DSEG
      mov  ds,ax
      mov  dx,offset Hello
      mov  ah,09h
      int  21h
      mov  ax, 5  
      add  ax, 2   
      call DEZI ; hier soll die Ausgabe erfolgen  
      mov  ax, 4C00h   
      int  21h  
    code ends 
    
    DEZI  PROC  
          PUSH AX  
          PUSH BX  
          PUSH CX  
          PUSH DX  
          MOV  BX,10  
          MOV  CX,0  
    DIVI: INC  CX  
          MOV  DX,0  
          DIV  BX  
          PUSH DX  
          CMP  AX,0  
          JNE  DIVI  
          MOV  AH,2  
    DIGIT:POP  DX  
          ADD  DL,'0'  
          INT  21h  
          LOOP DIGIT  
          POP  DX  
          POP  CX  
          POP  BX  
          POP  AX  
          RET  
    DEZI  ENDP   
    
    Code ends
         end Start
    
    :build   
    @echo off   
    set PATH=C:\Programme\TASM\BIN%PATH%  
    tasm /m3 /ml /q /t /w2 /z build.bat, %1.obj   
    tlink /c /k /Tde /x %1.obj, %1.exe   
    del %1.obj   
    %1.exe   
    pause
    

    Also alle ";" Wo kein Text von mir hinter steht, raus!
    Ich denke so sollte es funktionieren. Nebenbei habe ich dir einen Stacksegment reingepackt, dies ist reservierter Speicher auf dem du daten ablegen und wieder runterholen kannst, nach dem 'Last In - First out' verfahren. Wenn es immer noch nicht klappen sollte solltest du evtl. mal an die Stelle wo der Call stattfindet die Prozedur DEZI einbauen, natürlich OHNE: DEZI PROC und DEZI ENDP.

    Code-Hacker



  • Ich werde noch mal irre. Vorher mit deinem neuen Code:
    assume CS:Code,DS:DSEG ;hier evtl. noch durch ein komma getrenn
    schreiben: SS:SSEG
    **Error** build.bat(12) Undefined symbol: Code
    call DEZI ; hier soll die Ausgabe erfolgen
    **Error** build.bat(21) Undefined symbol: DEZI
    PUSH AX
    **Error** build.bat(27) Code or data emission to undeclared segment
    PUSH BX
    **Error** build.bat(28) Code or data emission to undeclared segment
    PUSH CX
    **Error** build.bat(29) Code or data emission to undeclared segment
    PUSH DX
    **Error** build.bat(30) Code or data emission to undeclared segment
    MOV BX,10
    **Error** build.bat(31) Code or data emission to undeclared segment
    MOV CX,0
    **Error** build.bat(32) Code or data emission to undeclared segment
    DIVI: INC CX
    **Error** build.bat(33) Code or data emission to undeclared segment
    MOV DX,0
    **Error** build.bat(34) Code or data emission to undeclared segment
    DIV BX
    **Error** build.bat(35) Code or data emission to undeclared segment
    PUSH DX
    **Error** build.bat(36) Code or data emission to undeclared segment
    CMP AX,0
    **Error** build.bat(37) Code or data emission to undeclared segment
    JNE DIVI
    **Error** build.bat(38) Undefined symbol: DIVI
    MOV AH,2
    **Error** build.bat(39) Code or data emission to undeclared segment
    DIGIT:POP DX
    **Error** build.bat(40) Code or data emission to undeclared segment
    ADD DL,';0'
    **Error** build.bat(41) Constant too large
    INT 21h
    **Error** build.bat(42) Code or data emission to undeclared segment
    LOOP DIGIT
    **Error** build.bat(43) Undefined symbol: DIGIT
    POP DX
    **Error** build.bat(44) Code or data emission to undeclared segment
    POP CX
    **Error** build.bat(45) Code or data emission to undeclared segment
    POP BX
    **Error** build.bat(46) Code or data emission to undeclared segment
    POP AX
    **Error** build.bat(47) Code or data emission to undeclared segment
    RET
    **Error** build.bat(48) Code or data emission to undeclared segment
    Code ends
    Dann so geändert:

    ;@goto build 
    
    DSEG segment 
          Hello db "Hello, World!", 0Dh, 0Ah, "$"   
    DSEG ends 
    
    SSEG Segment  ;hinter Segment eventuell noch folgendes hinschreiben: 'Stack' 
         dw 128 dup(?)  ;265 Byte für den stack reservieren, ohne initiaisierung 
    SSEG ends 
    
    code segment    
         assume CS:Code,DS:DSEG ;hier evtl. noch durch ein komma getrennt folgendes schreiben: SS:SSEG 
    Start:
      mov  ax,DSEG 
      mov  ds,ax 
      mov  dx,offset Hello 
      mov  ah,09h 
      int  21h 
      mov  ax, 5   
      add  ax, 2    
      ;call DEZI ; hier soll die Ausgabe erfolgen   
          PUSH AX   
          PUSH BX   
          PUSH CX   
          PUSH DX   
          MOV  BX,10   
          MOV  CX,0   
    DIVI: INC  CX   
          MOV  DX,0   
          DIV  BX   
          PUSH DX   
          CMP  AX,0   
          JNE  DIVI   
          MOV  AH,2   
    DIGIT:POP  DX   
          ADD  DL,'0'   
          INT  21h   
          LOOP DIGIT   
          POP  DX   
          POP  CX   
          POP  BX   
          POP  AX   
          RET   
      mov  ax, 4C00h    
      int  21h   
    code ends  
    
    Code ends 
         end Start 
    
    ;:build 
    @echo off 
    set PATH=C:\Programme\TASM\BIN;%PATH%
    tasm /m3 /ml /q /t /w2 /z build.bat, %1.obj 
    tlink /c /k /Tde /x %1.obj, %1.exe 
    del %1.obj 
    %1.exe 
    pause
    

    Bekomme ich imme rnoch drei Fehlermeldungen:
    assume CS:Code,DS:DSEG ;hier evtl. noch du
    schreiben: SS:SSEG
    **Error** build.bat(12) Undefined symbol: Code
    JNE DIVI
    **Error** build.bat(33) Undefined symbol: Code
    ADD DL,';0'
    **Error** build.bat(36) Constant too large
    LOOP DIGIT
    **Error** build.bat(38) Undefined symbol: Code
    Code ends

    aber dank dir schon mal für deine bisherige Hilfe. Allerdings kann ich immer noch kein Ende absehen. 😞

    Falls es wichtig ist: Turbo Assembler Version 4.1 und Turbo Link Version 7.1.30.1.



  • Komisch, aber wie gesagt, er müsste meinen code so wie ich ihn gepostet habe eigentlich auch nehmen. MASM und TASM unterscheiden sich fast gar nicht. Wenn nötig muss man kleine Anpassungen machen, das war es aber auch schon.

    Aber ich habe eben nochmal bei MASM geguckt, dort musste ich noch einen weiteren Pfad bei Path angeben. Selbiger Pfad, allerdings statt BIN -> BINR. guck mal ob es das bei dir auch gibt. Wenn ja, dann binde es mit ein. Wenn es dann klappt, versuche mal meinen Code von oben.

    Ansonsten, wie gesagt, ich weiß nicht wofür die Parameter sind beim assemblieren und linken, aber ansonsten würde ich diese einma weglassen....

    Code-Hacker



  • Werde ich machen, aber nicht mehr heute.



  • Um nochmal auf die Ausgangsfrage von AsmNewbie zurückzukommen ("Wieso werden Strings mit mov dx,offset FOO ausgegeben? wieso mit DX und nicht z.b AX?"):

    Strings werden unter DOS nicht allein mit diesem MOV Befehl ausgegeben. Dieser füllt nur das DX Register. Die Register werden (im Gegensatz zu normalen Windowsfunktionen, dort ist es der Stack) zum übergeben von Parametern verwendet. Die eigentliche Ausgabe macht der Code im DOS Kernel. Eine Funktion davon wird via INT 21h aufgerufen.
    Die Programmierer von DOS haben es nunmal festgelegt, dass diese Funktion in DX das Offset des Strings erwartet. Reine Willkür also, hehehe.


Anmelden zum Antworten