Punkt zeichnen (int 10, al 0Ch)
-
Hallo Leute!
Bin noch ganz neu in Assembler und habe mir nur das Hallo Welt Programm angeguckt und die kleine DOS API Referenz in meinem Buch. Jetzt hab ich in den Grafikmodus 640 * 480 gewechselt -> klappt
Und nun wollte ich einen Punkt zeichnen, aber ich seh ihn nicht. Hier mal der Code:CODE SEGMENT WORD 'CODE' ASSUME CS:CODE Start: ;---------------------------------------------------------- ; In Videomodus 640 * 480 mit 16 Farben wechseln ;---------------------------------------------------------- mov ah, 0 mov al, 12 int 10h ;---------------------------------------------------------- ; Punkt zeichnen ;---------------------------------------------------------- mov ah, 0Ch mov cx, 10 ; Splate mov dx, 10 ; Zeile mov al, 4 ; Farbattribut -> Ist 4 überhaupt gültig? int 10h ;---------------------------------------------------------- ; Auf Eingabe eines Zeichens warten ;---------------------------------------------------------- mov ah, 7 int 21h ;---------------------------------------------------------- ; Programm beenden ;---------------------------------------------------------- mov ah, 04Ch int 21h CODE ENDS END Start
Wer kann mir helfen? Ist das Farbattribut einfach nicht richtig? In meinem Buch stand nicht was man da einsetzen muss. Oder ist der Punkt zu klein das man ihn garnicht sehen kann? Wer kann mir dabei helfen?
Ich benutze TASM 5 und Windows XP, falls das was zur Sache tut :p
-
kann es vielleicht sein, dass der Interrput 0x10 nicht geht, da XP ein PM OS ist und keine BISO Interrupts zulässt.
-
Das glaube ich nicht...denn bei dem Wechsel in den Videomodus benutze ich ja auch den Interrupt 10h und es tut sich was. Ich bekomme so in einen "Vollbildmodus". Habe auch gerade ein farbiges Zeichen mit Interrupt 10h (Funktion 09) ausgegeben. Hat auch funktioniert.
Windows emuliert ja DOS wenn das Programm mit einem 16-bit Compiler/Assembler geschrieben wurde.
-
achso, na wenn Windos DOS emuliert, sollte das kein Problem sein.
Versuch doch mal eine Linie (mehrere Punkte auf einer Schleife) zu malen, vielleicht siehst du das dann besser.
-
Ok, könnte ich mal versuchen...doch leider bin ich wie gesagt noch totaler Anfänger und weiss noch nicht wie z.B. ne Schleife in Assembler aussieht
Könntest du mir vielleicht helfen, wie ich den Code in eine Schleife verpacken kann?
-
ich weiss nicht, ob es funzt, da ich nicht mehr so gut in Assembler bin (und vorallem nicht mehr in Intel Assembler)
;... ;---------------------------------------------------------- ; Punkt zeichnen ;---------------------------------------------------------- push bx xor bx,bx linie01: mov ah, 0Ch mov cx, bx ; Splate mov dx, 10 ; Zeile mov al, 4 ; Farbattribut -> Ist 4 überhaupt gültig? int 10h inc bx cmp bx,20h ;zeichne eine Linie, die 0x20 Spalten lang ist jl linie01
-
Danke für deine Mühen Kingruedi. Assemblieren konnte ich den Code, doch leider sehe ich immer noch nichts. Was könnte noch falsch sein? :p
-
Der Monitor gehört an :p
-
@TriPhoenix: Hast du den Code getestet? Sieht du etwa was? :p :p
-
Bisher net, ich kanns ja mal versuchen Wenn mir noch jemand sagt, wo ich TASM bekomme... (in der FAQ hab ich nichts gesehen...Google versuch ich gleich nochmal :))
Edit: den 2.01er hab ich shcon..gibt aber sicher noch aktuellere Versionen, oder? ^^
Zusatz 2 Unter WinXP ist dessen funktionieren fragwürdig..ich krieg nur ein wneig roten Matsch am oberen Rand, der hatte ein paar probs, den vollbildmodus zu greifen Vielelicht morgen
[ Dieser Beitrag wurde am 30.05.2002 um 02:02 Uhr von TriPhoenix editiert. ]
-
Moin, Moin...
Der Fehler des Programms liegt in der Zeile mov al, 12. Der
betreffende Videomodus hat den Wert 012(hex). Das entspricht 18(dez)!Also entweder schreiben mov al,18 oder mov al,012h.
Außerdem sollte wieder in den Textmodus geschaltet werden, bevor das Programm beendet wird.
mov ah,0 mov al,03h int 010h ; Programm beenden
Ciao...
[ Dieser Beitrag wurde am 30.05.2002 um 08:38 Uhr von KalEl editiert. ]
[ Dieser Beitrag wurde am 30.05.2002 um 08:39 Uhr von KalEl editiert. ]
-
Wow, vielen Dank an alle! KaiEl hatte recht, mit 12h in al funktioniert es
Aber dazu muss ich sagen, dass es dann in meinem Buch falsch stand, dort standen nämlich nur 12 :pGrafikprogrammierung ist ja dann ziemlich einfach, echt super
Jetzt bastel ich mir mal ein paar Funktionen zum Beispiel zum Zeichnen eines Kreises. Ist es überhaupt möglich irgendwie Funktionen wie in C/C++ zu schreiben? Dachte man nimm Labels.ZeichneKreis:
; CodeAber dann kann ich ja nie Werte übergeben. Kann man sowas machen?
-
funktionen gibt es auch in Assembler!
Beispiel
;... call kreis ;... kreis PROC NEAR ;... ret kreis ENDP
-
Moinsen...
Ähm, mein Name lautet nicht KaiEl sonder KalEl.
Danke...
-
Danke, habe es jetzt versucht das Zeichnen der Linie in eine Funktion einzubetten, dazu habe ich auch in meinem Buch nachgelesen, aber jetzt stürtzt das Programm ab:
;----------------------------------------------------------
; Linie zeichnen
;----------------------------------------------------------Linie PROC NEAR
push bx
xor bx,bx
linie01:
mov ah, 0Ch
mov cx, bx ; Splate
mov dx, 10 ; Zeile
mov al, 4 ; Farbattribut
int 10h
inc bx
cmp bx, 20h ;zeichne eine Linie, die 0x20 Spalten lang ist
jl linie01
ret
Linie ENDPcall Linie ; Die Linie-Funktion aufrufen
Windows meldet: "Die NTVDM-CPU hat einen ungültigen Befehl entdenkt."
Was könnte der Fehler sein?
@KalEl: Sorry, werde es mir merken :p
-
ich sehe in der proc "push bx" aber kein "pop bx"
-
Und nochmal Moinsen...
Hier ein kleines Programm, das die Parameterübergabe an eine
Assemblerfunktion zeigen soll:.model small .stack 0200h .data .code start: push 10 ; 1. Parameter auf den Stack push 20 ; 2. Parameter auf den Stack call addiere add sp, 4 ; Stack bereinigen mov ah, 7 int 21h mov ah, 04Ch int 21h ; Hier folgen die Funktionen addiere proc near push bp ; Register bp sichern mov bp, sp ; Stackframe aufbauen push bx ; Registerinhalt retten mov ax, word ptr [bp + 4] ; 1. Parameter nach ax mov bx, word ptr [bp + 6] ; 2. Parameter nach bx add ax, bx pop bx mov sp, bp ; alten Wert von sp wiederherstellen pop bp ; alten Wert von bp zurückholen ret addiere endp end Start
Die Funktion addiert die beiden Parameter. Das Ergebnis steht in Register ax und kann so an das Hauptprogramm übergeben werden.
Wichtig ist, dass der Stack bereinigt wird, d.h. die Parameter werden quasi wieder vom Stack entfernt.
Diese Art der Parameterübergabe ist wie in C. Pascal macht das etwas anders.
Ciao...
-
Danke dir
Es lag an 2 Sachen, erstmal das pop bx und dann ging's immer noch nicht, da ich so dämlich war und die Funktion in den Code des start-Labels gepackt hatte *lol* :p
Also hier nochmal der vollständige Code, falls es jemand ausprobieren möchte oder ähnliches
CODE SEGMENT WORD 'CODE' ASSUME CS:CODE ;---------------------------------------------------------- ; DrawLine Prozedur ;---------------------------------------------------------- DrawLine PROC NEAR push bx xor bx,bx LineLoop: mov ah, 0Ch mov cx, bx ; Splate mov dx, 80 ; Zeile mov al, 4 ; rot int 10h inc bx cmp bx, 80h ; zeichne eine Linie, die 0x80 Spalten lang ist jl LineLoop pop bx ret DrawLine ENDP start: ;---------------------------------------------------------- ; In Videomodus 640 * 480 mit 16 Farben wechseln ;---------------------------------------------------------- mov ah, 0 mov al, 12h int 10h ;---------------------------------------------------------- ; Grünes 'a' ausgeben ;---------------------------------------------------------- mov ah, 9 mov bh, 0 ; Bildschirmseite 0 mov cx, 1 ; Ein Zeichen mov al, 97 ; 'a' mov bl, 2 ; grün int 10h ;---------------------------------------------------------- ; Linie zeichnen ;---------------------------------------------------------- call DrawLine ;---------------------------------------------------------- ; Auf Eingabe eines Zeichens warten ;---------------------------------------------------------- mov ah, 7 int 21h ;---------------------------------------------------------- ; Videomodus zurückschalten ;---------------------------------------------------------- mov ah, 0 mov al, 3h int 10h ;---------------------------------------------------------- ; Programm beenden ;---------------------------------------------------------- mov ah, 04Ch int 21h CODE ENDS END start
-
Habe auch mal ne Frage zu deinem Code KalEl:
mov ax, word ptr [bp + 4] ; 1. Parameter nach ax
mov bx, word ptr [bp + 6] ; 2. Parameter nach bxWas macht man denn, wenn man ganz viele Parameter hat? Soviele Register stehen ja garnicht zur Verfügung
-
Dann verarbeitet man die Parameter halt hintereinander. Die bleiben schliesslich auf dem Stack erhalten.
Die Parameteruebergabe via Stack erscheint mir ehrlichgesagt sowieso nur sinnvoll, wenn entweder mehr Parameter verarbeitet werden muessen, als Register zur Verfuegung stehen (kommt fast nie vor)
Der code so unglaublich kompliziert und lang ist, dass man zwischendurch die Parameter so und so pushen muesste (eigentlich auch selten - ich wuerde dann eher auf globale Variablen zurueckgreifen)
Oder wenn man eine Assembler routine in eine Hochsprache wie zB. C einbinden will.