     

                      ͻ
                       
                    
                     
   ͻ        ͼ
                  ۰
                  ۰
       ͼ   ۰
                                 ۰
                           ۰
                      ۰
                       ۰
                          ۰
                                        ۰ 
                                                   ۰
ͻ                              ۰
DIE WELT DES                                ۰
GESCHWINDIG-                     ۰
KEITSRAUSCHES                             
ͼ                   
   ͻ                                      
   PART IV                                     
   ͼ                                      


 Liebe Zielgruppe!

 Tja, wieder 'mal Ausfall, wieder Info, wieder ein neuer Teil von 'Assembler-
 Die Welt der Geschwindigkeitsrausches'. Voil, here we go:
 

 =-> VERGLEICHE
 --------------

 Nach logischen (OR, AND usw.) und arithmetischen Operationen (ADD usw.) wird 
 der Zustand des Statuswords, entsprechend dem Ergebnis, aktualisiert (siehe
 Part III). Will man bestimmte Werte miteinander vergleichen, kann man das
 mit CMP (Compare) Ziel, Quelle tun. Ziel und Quelle knnen wieder Bytes,
 Words, Speicherinhalte und Konstanten sein. Beispiele: CMP AL,AH; CMP AL,1h;
 CMP AX,BX; CMP [0080h],00h; CMP [0080h],AL und CMP [AX],BL. Beim Vergleich 
 der Werte wird die Quelle vom Ziel subtrahiert (damit werden die Flags ak-
 tualisiert), das Ergebnis der Subtraktion wird aber NICHT zurckgegeben, der
 Ziel- und Quellwert NICHT verndert.

 Beispiel: MOV AX,4240h    ; AH = 42h und AL = 40h
           CMP AL,AH       ; Intern (im Prozessor): SUB AL,AH
                             Extern (fr das Programm): AF = 1, da bertrag 
                                                        von Bit 3 nach 4
                                                        CF = 1, da berlauf
                                                        SF = 1, da das
                                                        Ergebnis negativ ist
 
 
 =-> SPRNGE
 -----------

 
 >Der unbedingte Sprung
 ----------------------

 Format:  JMP marke

 - das Programm wird bei 'marke' fortgesetzt
 - fr 'marke' knnen beliebige Adressen (8- und 16-Bit) durch Bytes, Words,
   Speicherinhalte und Konstanten angegeben werden
 - Beispiele: JMP 0100h         (springt nach CS:0100h (Programmanfang))
              JMP ES:0200h      (springt nach ES:0200h)
              JMP DS:DX         (springt nach DS:DX)
              JMP [1234h:5678h] (springt zur Adresse, die im Speicher unter
                                 1234h:5678h abgelegt ist)
              JMP [1234h]       (springt zur Adresse, die im Speicher unter
                                 CS:1234h abgelegt ist)


 >Die bedingten Sprnge
 ----------------------

 Blo nicht in's Koma fallen, wenn Ihr die Sprungbefehle seht. 
 Ihr kommt locker mit einem Drittel der unten aufgefhrten aus! 
 Ungefhr die Hlfte knnt Ihr vergessen, weil sie doppelt vorkommen, viele
 wird man nie einsetzen. 
 Ein groer Vorteil ist, da die Namensgebung logisch aufgebaut ist - man 
 sich seinen Sprungbefehl quasi selbst 'zusammenbasteln' kann. 
 
 Jeder Sprungbefehl fngt mit J (von [J]ump - springe) an. Kennt man jetzt
 das englische Wort fr 'grer', kann man sich denken, wie der Befehl fr
 - Springe, wenn grer - lautet.
 
 Beispiele:
 ----------
 - Springe, wenn grer -- Jump if Above (engl.) =-> JA ist der entsprechende
   Sprungbefehl, das 'if' wird einfach weggelassen.
 - Springe, wenn kleiner -- Jump if Below (engl.) =-> JB
 - Springe, wenn kleiner oder gleich -- Jump if Below or Equal =-> JBE

 Die zulssigen englischen 'Grundbegriffe', wie Below, Above und Equal, knnt 
 Ihr aus der Tabelle entnehmen.


 Vorzeichenlos (Vorzeichen, also + oder -, wird nicht beachtet)
 --------------------------------------------------------------  

 Befehl Springe, wenn...                                        Bedingung
    
 JA     grer                    (Jump if Above)               CF = 0 
                                                                und ZF = 0
 JAE    grer oder gleich        (Jump if Above or Equal)      CF = 0
 JB     kleiner                   (Jump if Below)               CF = 1
 JBE    kleiner oder gleich       (Jump if Below or Equal)      CF = 1 
                                                                oder ZF = 1
 JNA    nicht grer              (Jump if Not Above)           CF = 1 
                                                                oder ZF = 1
 JNAE   nicht grer oder gleich  (Jump if Not Above or Equal)  CF = 1
 JNB    nicht kleiner             (Jump if Not Below)           CF = 0
 JNBE   nicht kleiner oder gleich (Jump if Not Below or Equal)  CF = 0 
                                                                und ZF = 0
 JCXZ   CX=0                      (Jump if CX Zero)             CX = 0
 JECXZ  ECX=0 (erst ab 386er!)    (Jump if ECX Zero)            ECX = 0
 JE     gleich                    (Jump if Equal)               ZF = 1
 JC     gesetztem Carry-Flag      (Jump if Carry)               CF = 1
 JNC    Carry-Flag nicht gesetzt  (Jump if Not Carry)           CF = 0
 JNE    nicht gleich              (Jump if Not Equal)           ZF = 0
 JNP    Parity-Flag nicht gesetzt (Jump if No Parity)           PF = 0
 JNZ    nicht null                (Jump if Not Zero)            ZF = 0
 JP     Parity-Flag gesetzt       (Jump if Parity)              PF = 1
 JPE    Paritt gerade            (Jump if Parity Even)         PF = 1
 JPO    Paritt ungerade          (Jump if Parity Odd)          PF = 0
 JZ     null                      (Jump if Zero)                ZF = 1
 
 Wobei   JA = JNBE, denn   grer = nicht kleiner oder gleich
         JAE = JNB, denn   grer oder gleich = nicht kleiner
         JB = JNAE, denn   kleiner = nicht grer oder gleich
         JBE = JNA, denn   kleiner oder gleich = nicht grer
         JE = JZ,   denn   nicht gleich -> nicht null 
         JP = JPE,  denn   PF gesetzt -> gerade Paritt
         JNE = JNZ, denn   nicht gleich -> nicht null
         JNP = JPO, denn   PF nicht gesetzt -> ungerade Paritt
 
 
 Vorzeichenbehaftet (Vorzeichen werden beachtet)
 -----------------------------------------------
 
 Befehl Springe, wenn...                                        Bedingung
    
 JG     grer                    (Jump if Greater)             ZF = 0 
                                                                und SF = OF
 JGE    grer oder gleich        (Jump if Greater or Equal)    SF = OF
 JL     kleiner                   (Jump if Less)                SF <> OF
 JLE    kleiner oder gleich       (Jump if Less or Equal)       ZF = 1 
                                                                oder 
                                                                SF <> OF
 JNG    nicht grer              (Jump if Not Greater)         ZF = 1 
                                                                oder 
                                                                SF <> OF
 JNGE   nicht grer oder gleich (Jump if Not Greater or Equal) SF <> OF
 JNL    nicht kleiner             (Jump if Not Less)            SF = OF
 JNLE   nicht kleiner oder gleich (Jump if Not Less or Equal)   ZF = 0 
                                                                und SF = OF
 JNO    kein berlauf             (Jump if Not Overflow)        OF = 0
 JNS    positiv                   (Jump if Not Signed)          SF = 0
 JO     berlauf                  (Jump if Overflow)            OF = 1
 JS     negativ                   (Jump if Signed)              SF = 1   

 Wobei   JG = JNLE, denn   grer = nicht kleiner oder gleich
         JGE = JNL, denn   grer oder gleich = nicht kleiner
         JL = JNGE, denn   kleiner = nicht grer oder gleich
         JLE = JNG, denn   kleiner oder gleich = nicht grer
 
 
 =-> Praxis
 ----------

 Genug Theorie, hier ein praktisches Beispiel: Alle Grobuchstaben des
 Alphabets sollen ausgegeben werden.

 Der ASCII-Code fr 'A' ist 41h, fr 'B' = 42h, 'C' = 43h... und 'Z' = 5Ah.

 Hier das entsprechende Proggi:

 MOV AX,0E41                  ; Funktion 0Eh des Vidoeinterrupts (Zeichen 
                              ; ausgeben) soll aufgerufen werden -> AH = 0Eh
                              ; in AL steht der auszugebende ASCII-Code, da
                              ; wir mit 'A' (ASCII 41h) beginnen -> AL = 41h
 marke:                       ; 'marke' als Einsprungmarkierung
 INT 10h                      ; Videointerrupt aufrufen -> Zeichen ausgeben
 INC AL                       ; ASCII-Code um eins erhhen -> nchstes 
                              ; Zeichen
 CMP AL,5Ah                   ; ist das nchste Zeichen = 'Z' (ASCII 5Ah)
 JBE marke                    ; wenn das nchste Zeichen kleiner oder gleich
                              ; 'Z' ist: das nchste Zeichen ausgeben
 MOV AH,4Ch                   ; Funktion 4Ch (Programm beenden)
 INT 21h                      ; DOS-Funktionsinterrupt aufrufen


 So, das war's fr heute. Wer Lust hat, kann ja 'mal ein kleines Proggi
 schreiben, das alle Kleinbuchstaben ausgibt. Eines, das alle Ziffern (1-0,
 also 1234567890) und eins, das Gro- und Kleinbuchstaben im Wechsel
 ausgibt (also AaBbCc...Zz). Die Listings gibt's in Part V!

 
 Ŀ
  Wer mir eine (besser zwei) Disk(s) zusendet und das Stichwort 'Assembler'
  irgendwo auf/im Brief vermerkt, bekommt seine Disk(s) randvoll mit       
  SW/PD/FW-Tools (A86, D86...) zum Thema Assembler zurck. Dazu gibt's die 
  ASM-Kurs-Parts!                                                          
                                                                           
  Bei leerer Disk gilt: Rckporto und Rckumschlag nicht vergessen!        
 

 
 Master YODA (Manuel Mbes, Lahnstr.4, 06846 Dessau)
 
 
 NOTE: Ŀ
        Wer die letzten Parts des ASM-Kurses verpasst hat, sollte sich  
                                                                        
                              das nchste SKYLINE                       
                                                                        
        besorgen, da der erste Part dort erscheinen soll (natrlich mit 
         dem Einverstndnis von SolarDesign). Das SKYLINE-DiskMag be-   
          kommt Ihr z.B. bei KILLER TAIFUN (Addy siehe ADDY, logisch)   
                        oder auch bei meiner Wenigkeit.                 
       

 NOTE3: Die einzelnen Parts gibt's natrlich auch bei mir, gegen Disk, Rck-
        umschlag und Porto.

 NOTE2: Sollte jemand Fehler in meinen Geschreibsel finden, mich loben,
        korrigieren, oder beschimpfen wollen, soll er mir seine Meinung mit-
        teilen!

     

--> An alle Interessierten

Heute wollen wir uns mal ein bichen mit objektorientierter Programmierung
beschftigen, - oder nicht? Die Sache ist nicht schwer zu verstehen,der
Sinn relativ einleuchtend.Es geht darum,Daten und Code in einem "Objekt"
zu vereinen,was die Programme pflegeleicht,erweiterbar und verstndlich
werden lt.In gewisser Weise ist OOP wirklich etwas besonderes,weil es dem
Anwender einen groen Abstand von der Maschine ermglicht und ihn zum
Regisseur einer Sammlung von gut funktionierenden Objekten macht.

Nun aber zu den Tatsachen:

Nehmen wir einmal an,Jemand kme auf die Idee,einen Punkt zu programmieren,den
er mit den Cursortasten ber den Bildschirm bewegen kann.Ich gebe zu,nichts
weltbewegendes,eine Routine zur Tastaturabfrage,eine zum lschen und eine zum
bewegen, - kinderleicht.
Nach getaner Tat sitzt Herr Jemand vor seinem teuren Marken-PC und denkt:
Es wre doch schn,wenn man so einem Punkt beibringen knnte,sich selbst zu
bewegen,wenn die Cursortasten gedrckt werden.Man mte den Code fr Konstruk-
tion,Sichtbarkeit,Unsichtbarkeit,Bewegung und Tastatur dermaen zusammenfgen,
da das Objekt Punkt,ohne die Fhigkeit sich zu bewegen,gar nicht mehr denkbar
ist.
Damit sind wir bei des Pudels Kern.Fortan ist der "Punkt" fr uns ein Objekt,
da ber ganz bestimmte Eigenschaften, - Methoden - ,verfgt.Das heit,erst-
mal deklarieren wir es als Objekt,dann schreiben wir die Methoden.

Das ganze sieht in TP6.0 dann,in vereinfachter Form,ungefhr so aus:

Punkt = object
 x,y : integer;
 procedure Init(InitX,InitY); -> Hier wird der Punkt zum Punkt
 procedure Zeige;             -> Um den Punkt zu zeigen
 procedure Verstecke;         -> um den Punkt beim Verschieben zu verstecken
 procedure MoveTo;            -> um dem faulen Punkt Bewegung beizubringen
 function  HolTaste;          -> Tastaturabfrage
 procedure Drag;              -> ruft MoveTo und HolTaste zum Verschieben auf
 end;

Nachdem wir die Methoden dann mit Anweisungen gefllt haben,sieht unser Haupt-
programm etwa so aus:

 Punkt.Init (80,100);
 Punkt.Drag (Parameter fr die Anzahl der Pixel fr die Verschiebung);

Jetzt haben wir einen echten OOP-Punkt,der sich selbst verschieben kann.Booh,
ih! Echt Super !! Und nu'.Das wre auch ohne OOP gegangen.

Auch Herrn jemand wird es langsam langweilig.Zwar hat er seinem Punkt noch
so einiges beigebracht,z.B.bei jedem Tastendruck die Farbe zu ndern,aber
irgendwie bleibt der blde Punkt ein Punkt.Also ein neues Projekt,ein Kreis
mu her.Was ist ein Kreis eigentlich ? Ein Kreis ist ja auch nur ein groer 
Punkt,man knnte ihn also als einen etwas dickeren Nachkommen des Punktes
bezeichnen.Die Initialisierung und die Methoden Zeige und Verstecke mten
fr den Kreis wohl neugeschrieben werden,aber die Fhigkeit der Bewegung
und des Verschiebens,die knnte er von seinem Vater (Mutter) erben.
Gesagt,getan,Herr Jemand teilt seinem Computer mit,da er das Objekt Kreis
als Nachkomme des Objekts Punkt zu betrachten habe,und das bei dem Aufruf:
Kreis.Zeige geflligst ein Kreis gezeichnet wird.Ebenso wird beim Aufruf:
Kreis.Verstecke das Objekt Kreis versteckt,nur den ganzen anderen Rotz,
den kann sich Herr Jemand sparen.Das neue Objekt Kreis hat von seinem Vater
(Mutter) Punkt gelernt,sich selbst zu verschieben und seine Farbe zu wechseln.

Jetzt kommt Leben in die Sache.Das nchste Objekt,da Herr Jemand von Punkt
ableitet,ist ein Rechteck.Super !! Wow!!.Nun baut er noch eine kleine PD-Maus-
routine ein, - und siehe - nun kann er mit der Maus kleine Rechtecke verschie-
ben.Wenn er seinem Objekt Rechteck nun noch beibringt,zu verschwinden,wenn er
einen Doppelklick in der oberen linken Ecke macht,was hat er dann ? Richtig,
dann hat er fast sein eigenes Windows programmiert.....

Herr Jemand ist jetzt ziemlich stolz,zum einen auf den Urvater seiner Objekte,
den Punkt,zum anderen auf die bemerkenswerten Fhigkeiten der Punkt.Kinder.
Er hat einen groen Teil der objektorientierten Programmierung begriffen,und
wenn Interesse besteht,knnte man seine weiteren Erfolge in einer der nchsten
Platinum-Ausgaben verfolgen.

>>> Out of Memory

     

===> An NUL und alle anderen

    GESCHWINDIGKEITSGEWINN DURCH DIREKTES PROGRAMMIEREN DER GRAFIKKARTE

  Hi Nul,

  im letzten Platinum hattest Du einen Grundlagenkurs ber die Grafik-
  programmierung im 320x200x256-Modus verffentlicht. Dabei erwhntest Du,
  da das "Grafikprogrammieren" in BASIC weniger umstndlich wre, als in
  beispielsweise TURBO-PASCAL, und da Du die direkte Programmierung
  der Karte deshalb im Turbo nicht nur aus Geschwindigkeitsgrnden
  vorziehst.

  Ich stimme nicht mit Dir berein, da die Programmierung in Pascal
  umstndlicher ist, als in Basic. Zwar ist es in Turbo schwieriger, die
  Grafik im Standard-Modus 320x200 zu initialisieren (es gibt einen BGI-
  Treiber von Borland, der 320x200x256 bei nur einer Bildschirmseite
  bietet, wie es auch bei Basic blich ist, doch gibt es auer diesem
  auch welche, die bis zu vier Seiten ansprechen knnen), doch kann man,
  wenn man einmal im Modus ist, sehr viel einfacher arbeiten als in
  BASIC o...

  Der Vorteil der BGI-Treiber liegt zudem darin, da man fr fast jede
  Grafikkarte bei fast jedem Modus einen BGI-Treiber bekommt, der die
  jeweilige Grafikkarte sogar selbststndig erkennt und sie dementsprechend
  initialisiert. Zudem kann man dann immernoch die doch recht bequemen
  Turbo-Routinen zur Grafikgestalltung verwenden, ohne wissen zu men,
  um welche Grafikkarte es sich handelt oder in welchem Modus man sich
  eigentlich befindet (das ist ja fast so einfach wie Windows, oder?).

  Allerdings mu ich Dir zustimmen, da das direkte ansprechen der Grafik-
  karte schneller ist, als die Turbo-Pascal-Routinen. Um dies zu testen
  habe ich ein kleines Programm geschrieben, da folgende Ergebnisse
  lieferte:

    Setzen von 32000 Pixel mit PutPixel:                0,2197s
    "      "   "     "     "   MEM:                     0,1099s

    Zeichen von 32000 Linien aus 9 Pixeln mit Line:     1,3731s
    "       "   "     "      "   " "      "   MEM:      0,9337s


    Zeichen von 32000 Linen aus 200 Pixeln mit Line:    19,2239s
    "       "   "     "     "   "   "      "   MEM:     18,4000s

  Whrend beim setzen eines einzigen Pixels MEM sehr viel schneller
  war als PutPixel, wird der Abstand zwischen MEM und Line bei der
  zweiten Messung schon geringer. Whrend MEM fr die 9fache Arbeit
  ca. die 9fache Zeit gebraucht hat, konnte die TP-Procedure relativ
  gegenber der ersten Messung aufholen.

  Bei der dritten Messung zeigt sich, da der Unterschied zwischen
  TP-Procedure und -im Vergleich dazu recht aufwendig programmierten
  MEM Anweisung- relativ gering ist. Zudem sollen die Grafikroutinen
  von BP-7 noch schneller sein, als die von TP-6, soda der Unterschied
  wohl noch geringer ausfallen wird.

  Sollte man also ein Programm schreiben, bei dem es auf jede ns ankommt,
  sollte man auf keinen Fall die TP-Anweisungen benutzen, whrend
  komplexe Aufgaben sich viel einfacher und fast ohne Zeitverlust direkt
  mit TP-Anweisungen realisieren lassen.

  Am gnstigsten ist es jedoch, beide parallel zueinander zu benutzen.
  D.h. man initialisiert die Grafik zuncht mit INITGRAPH und spricht die
  Grafikkarte nur dann direkt an, wenn dies aus zeitlichen Grnden ntig ist.
  Zudem sollte man sich vor Augen fhren, da Turbo Pascal keine lahme
  Interpretersprache ist. Die TP-Listings werden so schon vor der Aus-
  fhrung in recht flotte Programme bersetzt. Da die Programmierer von
  TP keine "grnen Jungs" sind, kommt es vor, da selbstgeschriebene,
  unoptimierte und komplexe ASM-Programme langsamer sind als anstndig
  geschriebene Pascal-Programme.

  brigens lassen sich die meisten Pascal-Programme sehr einfach
  optimieren: Man nimmt fr jedes Ergebnis einer Rechenoperation, die
  mehrfach ausgefhrt wird, eine eigene Variable. Dies schafft meist
  einen ungeahnten Geschwindigkeitszuwachs. Zudem gibt es verschiedene
  Wege, ein und den selben Effekt zu erreichen. So kann man statt
  v:=v+1 auch INC(v) schreiben oder statt IF v=1 THEN v:=0 ELSE v:=1
  v:=ABS(v-1), um nur ein paar sehr simple Beispiele zu nennen.

***>Skyman/SKY-Arts<***

     
