Ausgabe
-
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 segmentIch 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: @DATAallerdings 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 endsaber 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.