Assembler usw

nun dazu gehöhrt einiges mehr als nur das du uns sagst du willst das in ASM machen...

1.) Win32? DOS? NativeCode? PMode? RMode?

Nun wenn du windows programmierst, funktioniert es genauso wie in jeder anderen sprache nur eben als ASM syntax, also mit dem WinAPI

wenn du für Dos oder native-Realmode schreibst, sieht die sache anders aus... da kannst du die funktionen des INT10 benutzen um die graphikkarte anzusprechen, und dann schreibst du einfach je nach graphikmodi die daten in den graphikspeicher..

mov ax, 13h
int 10h

setzt den graphikmodus aus 0x13, wobei zu beachten is.. die funktionsnummer zum setzen des graphimodes (in ah) is 0 und der parameter in al is der graphikmodus...

mov es, 0xA000

und mit dem befehl bereitest du das extra segment dafür vor daten in den graphikspeicher zu schreiben.. das is es für VGA modus, bei EGA oder ähnlichem müsst ich nachgucken..

nun kannste einfach
mov al, 16
mov [es:0], al
so ein pixel auf den farbwert 16 z.B. setzen...
das funktioniert bei EGA genau so... die einzige ausnahme sind die 640x480 graphikmodi und dann die VESA modi... bei dem 640x480 modi arbeitest du mit bitmasken, wobei 1bit = 1 pixel, und musst dann die farben umschalten...
und bei VESA funktioniert es nahezu genau so nur mit dem unterschied das du zusätzlich BankSwitches einfügen musst.. also zwischen den speicherteilen hin und herschalten...

um einiges komplizierter wird es wenn du nun im native-protected mode programmierst.... denn dann musst du auch die graphikregister selbst ansteuern.... das sind über 100 register dies gibt für alles mögliche.. naja da würd ich sagen mach sowas im V86 und benutz bios

http://www.ctyme.com/intr/int-10.htm <-- das sind die graphikfunktionen die dir das BIOS und das VESA-BIOS zur verfügung stellen...
 
Hi Leute

Ich Habe ein Kleines OS Programmiert durch Hilfe anderer OS und Tutorials jetzt will ich noch Grafiken rein Setzten!
Ich meinte so etwas wie zb bei QBasic da kann man eine Linie Zeichnen
Hat jemand ein Beispiel dafür?

wie man von Punkt X1,Y1 nach Punkt X2,Y2 eine Linie zeichnet?

Und wie funktioniert das denn Richtig mir den Grafik Karten, was muss ich darüber wissen

Wie ändert man den Die Farbe von Buchstaben oder Grafiken?

Danke für eure Hilfe
 
Wer lesen kann is klar im vorteil

ich hab dich 1.) gefragt ob du fals du mit Nativecode arbeitest, was du beim einem eigenen OS zwangsleufig tust mit R oder P mode arbeitest..

2.) hab ich dir bereits genau beschrieben wie du pixel setzt und neu setzt, alles andere is nur erweiterung des ganzen...

und sowas wie linie zeichnen in assembler gibts so und so net fertig....

nochmal von vorn:
arbeitest du im RMode kannst du mit hilfe des Bios interupts 10h funktion 00h den bildschirmmodus ändern...
beispiel:
Code:
mov ax, 13h  ;setzt ah = 0, al = 13h
int 10h           ;biosinterupt aufrufen um die funktion auszufphren

um nun einen pixel zu setzten musst du den pixel in den graphikspeicher schreiben, wie der graphikspeicher organisiert ist und wo er liegt hängt vom graphikmodus ab.

fortsetzung des obigen beispiels:
bei modus 13h beginnt der graphikspeicher bei flat 0xA0000
entsprechend den regeln für realmode programmierung setzt du ein segmentregister auf 0xA000 um auf den speicher zugreifen zu können
der graphikspeicher ende in diesem fall 64000byte weiter...
entsprechend, kannst du nun einen pixel setzen

code dazu:
Code:
mov ax, 0xA000 ;segmentregister können nicht direkt geladen werden
mov es, ax         ;also zuerst in ax zwischenspeichern und dann rüber kopieren
so nun hast du die vorbereitungen abgeschlossen nun kannst du anfangen pixel zu setzen

der mode 13h ist ein 320x200 pixel großer modus, und er benutzt 256 farben, entsprechend ist ein pixel = 1 byte

der graphikspeicher ist definiert als bytearray mit einer länge von 64000byte entsprechend das jeder pixel ein byte ist brauchst du nur von der oberen linken ecke anfangen zu zählen.. die formel für die berechnung des offsets im graphikspeicher:
offset = y*320 + x
x = richtung in x
y = richtung in y
offset = der wert den du beim zugriff benutzen musst

vergiss bei dem ganzen bitte nich das zeilen und spalten nummerierung bei 0 beginnt...

und nun schreibste den farbwert den du willst an die entsprechende stelle

Code:
mov cx, offset       ;offset in register laden
mov dl, farbwert  ;farbwert in register laden
mov [es:cx], dl     ;farbwert mit hilfe von segmentoverride präfix in dereferenziertes CX schreiben

also noch genauer kann ich es fast nicht mehr erklären

nocheinmal der link auf die interupt liste von R-Brown http://www.ctyme.com/intr/int-10.htm

im pmode funktioniert das ganze ganz ähnlich

dort machst du in deiner GDT einen eintrag für den graphikspeicher, im VGA modi is der flat offset wie schon erwähnt 0xA0000 wenn du den modus ändern willst brauchst du die grphikregister dazu die über den out befehl angesprochen werden, wie die allerdings alle genau funktionieren, das würde den rahmen dieses forums um megabytes an text sprengen...einfach mal googlen...

und was den zugriff auf den graphikspeicher betrifft.. das selbe in grün...

also wieder selector nehmen und
Code:
mov ax, selector
mov es, ax
mov cx, offset
mov dl, farbwert
mov [es:cx], dl

einzig erkennbarer unterschied hier... ich benutz anstat von 0xA000 hier den selektor der auf den eintrag der GDT zeigt...
ansonsten, aufpassen das du kein DPL laden willst für das dein CPL nich ausreicht... und natürlich sollte RPL = DPL sein.. wie halt immer außer bei call gates.. stell sicher das du nich versehendlich in der LDT landest, ja die üblichen dinge die man beim arbeiten mit pmode segmenten eben beachten muss....


So und wenn du das noch immer nich verstanden hast jetzt, dann sag uns zu aller erstmal in welchem modus du bist,... denn dann kann ich geziehlt darauf eingehen...
 
hi....
ich hab den code ausprobiert..aber bei mir kommt immer ein fehler hiner mov [es:cx], dl ....das komische is, dass der fehler immer genau eine zeile danach kommt (fehler. Invalid effective adress)
der code, den ich genommen hab sieht folgendermaßen aus:

MOV AX, 13h
INT 10h

MOV AX, 0xA000
MOV ES, AX

MOV CX, 321
MOV DL, 2
MOV [ES:CX], DL


wo is der fehler?
 
ups ja, da muss man die operator geröße explizit angeben

Code:
mov byte [es:cx], dl
so sollte es funktionieren...

hinweis: der asm code is nach NASM syntax verfasst

ich zeig dir mal n kleines beispiel:

Code:
[org 0x100]
[bits 16]
	jmp _start
_start:
	mov ax,0x0013		;
	int 10h			;switch to 640x480x16
        mov bx,0xA000  
        mov es,bx          	;set es to graphik memory  
	
	
	mov ecx,0xFF		;all colors
_loop2:
	mov eax, ecx		;backup collor for reusing ecx
        mov ecx,0xFFFF  	
_loop1:
	mov byte [es:ecx-1],al  ;write pixel to display memory
	loop _loop1		; next pixel
	call _whait		; whait, or it would be to fast to see it
	mov ecx,eax		;resore color value
	loop _loop2		;next color
	

	mov ah,08h		;whait for key
	int 21h			
	mov ah, 4ch		;exit process
	int 21h
_whait:
	mov ecx, 0xFFFF
_whait2:			;let the app whait a little time	
	hlt
	hlt
	hlt
	loop _whait2
	ret

kompilieren mit
nasmw -fbin -o test.com test.asm
 
ich hab den code eben noch assembliert und häng ihn dir als dateianhang dran

sorry wegen doppenposting, aber dateien nacfhträglich anhängen geht nich :(

leider kann ich auch das com file nich direkt anhängen :( und so sind aus 63Byte code datei 173byte zip geworden.. naja kann man nix machen
 

Anhänge

  • test.zip
    174 Bytes · Aufrufe: 96
So endlich habe ich mal wieder Zeit zu schreiben

Ich hätte eine Frage zu dem Beispiel code, und zwar ob der im Realmode ist?
Ich bin noch anfänger in Assembler!
 
nasmw

fürs beispiel ;)
kann man die .com files (die man ja unter windows ausführen kann nur mit nasmw machen? ,..oder auch mit nasm ?
(nasm = netwide assembler for windows ? ):) :) :)

und noch ne frage ;) ..
wie kann man im grafik modus linien zeichnen?..
ich wolltes erst mit den einzelnen pixeln machen.. aber das is mir irgendwie zu aufwendig geworden 320 pixel einzeln auf weiß zu stellen...ich hätte hochstens ne schleife machen können.. aber abgesehen davon, dass ich völlig vergessen hab, wie der ADD befehl , dachtich mich, dass es sicherlich viel zu lange dauern würde die schleife und dasses ja auch möglich sein müsste einfach gleich ganze linien zu zeichnen wo man nur die anfangs- und endkoordinatehn angeben muss... is das möglich?
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück