Tutorials

Assemblerkurs 1 Tutorial

Einloggen
Benutzername:
Passwort:

Passwort vergessen?
Kostenlos
Anmelden
anzeigen
Assemblerkurs 1
Assembler

2545 - javadomi - 06.02.2006 21:52 Uhr - Version: 2 - - verlinken als BB-Code


0. Vorvorwort:
Ich zeige in diesen Workshop, wie man mit den
Borland Turbo Assembler arbeitet und ich beziehe
mich natürlich auf die Computer, die fast jeder
haben sollte, also ein x86. Ich habe jedenfalls
einen Intel Processor, aber ich weiß nicht, wenn
ihr ein anderen habt, dann kann da was nicht
funktionieren, aber sollte eigentlich schon, wenn
es x86er sind, man weiß ja nie. Man sollte sich
QuickBasic 7.1 downloaden, dort ist alles drin.


1. Vorwort:
Da es mein erster Kurs ist, werde ich praktisch
bei Null anfangen. Die Vorraussetzung ist, dass
ihr den Turbo Assembler von Borland (TASM) oder
einen anderen, wie z.B. den Mikro Assembler
von Microsoft habt. Aber bei den Micro Assembler
werden wahrscheinlich ein paar Syntaxfehler auftreten,
weil ich euch hier zeige, wie man mit den TASM
arbeitet. Und da werden auch die Aufrufe für das
kompilieren und linken anders aussehen. Es ist empfehlenswert, wenn ihr
euch mit den Computern schon etwas auskennt, muss
nicht unbedingt sein, weil wir fangen bei Null an.
Außerdem wäre es hilfreich eine andere Sprache
zu beherrschen, weil man es dann besser verstehen
kann. Assembler sollten nur kluge Köpfe lernen,
weil es sich für Noobs nicht lohnt. Assembler ist
sehr, sehr schwer. Jetzt kommt der theoretische
Teil ran, also über den Aufbau des Computers, usw.
Ok, das war das Vorwort.


2. Der Computer:
Das Herz des Computers ist der Processor,
die sogenannte CPU, wie jeder wissen sollte. Da
werden die Assembler Befehle verarbeitet. Das
funktioniert folgendermaßen: Die CPU ist in zwei
Teile geteilt. Der erste Teil holt sich die Assembler
Befehle aus den Arbeitsspeicher und gibt sie in
eine Warteschlange des Processors. Der zweite
Teil holt sich dann die Befehle und verarbeitet
sie. Dabei rechnet er, je nach Befehl, arthematische
Operationen aus, spricht den Arbeitsspeicher an,
sendet Daten an Drucker, usw... Bis jetzt brauchen
wir nichts mehr über den Processor zu wissen. Nun
kommen wir zum Arbeitsspeicher, nämlich den RAM.
Jede Speicherstelle im RAM wird Adresse genannt,
die frei beschrieben und gelesen werden kann. Wie
jeder weiß, wird das RAM nach dem Ausschalten des
Computers gelöscht oder auch in meiner Sprache
freigegeben.


3. Real Mode Adressierung:
Der Real Mode ist der Processor Modus, in dem DOS
normalerweise arbeitet, und er hat nur 16 Bit. Der
Speicher wird im Real Mode nicht linear, sondern
über einen Offset adressiert. Dazu gibt es ein
Segment. Das Segment wird mit 16 mal genommen
und der Offset wird dazuaddiert, dann hat man
eine physikalische Adresse. Ein Segment ist hier
64 KB (Kilobyte) groß. Daraus können wir schließen,
dass die Offsetadresse zwischen 0h und ffffh groß
sein muss. Hinter einer Hexadezimalen Zahl wird
immer ein "h" hinten rangehängt; das macht die
Sache einfacher. Die Adresse wird immer in dieser
Form geschrieben xxxx:xxxx. Es ist zu beachten,
dass sie in der hexadezimalen Schreibweise
geschrieben wird. Wer nicht weiß, was das
Hexadezimales Zahlensystem ist, den kann ich
das hier kurz erklären. Unser Zahlen System,
was wir eigentlich in der Schule am Anfang lernen,
hat die Basis 10, also die Zahlen von 0 - 9,
logischerweise. Das Hexa-Zahlensystem hat aber
die Basis 16, also nach der 9 kommt ein Buchstabe,
oder auch genauer gesagt der Buchstabe A. Dann im
Alphabet: A - F. Also darauf schließt man, dass
das Hexa-Zahlensys von 0 - F geht, wobei A = 11,
B = 12, C = 13, D = 14, E = 15 und F = 16 ist.
Ist doch einfach, oder? Und wenn man im Hexa z.B.
17 ausgeben will, also die Zahl nach F, dann schreibt
man 10h hin. Darauf folgt natürlich: 11h = 18, 12h = 19,
13h = 20, ..., 19h = 26, 1Ah = 27, 1Bh = 28, usw. So,
ich hoffe, dass ihr es verstanden habt. Wenn nicht,
dann fragt nochmal irgendwo nach, wie z.B. in einen
Mathe Buch.


4. I/O Ports:
Oder auch deutsch: E/A Ports, also Ein-, Ausgabeports.
Wenn wir Peripheriegeräte ansprechen wollen, also z.B.
Tastatur oder Drucker, oder z.B. Grafikkarte dann
benutzen wir dafür diese E/A Ports. Ich werde jetzt auf
das Thema nicht länger eingehen, weil ich es später
besser erklären kann. Jetzt ist es noch zu früh dazu.
Noch ein bisschen Theorie, dann können wir bereits das
erste Programm schreiben.


5. Register:
Die Register vom Processor haben eigentlich immer breite
von 16 Bit Integer-Variable Breite, die normalerweise von
0h - ffffh gehen, also von 0 bis 65535. Sie sind viel
schneller als normale Variablen, die im RAM abgelegt
sind, weil sie ja ein Hauptbestandteil des Processors
sind. Es gibt verschiedene Arten von Registern:

Allgemeine Register: Sie sind frei verwendbar. Es gibt:

AX = Der Akkumulator heißt das Ding. Er kann in zwei
8 Bit Register aufgeteilt werden, und diese heißen
dann AH und AL (Erklärung folgt später). Dieses Register
wird zur Abwicklung von 16 Bit Multiplikationen und
Divisionen verwendet. Für die 8 Bit Multiplikation
und Division werden nur die Register AH und AL verwendet.

BX = Das Base Register lässt sich bei Speicherzugriffen
als Zeiger verwenden. Natürlich lässt es sich auch in
zwei 8 Bit Register unterteilen. Also in BL und BH.

CX = Das Count Register dient als Zähler für Schleifen.
Es lässt sich in CL und CH aufteilen.

DX = Das Daten Register wird von Befehlen, die die I/O
Ports ansprechen und dient dazu auch Rechenoperationen
durchzuführen. Es lässt sich ebenfalls in DL und DH
aufteilen.

Wie ihr bereits gesehen habt, lassen sich alle allgemeinen
Registerin zwei 8 Bit große Register aufteilen. Also wenn
in AX sich zumBeispiel die Zahl 12CDh aufhält, dann steht
in AH 12h und in AL steht dann CDh. Ist ganz einfach, oder?
Mann nimmt das X von AX weg, dann setzt man dafür ein H für
Heigh Register oder ein L für Low Register ein. Also darauf
folgt, dass das Heigh Register die zwei linken Hexadezimalzahlen
nimmt und das Low Register die am Ende stehenden. Es gibt noch
weitere Register, nämlich die Segment Register. Ihr wisst ja
von den Kapitel Real Mode Adressierung, was Segmente sind.
In diesen Registern wird nun die Segment Adresse des Segments
angegeben. So kann man in ein beliebigen Segment Daten ablegen.

CS = Pointer auf Codesegment. Dort stehen eigentlich die Assembler
Befehle. Aber später kann man da auch ein bisschen tricksen.

DS = Pointer auf das Daten Segment, wo die Variablen stehen. Also
Pointer ist ein Zeiger.

ES = Darf auf jedes beliebige Segment im RAM zeigen.

SS = Zeigt auf das Stacksegment, wo die Daten zwischen gespeichert
werden können.

Es gibt noch den Base Pointer (BP), SI und DI, die meistens für
Stringbefehle eingesetzt werden. Aber es gibt noch den IP (Instruction
Pointer), der den Programmierern nicht zusteht. Dort steht ein Zeiger,
der auf die nähste Anweisung im Programm steht. Wenn man den verändert,
dann kann was schlimmes passieren, wenn du Glück hast, dann nur ein
Absturz, aber wenn du kein Glück hast, dann... Noch ist von den SP,
den Stack Pointer abzuraten. Da kann das gleiche passieren.


6. Interrupts:
Interrupts sind einfache Unterprogramme. Davon gibt es zwei Arten,
Nämlich die Software Interrupts und die Hardware Interrupts. Die
Hardware Interrupts werden aufgerufen, wenn auf einen Peripherie
Gerät eine Taste gedrückt wird. Wie z.B. auf den Drucker. Doch man
kann einige Hardware Interrupts ausschalten, indem man einfach den
Assembler Befehl cli benutzt, und fürs einschalten sti. Die Software
Interrupts sind eigentlich nur die Unterroutinen. Sie kommen vom
Bios und von DOS. Diese werden in Assembler mit den Befehl int
aufgerufen. Meistens haben diese Interrupts mehrere Funktionen. Die
Funktionsnummer wird meistens im AH Register angegeben (siehe Kapitel
Register). Das war vorerst Schluss mit der Theorie.


7. Interrupt 10h Funktion 9h:
Das hier wird unser erstes Beispielprogramm sein. Keine Sorge, es
wird alles genau erklärt.

1
2
3
4
5
6
7
8
9
10
11
12
13
MODEL TINY ;So beginnen COM-Dateien
CODE SEGMENT ;Beginn des Code Segments
ASSUME CS:CODE;Zuweisung an CS
ORG 100h ;Startadresse für COM-Dateien
start: ;Startlabel
MOV AX,0903h ;Funk. 9h, ASCII-Zeichen 2
MOV BX,15 ;Farbcode Weiß, also 15
MOV CX,1 ;1 Zeichen ausgeben
INT 10h ;Zeichen auf Bildschirm schreiben
MOV AX,4C00h ;Funk. 4Ch
INT 21h ;DOS-Exit
CODE ENDS ;Ende des Code Segments
END start ;Ende des Programms


Nun, um das Programm zu kompilieren und Linken, braucht ihr den TASM,
der mit QuickBasic 7.1 mitgeliefert wird. Am besten ihr speichert die
Datei im QB7.1 Ordner unter test.asm, und dort macht ihr eine
Batchdatei (compile.bat) und in sie schreibt ihr folgendes rein:
TASM /T/L test.asm
LINK /t test
Nun, wenn ihr sie startet, also die Batchdatei, dann erscheint etwas,
wo ihr was eingeben müsst, also die OBJ Datei, die vom assemblieren
rausgekommen ist, ist schon eingegeben. Dort schreibt ihr gar nichts
rein. Alles lasst ihr einfach so, einfach immer Enter drücken. Nun
hab ihr eine Ausführbare Com Datei. Das /t beim linken sagt aus, dass
es eine kleine Datei sein soll, also eine Com Datei.
Wenn ihr dann die Datei startet, dann erscheint ein schönes Herz.
Windows macht manchmal die Dos Fenster ganz schnell weg, deshalb solltet
ihr das per Batch oder Dos aufrufen. Doch wie funktionierts? Ganz
simpel: Das Programm benutzt die Funktion 9h des Interrupts 10h.
Diese Funktion gibt ein ASCII Zeichen aus, ohne die Cursor Position zu
verändern. AH ist hier die Funktionsnummer, also 9, AL das ASCII Zeichen,
BL die Farbe, BH, die Bildschirmseite und CX, wie oft das Zeichen
ausgegeben wird. Hier nochmal eine ganz genaue Erläuterung zum Programm:
Zeile 1: Gibt das Speichermodell an. Coms dürfen nur TINY benutzen.
Für normale Exe Dateien gibt es
SMALL: Codeseg und Dataseg sind zusammen kleiner 64 KB
MEDIUM: Code ist größer als 64 KB, Summe aller Datasegs ist kleiner als 64 KB
COMPACT: ein Codeseg, mehrere Datasegmente
LARGE: Mehrere Code Segmente > 64 KB
HUGE: alles kommt in Frage
Z.2: Anfang von Codeseg. Hier sollten die Befehle des Programms stehen
Z.3: CS soll auf Codeseg zeigen
Z.4: Anfangs Adresse ist CS:100h, das ist die Offset schreibweise. Am
anfang der Coms steht noch etwas ffh langes am Anfang. Ist aber nur für
Betriebssystementwickler relevant.
Z.5: Das ist ein Label, wie es in anderen Programmiersprachen den auch
gibt. Zu den kann man durch ein jmp Befehl springen.
Z.6: Hier wird das ASCII Zeichen und die Funktionsnummer angegeben.
Das Register teilt sich ja in zwei 8 Bits. AH ist die Funktionsnummer,
also 09h und AL 03h, das ASCII Zeichen.
Z.7: Damit teilen wir den BX 0015 ein. 00 ist BH, die Bildschirmseite und
BL die Farbe 15. Mit dieser Methode spart man ein paar Microsekunden
Zeit.
Z.8: CX wird der Wert 1 zugeteilt, sodass das Zeichen nur einmal an der
selben Stelle ausgegeben wird.
Z.9: Ruft den Interrupt 10h auf, der das Herz ausgibt.
Z.10+11: Beendet das Programm vollständig. Wenn man das nicht macht,
dann führt dein Programm die Befehle nach deinen Programm aus und
das ist sehr gefährlich. Du solltest das immer machen.
Z.12: Ende Codesegment
Z.13: Ende vom Programm


8. Der Befehl MOV:
Es ist wohlmöglich der wichtigste Befehl in Assembler. Die Syntax
ist ganz einfach zu lernen: mov Ziel, Quelle. Hier gibt es
jetzt einige Varianten zu diesen Befehl:

mov ax,0903h
Eine Konstante wird den Register AX zugewiesen.

mov ax,bx
Der Inhalt von bx wird den Register ax zugewiesen.

mov bx,[0B001h]
bx wird der Inhalt der Speicherstelle DS:0B001h zugewiesen.

mov bx,es:[0B001h]
Nennt sich Segment Override. bx wird der Inhalt der Speicherstelle
ES:0B001h zugewiesen.

Ende:
So, ich habe euch Einbisschen zu Assembler gezeigt, aber das ist
erst die Nummer 1. Also später zeige ich euch noch weitere Varianten
mit den MOV Befehl, ein paar neue Interrupts, die Bitverknüpfungen,
usw. Bis dahin könnt ihr mit den mov Befehl rumspielen, aber auf keinen
Fall auf IP oder SP zugreifen. Siehe in den Kapiteln nochmal nach.
Ansonsten wünsche ich dir noch viel Spaß.


Mitglieder-Kommentare


Es sind leider noch keine Einträge vorhanden!

Nur registrierte Mitglieder könnten einen Kommentar schreiben.

Melde dich doch ganz einfach an, es ist kostenlos. :-)