|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
darkinsanity aka sts
Anmeldungsdatum: 01.11.2006 Beiträge: 456
|
Verfasst am: 31.10.2007, 14:53 Titel: Pixel setzen in ASM |
|
|
Hi. Ich schreibe ja gerade eine SVGA-Lib. wegen der Geschwindigkeit habe ich pqb.pset und pqb.point jetzt in Assembler geschrieben. Aber wenn ich es mit NASM in eine obj umwandeln will, kommen immer Fehler.
NASM hat Folgendes geschrieben: |
H:\>nasm -f obj grafik.asm
grafik.asm:1: error: attempt to define a local label before any non-local labels
grafik.asm:1: error: parser: instruction expected
grafik.asm:2: error: attempt to define a local label before any non-local labels
grafik.asm:3: error: attempt to define a local label before any non-local labels
grafik.asm:3: error: parser: instruction expected
grafik.asm:5: error: attempt to define a local label before any non-local labels
grafik.asm:9: error: parser: instruction expected
grafik.asm:10: error: symbol `PUBLIC' redefined
grafik.asm:10: error: parser: instruction expected
grafik.asm:11: error: symbol `PUBLIC' redefined
grafik.asm:11: error: parser: instruction expected
grafik.asm:12: error: symbol `PUBLIC' redefined
grafik.asm:12: error: parser: instruction expected
grafik.asm:23: error: parser: instruction expected
grafik.asm:24: error: parser: instruction expected
grafik.asm:53: error: invalid segment override
grafik.asm:58: error: symbol `pqb.pset' redefined
grafik.asm:58: error: parser: instruction expected
grafik.asm:63: error: symbol `public' redefined
grafik.asm:63: error: parser: instruction expected
grafik.asm:64: error: parser: instruction expected
grafik.asm:94: error: invalid segment override
grafik.asm:98: error: symbol `pqb.point' redefined
grafik.asm:98: error: parser: instruction expected
|
hier der Sourcecode:
Code: |
.model huge
.386
.stack 100h
.DATA
;Variablen kommen hierhin
PUBLIC pqb.xresolution
PUBLIC pqb.yresolution
PUBLIC pqb.goffset
PUBLIC pqb.BankSize
pqb.xresolution DW 0
pqb.yresolution DW 0
pqb.goffset DW 0
pqb.Banksize DW 0
.Code
;-------------------------------------
; pqb.pset setzt einen Pixel
;-------------------------------------
public pqb.pset
pqb.pset proc x:word, y:word, farbe:word
push ds
; Wenn der Pixel auserhalb des Bildschirms liegt, dann überspringen
cmp x, pqb.xresolution-1
jg SkipPixel
cmp x, 0
jl SkipPixel
cmp y, pqb.yresolution-1
jg SkipPixel
cmp y, 0
jl SkipPixel
; Die Berechnung des Offsets
mov AX, y
mov BX, pqb.xresolution
IMul BX
ADD BX, x
mov pqb.goffset, BX
; Benötigte Bank im VRAM berechnen
mov AX, BX
mov CX, pqb.Banksize
Idiv CX
; mit Hilfe der Variable bank die benötigte Bank im VRAM setzen
mov AX, 4F05h
mov BX, 0
mov DX, CX
mov CX, 0
int 10h
; Den Pixel setzen
mov [A000h:pqb.goffset], farbe
SkipPixel:
pop ds
ret
pqb.pset endp
;-------------------------------------
; pqb.point liest einen Pixel
;-------------------------------------
public pqb.point
pqb.point proc x:word, y:word
push ds
; Wenn der Pixel auserhalb des Bildschirms liegt, dann überspringen
cmp x, pqb.xresolution-1
jg SkipPoint
cmp x, 0
jl SkipPoint
cmp y, pqb.yresolution-1
jg SkipPoint
cmp y, 0
jl SkipPoint
; Die Berechnung des Offsets
mov AX, y
mov BX, pqb.xresolution
IMul BX
ADD BX, x
mov pqb.goffset, BX
; Benötigte Bank im VRAM berechnen
mov AX, BX
mov CX, pqb.Banksize
Idiv CX
; mit Hilfe der Variable bank die benötigte Bank im VRAM setzen
mov AX, 4F05h
mov BX, 0
mov DX, CX
mov CX, 0
int 10h
; Den Pixel auslesen
mov AX, [A000h:pqb.goffset]
pop ds
ret
pqb.point endp
|
ich hoffe ihr könnt mir helfen. Danke im vorraus! |
|
Nach oben |
|
|
atari gesperrt
Anmeldungsdatum: 26.08.2007 Beiträge: 144
|
Verfasst am: 26.11.2007, 17:48 Titel: |
|
|
Zitat: |
Ich schreibe ja gerade eine SVGA-Lib. wegen der Geschwindigkeit habe ich pqb.pset und pqb.point jetzt in Assembler geschrieben.
|
warum nimmst du nicht mmx-routinen, die sind nochmal um den faktor 100 schneller. |
|
Nach oben |
|
|
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 26.11.2007, 18:03 Titel: |
|
|
MMX ist nur dann sinnvoll, wenn auch wirklich gerechnet werden soll.
Hier in dem Fall wird aber so gut wie gar nicht gerechnet. _________________ Eine handvoll Glück reicht nie für zwei.
--
|
|
Nach oben |
|
|
darkinsanity aka sts
Anmeldungsdatum: 01.11.2006 Beiträge: 456
|
Verfasst am: 28.11.2007, 22:43 Titel: |
|
|
ich hab keine Ahnung was MMX-Routinen sind. Habt ihr eine Idee warum NASM das nicht annehmen will? Ich hab keine Ahnung wo der Fehler liegt, ich hab mir sogar (wegen den Variablen) extra den Sourcecode von DQB angesehen, damit ich nichts falsch mach, hat aber wohl nix geholfen. |
|
Nach oben |
|
|
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 28.11.2007, 22:56 Titel: |
|
|
Assembler<>Assembler.
Wenns es um andere Sachen, als direkt um Code geht (hier z.B. um Instruktionen, wie etwas zugänglich zu machen ist), dann sollte immer das jeweilige Handbuch zu Hilfe gezogen werden.
Ich hab lange nix mehr mit NASM gemacht, aber AFAIR stand dazu auch was im Manual. _________________ Eine handvoll Glück reicht nie für zwei.
--
|
|
Nach oben |
|
|
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 29.11.2007, 11:35 Titel: |
|
|
Hi,
anscheinend hast du einfach TASM-Code (oder so) genommen und versuchst, diesen mit NASM zu compilieren.
Geht natürlich nicht.
Code: | grafik.asm:1: error: attempt to define a local label before any non-local labels |
Alles was mit einem Punkt anfängt, wird als lokales Label (Sprungmarke) verstanden.
Preprocessor-Befehle in NASM sehen anders aus.
Da musst du dich schon selbst einarbeiten: http://web.mit.edu/nasm_v0.98/doc/nasm/html/nasmdoc4.html
PUBLIC, endp, .model huge, .stack xxx und sowas gibts in NASM nicht
Sry, aber du verwendest den komplett falschen Assembler für diesen Code^^ _________________
|
|
Nach oben |
|
|
darkinsanity aka sts
Anmeldungsdatum: 01.11.2006 Beiträge: 456
|
Verfasst am: 29.11.2007, 13:17 Titel: |
|
|
oder den falschen Code für diesen Assembler. Danke für die Tipps. |
|
Nach oben |
|
|
Bimi
Anmeldungsdatum: 03.12.2007 Beiträge: 66
|
Verfasst am: 06.12.2007, 09:46 Titel: Re: Pixel setzen in ASM |
|
|
sts hat Folgendes geschrieben: | Hi. Ich schreibe ja gerade eine SVGA-Lib. wegen der Geschwindigkeit habe ich pqb.pset und pqb.point jetzt in Assembler geschrieben. |
...geht es dir um Performance oder um Erfahrung in Assembler zu sammeln.
Geschwindigkeitsrekorde wirst du damit nicht brechen, könnte sogar sein das zu langsamer bist als PSET...
Für jeden (!) Pixel wird die Speicherbank berechnet...
Zwei Prüfungen für jede Koordinta obwohl man mit einer auskäme
Aufruf des Schneckenlahmen int 10....
Der Code ist vielleicht geeignet um auf einem 386 mit begrenztem Speicher zu laufen.
Folgende Gedanken:
* VideoRAM sitzt auf der Graphikkarte und nicht im Hauptspeicher. Das VRAM kann also nicht mit RAM-Frequenz, sondern nur mit Busfrequenz angesprochen werden (bis zu Faktor 20 langsamer).
* es werde immer nur 16 Bit übertragen obwohl 64 möglich wären
* VRAM ist nicht linear, zusätzliche Kommandos (Buszyklen) werden benötigt um die Speicherbank umzuschalten.
* auf manchen Systemen läuft der Bus synchron. nops in großer Menge werden durch die CPU eingefügt...
Der Code wird also im wesentlichen auf das V-RAM warten.
Daher folgender Anstatz:
* lokalen Speicher reservieren - dabei die Auflösung auf die nächste Zweierpotenz aufrunden.
Beispiel:
* 320 * 200 Bildpunkte
* Speicher 512 * 256
* Masken erstellen: 0xFF00 für y und 0xFE00 für x bei dieser Auflösung
Pixel setzen:
* x mit x Maske mit logisch UND verknüpfen - bleibt was übrig bin ich außerhalb. Damit erschlage ich mit einem(!) Vergleich auch negative werte, weil dann das erste Bit gesetzt ist und das von der Maske erfaßt wird.
* analog y
* Damit werden jedoch auch alle Pixel gespeichert, die im Bereich 320 bis 512 für x liegen - macht aber nix, sind zwar im Speicher, wir stellen sie dann einfach nicht dar...
Getriggert durch einen TimerInterrupt z.B. unter Dos wird nun der Zwischenpuffer ausgegeben - und das nicht durch move, sondern mittels stos-Befehlen...
Von jeder Zeile werden nur die ersten 320 Bytes an den Videopuffer übertragen. Umschalten der VRam Seiten nur je einmal pro Ausgabe notwendig.
Nocheinmal ein bischen Pseudocode für obige ScreenSize:
Code: |
#define X_MASK = 0xFE00
#define Y_MASK = 0xFF00
short bildpuffer[512*256];
SUB setPixel (short x, short y, short color) {
if ((x UND X_MASK) != 0x00) return; // x Koordinate außerhalb
if ((y UND Y_MASK) != 0x00) return; // y Koord außerhalb
y = y << 9; // da eine virtuelle Bildschirmzeile einer 2er Potenz entspricht,
// kann eine Multiplikation der Zeile mit Shiftbefehlen
// abgebildet werden -> schneller als imul!
bildpuffer[y+x] = color;
}
SUB copyBuffertoVRAM (char *buffer) {
char *dest = VRAMBASEADDR;
char *src = buffer;
for bank = 0 to banksize {
switchBank ();
dest = VRAMBASEADDR;
for line = 0 to lineinbank {
memcpy (dest,src,512);
src += 512;
}
}
}
|
Wer C beherrscht kann den Unterschied erfahren - der Befehl memcpy verwendet stos-Befehle. Schreibt mal euer eigenes memcopy in reinem C.
Meine Variante lief auf meinem nicht überragend schnellen PC ca 8 Sekunden für ein GB mit reinen mov Befehlen. Durchsatz 125 MB/s
memcpy braucht für die gleiche Aktion 0,4 Sekunden...2,5GB/s... |
|
Nach oben |
|
|
darkinsanity aka sts
Anmeldungsdatum: 01.11.2006 Beiträge: 456
|
Verfasst am: 06.12.2007, 13:17 Titel: |
|
|
Mir geht es sowohl um Erfahrung sammeln als auch darum, das meine selbstgeschriebene Lib möglichst schnell wird. Die local label Fehler hab ich schon weg. Ich werd mal versuchen die NASM doc zu verstehn. |
|
Nach oben |
|
|
Bimi
Anmeldungsdatum: 03.12.2007 Beiträge: 66
|
Verfasst am: 06.12.2007, 13:37 Titel: |
|
|
sts hat Folgendes geschrieben: | Mir geht es sowohl um Erfahrung sammeln als auch darum, das meine selbstgeschriebene Lib möglichst schnell wird. Die local label Fehler hab ich schon weg. Ich werd mal versuchen die NASM doc zu verstehn. |
Dann hau zuerst die int's raus und schreib direkt in den Speicher - aber nicht ins V_RAM, das wird ein Flaschenhals auf mordernen Systemen. |
|
Nach oben |
|
|
darkinsanity aka sts
Anmeldungsdatum: 01.11.2006 Beiträge: 456
|
Verfasst am: 10.12.2007, 20:10 Titel: |
|
|
ohne int's ? wie das denn? In allen Tutorials, die ich über SVGA gelesen hab, wurde immer int 10 benutzt.
/Edit:
Hab noch en paar Probleme mit der NASM doc. wie kann ich den Variablen definieren? und wieso ist die Zeile mov [A000h:pqb.goffset], farbe fehlerhaft? |
|
Nach oben |
|
|
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 10.12.2007, 20:20 Titel: |
|
|
Der INT selber schreibt auch nur den Farbwert in den Grafikspeicher.. wenns schnell gehen soll, musste das halt selbst in ASM lösen.
Tut mir leid, wenn ein Fehler drin sein sollte, hab auch schon länger nimmer gecodet.
Aber fest steht, dass du ein Label in eckige Klammern setzen musst, um den unter der Labeladresse gespeicherten Wert und nich die Labeladresse selbst zu bekommen.
mov ax, [pqb.goffset]
mov es, ax
mov [A000h:es], [farbe]
...
farbe db 4 _________________
|
|
Nach oben |
|
|
marzec
Anmeldungsdatum: 13.10.2004 Beiträge: 267
|
Verfasst am: 10.12.2007, 20:31 Titel: |
|
|
wenn es dir wirklich nur m as elernen von x86 asm ndgfx programmierung geht, würde ich dir empfehlen mit der win32 oder linx version von fb zu arbeiten. dort kannst du einfacher fuhrwerken. fenster erstellen, speicher für offscreenbuffer allokieren, pointer an inline asm code weiterreichen, pixel, linien etc zeichnen. inhalt des allokierten speichers in den fenterframebuffer koperen fertig falls dir c lieber ist als glue code empfehl ich dir tinyptc als gfx lib. _________________ Yagl - yet another gameprogramming library |
|
Nach oben |
|
|
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 10.12.2007, 20:40 Titel: |
|
|
Ja, aber beim direkten Speicherzugriff wird der lästige und vergleichsweise teure Weg über den Interrupt gespart. _________________ Eine handvoll Glück reicht nie für zwei.
--
|
|
Nach oben |
|
|
Bimi
Anmeldungsdatum: 03.12.2007 Beiträge: 66
|
Verfasst am: 11.12.2007, 08:57 Titel: |
|
|
sts hat Folgendes geschrieben: | ohne int's ? wie das denn? In allen Tutorials, die ich über SVGA gelesen hab, wurde immer int 10 benutzt.
|
Mal ein paar Worte zu Assembler....
Assembler ist nicht per Definition schneller. Assembler ist dann und nur dann schneller wenn man weiß was da wirklich passiert und vor allem wie. Die meisten Assemblertutorials wurden von Leuten geschrieben, die schon einmal ein paar Zeilen in Assembler geschrieben haben, die sie selbst in irgend eineam andern Tut geklaut haben.
In 95% der der Fälle in denen ich asm Code lese denke ich mir, derjenige könnte es auch bleiben lassen, da bekommt ein guter optimierender Compiler nen besseren Code hin.
Performant Assembler programmieren heißt in erster Linie die Hardware kennen. Zilesetzung ist es durch diese Kenntnis dort den speziellen Weg gehen zu können wo ein Compiler den Allgemeinen gehen muss. Ein moderne CPU kennt ein paar hundert Maschinenbefehle, die meisten Compiler verwenden nicht einmal 20% davon. Interressant sind nicht diese 20%, sondern die restlichen 80%.
Assembler ermöglicht es mir Techniken anzuwenden, die anders nicht gehen.
* für Stringvergleiche nutzt man MMX, nicht die normalen Register
* Warum den "langsamen" Coprozessor für Gleitkommaoperationen verwenden, der in der Regel nur einige MegaFlops hat wenn auf jeder modernen 3D Graphikkarte einer ist, dessen Leistung im TerraFlops-Bereich liegt - man muss ihn nur zu nutzen lernen (und das ist alles andere als einfach...)
Ist eigentlich ganz einfach:
Wenn du mit Pixelzeichnen ganze Bildschirme füllst und das so schnell hintereinander, dann schaffst du damit auch auf schnellen Systemen kaum 100 Bilder je Sekunde. Ein Rechner mit 1 GHz ist etwas um den Faktor 2000 schneller als ein alter 386er mit 40Mhz - und der schaffte schon 40 Frame/Sekunde bei Spielen - irgendetwas hat man damals anders gemacht...und das gilt es herauszufinden.
sts hat Folgendes geschrieben: |
/Edit:
Hab noch en paar Probleme mit der NASM doc. wie kann ich den Variablen definieren? und wieso ist die Zeile mov [A000h:pqb.goffset], farbe fehlerhaft? |
Segmentübergreifende Addressierung geht unter 16 Bit nur wenn die Segmentadresse in einem Segmentregister steht. Bei jedem mov-Befehl muß einer der beiden Operanten ein Register sein. Mit nur einem mov von Speicher in Speicher kopieren geht z.B. bei Motorola, nicht aber bei Intel. Dumm an der Kiste ist auch, das sich ein Segmentregister nicht direkt laden läst, sondern nur über den Umweg eines anderen Registers. Paul hat die richtige Lösung gepostet.
Mach aber bitte nicht den Fehler das Segmentregister für jede Pixelausgabe neu zu setzen - einmal reicht um dann alle Pixel auszugeben... _________________ Rechtbehelf:
Rechschreibverfehlungen, Vergehen an der Deutschen Sprache sowie Stabwechselverbuchselungen unterliegen dem Urheberrecht, sind voll beabsichtigt und fördern das aufmerksame Lesen. |
|
Nach oben |
|
|
marzec
Anmeldungsdatum: 13.10.2004 Beiträge: 267
|
Verfasst am: 11.12.2007, 16:57 Titel: |
|
|
Bimi hat Folgendes geschrieben: | sts hat Folgendes geschrieben: | ohne int's ? wie das denn? In allen Tutorials, die ich über SVGA gelesen hab, wurde immer int 10 benutzt.
|
* Warum den "langsamen" Coprozessor für Gleitkommaoperationen verwenden, der in der Regel nur einige MegaFlops hat wenn auf jeder modernen 3D Graphikkarte einer ist, dessen Leistung im TerraFlops-Bereich liegt - man muss ihn nur zu nutzen lernen (und das ist alles andere als einfach...)
|
<klugscheiss> also als ich das letzte mal gestern die Tesla specs ansah waren da 350gflops theoretische spitze . für intels neuere dual cores sinds 30gflops. graka is auch nicht unbedingt für alles und jedes geeignet. eher im gegenteil, anwendung is trotz CUDA recht limitiert. </klugscheiss> _________________ Yagl - yet another gameprogramming library |
|
Nach oben |
|
|
atari gesperrt
Anmeldungsdatum: 26.08.2007 Beiträge: 144
|
Verfasst am: 12.12.2007, 12:01 Titel: |
|
|
Zitat: |
man muss ihn nur zu nutzen lernen (und das ist alles andere als einfach...)
|
dann schreib mal hier in freebasic "asm" ein beispiel mit den float-befehlen , die in der grafikkarte enthalten sind.
vielleicht kann sich volta da mal austoben.
mfg |
|
Nach oben |
|
|
Bimi
Anmeldungsdatum: 03.12.2007 Beiträge: 66
|
Verfasst am: 12.12.2007, 13:15 Titel: |
|
|
atari hat Folgendes geschrieben: | Zitat: |
man muss ihn nur zu nutzen lernen (und das ist alles andere als einfach...)
|
dann schreib mal hier in freebasic "asm" ein beispiel mit den float-befehlen , die in der grafikkarte enthalten sind.
vielleicht kann sich volta da mal austoben.
mfg |
Genau das ist der Punkt!
Es wird erwartet das man die GPU exakt genau so verwenden kann wie ein FPU und das ist nun einmal nicht der Fall. Das Verfahren ist nicht so trivial als das es mit ein paar Zeilen Code abgedeckt wäre...
Es sind eben nicht einfach ein paar asm-Befehle - die GPU kann man mittels normaler ASM Befehle sowieso nicht erreichen. Woher sollte FB die Mnemonics kennen, wie sollte unterschieden werden ob ein Befehl nun an die CPU oder an die GPU geht?
Schon die FPU nutzt dazu einen Trick: FPU-Befehle sind für die CPU unbekannt und lösen eine Exception aus. Die FPU setzt sich genau an diesen ExceptionHandler und leitet damit die Opcodes an sich selbst weiter. Dieser Hanlder kann auch Software sein wenn keine FPU vorhanden ist - nur durch diesen Trick waren früher die FPU-Emulatoren möglich.
Eine GPU kann das jedoch nicht machen, das sie im Gegensatz zur FPU nicht auf der Northbrigde, sondern auf der Southbridge bzw. an der dort angedockten GraKa sitzt und somit keine direkte Verbindung zu CPU hat und sich dort an den Exceptionhandler andocken könnte.
Hinzu kommt das die GPU IMMER assynchron läuft, sozusagen ein fest eingebautes Multithreading.
Der Trick funktioniert ein wenig anders:
Man muss wissen wie die GPU z.B. eine Projektion berechnet um festzustellen das dieses Verfahren nicht nur für die Projektion von Bildern benötigt wird, sondern auch z.B. bei der Berechnung finiter Elemente.
Die GPU wird durch Listen Programmiert (wer früher mit dem Amiga gearbeitet hat, dem sind Copper Listen ein Begriff, funktioniert hier so ähnlich). Diese Befehlsliste wird auf der PCU zusammengebaut und dann in einen speziellen Speicherbereich auf der GraKa kopiert und dort die GPU "gezündet", die dann das Ganze ausführt - parallel zur CPU und zru FPU. Dafür brauche ich keine einzige Zeile Inlineassembler
Billiger kann man nicht an einen Vektorprozessor herankommen als durch eine GPU. Einsatzgebiete sind Molekularberechnungen, finite Elemente, Verschlüsselung.
Ein bekanntes Projekt in denen das gemacht wird ist z.B. Folding@home
Die Gründe warum das nicht in der Breite gemacht wird sind drei:
1. Ein solches Programm muss für eine bestimmte GPU massgeschneidert werden. ATI steuert seine GPU völlig anders an als z.B. NVidia, eine GF6 arbeitet etwas anders als eine GF7
2. Die GPU ist ein Spezialprozessor welche nur diejenigen Funktionen abbildet, welche auch benötigt werden. Sie kann nicht als allgemeine FPU verwendet werden. Bevor als eine Aufgabe durch eine GPU bearbeitet werden soll muss geprüft werden ob dies überhaupt möglich ist. Jede Aufgabenstellung muss analysiert und individuell Programmiert werden.
3. Wer braucht das eigentlich im normalen Alltag? Die Zocker nutzen die GPU sowieso schon sinngemäss und wohl kaum jemand rechnet mal über Nacht mal schnell eine Kernfusion aus. Es lohnt sich nur für Aufgabenstellungen, welche für eine FPU extreme Rechenzeiten bedeuten würde. Es macht keinen Sinn die GPU anzutriggern umd die Berechnung um den Faktor 20 zu beschleunigen, wenn ich dann von 20 Minuten Rechenzeit auf eine komme - man muss schon noch die Zeit der Implementierung dazurechnen.
Die GPU als hochparalle FPU einzusetzen ist eine Technik des high performance computings und keine Massensportart.
Wer mehr wissen möchte dem empfehle ich folgendes Buch:
"GPU Gems 2: Part IV - General-Purpose Computation on GPUs: A Primer. Addison Wesley Publishing Company, 2005" _________________ Rechtbehelf:
Rechschreibverfehlungen, Vergehen an der Deutschen Sprache sowie Stabwechselverbuchselungen unterliegen dem Urheberrecht, sind voll beabsichtigt und fördern das aufmerksame Lesen. |
|
Nach oben |
|
|
darkinsanity aka sts
Anmeldungsdatum: 01.11.2006 Beiträge: 456
|
Verfasst am: 12.12.2007, 15:46 Titel: |
|
|
NASM hat Folgendes geschrieben: |
G:\>nasm sgrafik.asm -f obj
sgrafik.asm:48: error: invalid segment override
sgrafik.asm:92: error: invalid segment override
sgrafik.asm:92: error: invalid effective address
|
Code: |
;Variablen kommen hierhin
;Globale Variablen werden mit PUBLIC VARIABLENNAME deklariert und dann noch mit z.B.:
;LibVersion DW 0013Dh ; DirectQB library version
;PUBLIC pqb.xresolution
;PUBLIC pqb.yresolution
;PUBLIC pqb.goffset
;PUBLIC pqb.BankSize
;pqb.xresolution DW 0
;pqb.yresolution DW 0
;pqb.goffset DW 0
;pqb.Banksize DW 0
;-------------------------------------
; pqb.pset setzt einen Pixel
;-------------------------------------
extern pqb.pset
;pqb.pset proc x:word, y:word, farbe:word
push ds
; Wenn der Pixel auserhalb des Bildschirms liegt, dann überspringen
cmp x, pqb.xresolution-1
jg SkipPixel
cmp x, 0
jl SkipPixel
cmp y, pqb.yresolution-1
jg SkipPixel
cmp y, 0
jl SkipPixel
; Die Berechnung des Offsets
mov AX, y
mov BX, pqb.xresolution
IMul BX
ADD BX, x
mov pqb.goffset, BX
; Benötigte Bank im VRAM berechnen
mov AX, BX
mov CX, pqb.Banksize
Idiv CX
; mit Hilfe der Variable bank die benötigte Bank im VRAM setzen
mov AX, 4F05h
mov BX, 0
mov DX, CX
mov CX, 0
int 10h
; Den Pixel setzen
mov as, [pqb.goffset]
mov es, ax
mov [A000h:es], [farbe]
; mov [A000h:pqb.goffset], farbe
SkipPixel:
pop ds
ret
;pqb.pset endp
;-------------------------------------
; pqb.point liest einen Pixel
;-------------------------------------
extern pqb.point
;pqb.point proc x:word, y:word
push ds
; Wenn der Pixel auserhalb des Bildschirms liegt, dann überspringen
cmp x, pqb.xresolution-1
jg SkipPoint
cmp x, 0
jl SkipPoint
cmp y, pqb.yresolution-1
jg SkipPoint
cmp y, 0
jl SkipPoint
; Die Berechnung des Offsets
mov AX, y
mov BX, pqb.xresolution
IMul BX
ADD BX, x
mov pqb.goffset, BX
; Benötigte Bank im VRAM berechnen
mov AX, BX
mov CX, pqb.Banksize
Idiv CX
; mit Hilfe der Variable bank die benötigte Bank im VRAM setzen
mov AX, 4F05h
mov BX, 0
mov DX, CX
mov CX, 0
int 10h
; Den Pixel auslesen
mov as, [pqb.goffset]
mov es, ax
mov ax, [A000h:es]
; mov AX, [A000h:pqb.goffset]
pop ds
ret
;pqb.point endp
|
danke für die Tipps.
geht leider immer noch nicht.
wenn NASM es akzeptieren würde, würde es dann das tun was ich haben will? |
|
Nach oben |
|
|
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 12.12.2007, 18:37 Titel: |
|
|
Das Register as gibts nicht.
NASM gibt dir doch wunderbare Fehlermeldungen aus, warum müssen andere das für dich berichtigen?
In Zeile 48 und 92 der gleiche Fehler.
Richtig wäre Code: | mov ax, [pqb.goffset] |
_________________
|
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|