Home |
Sitemap |
8086 Assembler:
|
| Dies ist eine Sammlung von älteren Assemblerunterlagen zur MS-DOS-Programmierung, die vielleicht dem Einen oder Anderen nützlich sein könnte. Die Programmierungsbeispiele sind für den Microsoft Macro Assembler Version 4.00 von Microsoft codiert. Diese Version 4.00 stammt von 1985 und erzeugt 16-bit-Code.
Die gebrachten Programmbeispiele lassen sich nach kleinen Änderungen auch mit dem moderneren Microsoft Assembler ML.EXE bis mindestens zur Version 6.14 erfolgreich umwandeln und linken. Dabei müssen sie u.a. die Direktive „.MODEL TINY“ erhalten. Ein wenig darüber steht auf der Seite „Assemblieren und Linken für .COM-Dateien beim MASM 4.00 und beim ML - Assembler“. Die erzeugten MS-DOS-Programme sind sehr kurz. Das fertige Beispielprogramm (frage.com) ist gerade mal 216 Bytes lang! Die Verfahren funktionieren unter Windows 98, Windows XP, Windows VISTA und vermutlich auch unter weiteren Versionen von Windows. Microsoft liefert bei VISTA und angeblich auch bei Windows 7 einen deutschen 16-Bit-Tastaturtreiber mit. Um ihn zu nutzen, muss man in der Datei
%SystemRoot%\system32\autoexec.nt eintragen: LH KB16 GR,,%SystemRoot%\system32\keyboard.sys 4DOS ist eine komfortable Alternative zu COMMAND.COM und CMD.EXE. Allerdings werden von 4DOS unter XP, VISTA und wohl auch Windows 7 die langen Dateinamen im MS-DOS-Stil angezeigt. 4DOS 7.50 und sein Nachfolger 4dos 8.00 sind Freeware und lassen sich aus dem Internet herabladen. Vom gleichen Hersteller wie 4DOS kommt „Take Command®“. Dessen Freeware-Version Take Command/LE bietet den Benutzungskomfort von 4DOS und kommt mit langen Dateinamen zurecht. Das Program ist für Windows XP und seine Nachfolger gechrieben.
|
8086 Assembler, Adressbildung |
Zurück zur Assemblerauswahl |
ADRESSE (Adressbildung)Segmentanteil * 16d + Offsetadresse = physikalische Adresse [16 bit]*16d->[20 bit] [16 bit] [20 bit] Segmentanteil *16 1011 0000 1111 1100 + Offsetanteil 0000 0001 1100 1101 ------------------------------------------------- = physikalische Adresse 1011 0001 0001 1000 1101
SegmentregisterDer 8086 und der 8088 verwenden 20-bit-Adressen für die Speicheradressierung. Somit können sie bis zu 1 Megabyte Speicher adressieren. Die Register und die Adressfelder aller Instruktionen sind jedoch nur 16 bit lang. Immer, wenn auf den Speicher zugriffen wird, liefert das Programm eine 16 bit lange Adresse. Weitere 16 bit der Adressbildung werden aus dem Segmentregister bezogen. Diese werden um 4 Bits (1 Halbbyte bzw. 1 Nibble) nach links verschoben und auf die 16 Bits Adressanteil des Programmes aufaddiert, um die wirkliche Speicheradresse zu bilden. Der Inhalt der Segmentregister kann verändert werden, so dass ein Zugriff auf jede Speicheradresse möglich ist. Die Segementregister sind Spezialregister. Es gibt je eines für
Man tendiert dazu, den Inhalt der Segmentregister am Beginn des Programmes mit Daten zu versorgen und sie im Programmablauf möglichst nicht zu verändern.
MOV AX,DATASEG
MOV DS,AX ;Set value of Data segment
ASSUME DS:DATASEG ;Tell assembler DS is usable
.......
MOV AX,PLACE ;Access storage symbolically by 16 bit address
Im vorstehenden Programmbeispiel weiß der Assembler, dass keine Besonderheiten vorliegen, da die Maschine von sich aus das DS-Register zur Adressbildung für den normalen Zugriff auf Daten verwendet. Falls man im obigen Beispiel ES statt DS für den Datenzugriff verwenden möchte, müsste man es gesondert angeben. Vor der MOV-Anweisung, die auf die symbolische Adresse SPACE zugreift, würde eine vorgestelltes ES der Maschine mitteilen, dass hier ES anstelle von DS zur Adressbildung zu verwenden ist. Einige Konventionen erleichtern den Umgang mit den Segmentregistern. Handelt es sich beispielsweise um eine COM-Programm (und nicht um eine EXE-Programm), haben alle vier Segmentregister den gleichen Inhalt. Das Programm läuft vollständig in einem Bereich von 64 kB ab. Wenn erforderlich, kann man diesen Adressraum verlassen, muss es aber nicht. Adressierungsarten
Annahmen bei Auslassung von Angaben zur Verwendung der Segment-Register (default rules for which segment registers are used) zur Adressbildung:
|
|||||||||||||||||||||||||||||||||||||||||||||||||
Namenskonventionen
|
Zurück zur Assemblerauswahl |
Ein Name ist eine Abfolge von Zeichen bestehend aus Buchstaben, Ziffern und den folgenden Sonderzeichen: Unterstrich (_), Prozentzeichen (%), Fragezeichen (?), Dollarzeichen ($), dem at-Zeichen bzw. Klammeraffen (@) und dem Punkt (.). Folgende Regeln gelten:
|
Registerbeschreibung |
Zurück zur Assemblerauswahl |
8086 Assembler: Ablaufsteuerung |
Zurück zur Assemblerauswahl |
Hier geht es um
CALL, RET, INT, IRET, JMPAchtung, CALL und INT schieben Adressinformationen auf den Stack. RET und IRET entfernen diese Informationen wieder vom Stack.Um System-Funktionen aufzurufen, wird der INT-Befehl benutzt. Man muss nicht wissen, wie dies genau funktioniert, sondern man kann hier "kochbuchartig" vorgehen. Die Übergabe von Steuerungsanweisungen (CALL, RET, JMP) erfordert ein gewisses Verständnis. Sie können so klassifiziert werden:
Bedingter Sprung (Conditional jump)Die verschiedenen Sprungbedingungen sind eher verwirrend. Hier eine Übersicht:
JZ bedeutet was es sagt: verzweige bei gesetztem Zero-bit
JNZ bedeutet was es sagt: verzweige, wenn das Zero-bit nicht gesetzt ist
JG größer: bedeutet "wenn die vorzeichenbehaftete
Differenz positiv ist"
JA über (above): bedeutet "wenn die nicht vorzeichenbehaftete
Differenz positiv ist"
JL kleiner (less): bedeutet "wenn die vorzeichenbehaftete
Differenz negativ ist"
JB unter (below): bedeutet "wenn die nicht vorzeichenbehaftete
Differenz negativ ist"
JC carry: ist das Gleiche wie JB
JP verzweige bei gesetztem Paritätsflag (even)
JPE parity even: ist das Gleiche wie JP
JNP verzweige bei nicht gesetztem Paritätsflag (odd)
JPO parity odd: ist das Gleiche wie JNP
JCXZ verzweige wenn CX den Inhalt 0 hat.
JECXZ verzweige wenn ECX den Inhalt 0 hat. Der Befehl wurde mit
dem 386er Prozessor eingeführt.
Für .COM-Programme bis einschließlich 80286er Prozessor gilt, dass alle anwendbaren bedingten Verzweigungen automatisch DIRECT, NEAR und SHORT sind. Das bedeutet: Man kann nicht weiter als 128 Bytes entfernt vor oder zurück verzweigen. Ab dem 80386er Prozessor entfällt die genannte Entfernungsbeschränkung. Für „Verzweige wenn“ Jcc kann „Jcc“ sein: Ohne Vorzeichen (unsigned):
JA größer als CF=0 und ZF=0 (wie JNBE) JAE größer oder gleich CF=0 (wie JNB und JNC) JB kleiner als CF=1 (wie JNAE und JC) JBE kleiner als oder gleich CF=1 und ZF=1 (wie JNA) JC Carry Flag gesetzt CF=1 JNA nicht größer als CF=1 und ZF=1 (wie JBE) JNAE nicht größer/gleich CF=1 (wie JB und JC) JNB nicht kleiner CF=0 (wie JAE und JNC) JNBE nicht drunter/gleich CF=0 und ZF=0 (wie JA) JNC kein Übertrag CF=0 Mit Vorzeichen (signed): JG größer ZF=0 und SF=OF (wie JNLE) JGE größer/gleich SF=OF (wie JNL) JL kleiner SF<>OF (wie JNGE) JLE kleiner/gleich ZF=1 und SF<>OF (wie JNG) JNG nicht größer ZF=1 oder SF<>OF (wie JLE) JNGE nicht größer/gleich SF<>OF (wie JL) JNL nicht kleiner SF=OF (wie JGE) JNLE nicht kleiner/gleich ZF=0 und SF=0 (wie JG) JNO kein Überlauf OF=0 JNS positv SF=0 JO Überlauf OF=1 JS negativ SF=1 Sonstige: JCXZ CX-Register gleich 0 JE gleich ZF=1 (wie JZ) JNE nicht gleich ZF=0 (wie JNZ) JNZ nicht null ZF=0 JNP keine Parität PF=0 (wie JPO) JP Parität PF=1 (wie JPE) JPE gerade Parität PF=1 (wie JP) JPO ungerade Parität PF=0 (wie JNP) JZ null ZF=0 (wie JE) SchleifenHierzu gehören LOOP, LOOPE, LOOPNE, LOOPNZ, LOOPZ.allgemeine Syntax: cc siehe bei Jcc. Die Bedingung bezieht sich auf die Dekrementierung von CX. Verwendungen:LOOP für Schleifen.LOOPE und LOOPZ, um in Schleifen nach Werten ungleich 0 zu suchen. LOOPNE und LOOPNZ, um in Schleifen nach Werten gleich 0 zu suchen. |
8086 Assembler,
|
Zurück zur Assemblerauswahl |
Eine typische Verwendung zeigt der nachfolgende Ausschnitt: Beim Aufruf des Programmes wird ein Parameter mitgegeben. In Abhängigkeit vom mitgegebenen Parameter verzweigt das Programm. Maßgebend für das Verzweigungsziel ist das
erste (häufig auch das einzige) Zeichen des Parameters.
BATch Control Program Vers.:29.10.95
batc ? Eingabe J/N im Dialog
Errorlevel bei Ausgang: 0 nach J od.Y, 1 nach N, 3 nach ^C
batc W prompted mit <-'
batc B Warmboot
batc Cx setzt Randfarben (EGA/VGA) x=0...F, vergl. batc F
batc E... Ausgabe ESC... zum Bildschirm (z.B. für ANSI-Treiber)
batc F Anzeige Farbpalette auf Bildschirm.
batc J setzt Errorlevel auf 0
batc K Keycode anzeigen
batc M Verwendung als more-Filter, Aufruf hinter |
batc N setzt Errorlevel auf 1
batc P... Textausgabe auf Drucker LPT1. Anleitung: batc P
batc R Resetbefehl fuer Drucker an LPT1 (BIOS)
batc S Zeichenvorrat zum Bildschirm
batc V Zeigt den Inhalt des Video-State-Buffers
batc xx VGA auf xx Zeilen/Seite, 25 / 28 / 43
batc Y Anzeige diverser Systeminformationen
Die dafür zuständige Programmierung wird nachfolgend gezeigt. Mit den ersten vier Befehlen mov al,byte ptr cs:fcb+1 lea di,btab ;befehlstabelle mov cx,lbtab ;deren laenge repne scasb wird festgestellt, ob der erste Buchstabe des beim Programmaufruf mitgegebenen Parameters in der Tabelle 'MYWV42BCDEFPRS?NJK ' enthalten ist. Ist er enthalten, erfolgt eine Verzweigung zur Marke w1, andernfalls geht es zur Marke hilfe- dort wird die oben dargestellte kurze Bedienungsanleitung am Bildschirm gezeigt. Ganz wichtig: Das Registerpaar CX enthält die Position des übereinstimmenden Zeichens in der Tabelle, und zwar von hinten gezählt. Ab dem Merkmal wohin beginnt eine Verzweigungsadresstabelle. Sie enthält alle in Frage kommenden Zieladressen, ist jedoch genau andersherum angeordnet wie die Tabelle btab der möglichen Aufrufparameter. Beim Merkmal w1 erhält das DI-Registerpaar die Adresse des Sprungzielen und der Sprung wird ausgeführt. Das verwendeten Unterprogramm prmsg stellt den nachfolgenden Text auf dem Bildschirm dar. Das Macro dbl definiert eine Textzeile mit abschließendem Zeilenwechsel.
|