Grundlagen über die Hardware

Zurück

Leider gehört zum Verständnis von Assembler auch ein wenig Theorie über die Hardware dazu. Keine Angst, dass Ganze ist doch recht interessant. Ich bin auch kein Lehrer, der nur sachlich irgendwo vorne vor sich hinredet (und man derzeit einschläft), sondern ich versuche das Ganze ein wenig schmackhaft zu präsentieren :) Ja und da wir nicht in der Schule sind, kann man sich nebenbei ruhig einen Kaffee, oder Sonstiges gönnen.


Wir werden die folgenden Bereiche mal näher unter die Lupe nehmen:

     - wie ein PC funktioniert
     - was niederwertige und höherwertige Bytes sind
     - was ein Stack ist
     - Zahlensysteme

Hört sich doch gar nicht so schrecklich an, oder?

 

1. Wie funktioniert denn nun eigentlich ein PC?

Ein Computer ist immer nach dem selben Prinzip aufgebaut. Es nennt sich "Von-Neumann-Architektur".
Man hat vielleicht schon mal davon gehört, dass ein Computer aus folgenden Teilen besteht:

     - Rechenwerk
     - Steuerwerk
     - Speicher
     - Register
     - Eingabeeinheit
     - Ausgabeeinheit

 

Das Rechenwerk

Man kann es eigentlich schon fast aus dem Namen herauslesen, um was es hier geht. Richtig, es handelt sich hier um einen Teil im Prozessor, der für Rechenoperationen und logische Entscheidungen (kleiner als, usw...) zuständig ist. Das Rechenwerk nennt man auch ALU (Arythmetik Logic Unit). Also grob übersetzt: "Mathematischer Logischer Abschnitt".

 

Das Steuerwerk

Auch hier kann man sich schon denken, worum es hier geht. Das Steuerwerk steuert Vorgänge. Als Vorgänge meine ich hiermit zum Beispiel das holen von Befehlen aus dem Speicher. Es schnappt sich also einen Befehl nach dem anderen aus dem Speicher und führt den Befehl mit Hilfe von anderen Teilen aus, wenn es nötig ist. Es steuert auch das Bussystem und schaut dass es nicht zu einem Datencrash kommt.

 

Der Speicher

Hier ist der Arbeitsspeicher gemeint, in dem sich eine Menge von Daten befinden können. Kommt immer ganz darauf an, wieviel MB gerade im Computer drinnen sind. Ich hab derzeit z.B. eine 256 MB RAM-Bank eingebaut. Ich weis, dass ist nicht gerade viel, aber man kommt damit aus :) Jedesmal, wenn ein Programm gestartet wird, muss der Programmcode mal in den Speicher geladen werden. Hier kann dann der Prozessor dann in aller Ruhe Variabeln, Befehle, usw... holen, wenn er sie braucht und wenn das Programm beendet wird, schmeißt er wieder alles vom Speicher raus, damit andere Programme Platz haben. Nicht nur Programme, sondern auch andere Sachen werden hier verwahrt. Wenn ich jetzt zum Beispiel die Taste X drücke, steht im Speicher drinnen, welche Taste ich gerade gedrückt habe. Auch das hier steht gerade im Speicher. Natürlich wird der Speicher nicht einfach blind verteilt, sondern jedem Programm wird ein eigener Bereich im Speicher zugewiesen.
Ein kleiner Test für die Praxis: Der Prozessor holt sich ja die Befehle aus dem Arbeitsspeicher. Wenn er also keinen Arbeitsspeicher hat, hat er keine Befehle und nix geht. Nehmt doch mal (auf eigene Gefahr) euren Rahmspeicher aus dem PC und dreht dann den PC auf. Keine Angst, im Normalfall wird der PC nicht kaputt. Beep, Beep, Beep, ... außer einem Beepen passiert nichts, da beim POST (Power On Self Test) bemerkt wurde, dass es keinen Platz gibt, wo man Befehle ablegen könnte.
Für das überprüfen ist übrigens der CMOS-Chip (der das BIOS enthält) zuständig. Was aber, wenn der Speicher nicht mehr für die ganzen laufenden Programme ausreicht? Ganze einfach, dann legt das Betriebssystem eine Auslagerungsdatei (SWAP-Datei) auf der Festplatte an, die einen Arbeitsspeicher simuliert. Also bräuchte man eigentlich nur soviel Speicher, wie das Betriebssystem für sich selbst benötigt. Zu beachten sei dabei, dass der Zugriff auf die Festplatte viel länger dauert, als auf eine RAM-Bank. So, nun sollte jeder wissen, warum der PC einen Speicher braucht.

 

Register

Register sind Speicher, die sich im Prozessor befinden. Da sie im Prozessor sind, müssen sie relativ klein sein. Doch wozu brauche ich nun Register im Prozessor, wenn ich ja einen Arbeitsspeicher habe. Nun ja, sie sind ersten die schnellsten Speicher, die es im Computer gibt, da sie sich ja direkt im Prozessor befinden und zweitens sind sie das Wichtigste beim Programmieren in Assembler. Warum? Das werde ich hier gleich erklären. Die Register hatten bis zum 286er Prozessor immer nur eine Größe von 16 Bit, seit dem 386er ist diese Größe aber glücklicherweise auf 32 Bit gestiegen. Diese Register haben alle einen eindeutigen Namen. Keine Angst, diese sind recht einfach zu merken. Bitte lasst euch von der Vielzahl der Register nicht abschrecken. Ich möchte hier nun mal die Arten der Register auflisten, die es im Computer gibt:

REGISTERARTEN

Universalregister

Segmentregister

Index- und Zeigeregister

Flagregister

Die Register werden im Folgenden alle beschrieben. Ich möchte hier gleich erwähnen, dass es nicht notwendig ist, alles an einem Tag zu lernen!!! Ich finde, das sollte man bei den Registern sogar meiden, da diese doch eine Fülle an Lernstoff bieten und es Anfängern wie uns nicht gerade leicht fällt, alles gleich zu verstehen. Wen man jedoch alles sofort versteht, kann man durchaus den ganzen Abschnitt an einem Tag durcharbeiten.

 

Universalregister

Die Universalregister umfassen 4 Register mit dem Namen A, B, C und D. Das ist leider noch nicht der vollständige Name. Hat das Register A z.B. 16 Bit wird es AX genannt und hat es 32 Bit, dann wird es EAX genannt. AX kann man dabei wieder in 2 mal 8 Bit unterteilen. Diese haben den Namen AH (A High) und AL (A Low). Das Gleiche gilt für die Register B, C und D. Ich weis, dass ist jetzt ein wenig verwirrend, aber das gibt sich mit der Zeit recht schnell. 

Hier eine kleine Grafik, um eine etwas bessere Vorstellung darüber zu bekommen, wie das jetzt mit den Bits in den Registern aussieht:

Bei einem 286er würde es nur ein AX Register geben, dass in AH und AL unterteilt werden kann. AH und AL haben hier jeweils 8 Bit. Man kann sie gemeinsam als AX, oder einzeln als AH und AL nutzen. Links sehen wir eine Erweiterung von 16 Bit, die es ab dem 386er Prozessor gibt. Das AX Register mit der Erweiterung wird dann EAX genannt, welches 32 Bit hat. Die Register EBX, ECX und EDX sind ebenfalls so aufgebaut.

 

Segmentregister

Um erklären zu können, welche Aufgabe diese Register haben, müssen wir das Thema "Speicher" mal genauer unter die Lupe nehmen. Befehle die im Speicher liegen, müssen ja eine Position haben. Diese Position nennt man Adresse. Beim Programmieren nennt man das Ganze "Zeiger". Ich zeige also auf eine bestimmte Stelle im Speicher.  Es gibt nun aber 2 verschiedene Arten von Adressen. Wir hätten da die "Physikalische Adresse" und die "Logische Adresse". Jetzt wundert man sich natürlich, warum man 2 Adressen braucht, um eine Adresse anzugeben. Ich muss ehrlich zugeben, dass ich am ersten Blick auch nicht genau wusste, was das soll, doch als ich dann weitergelesen habe, ist mir klar geworden, dass es unumgänglich ist. Warum das so ist, will ich  jetzt erklären:

Wie man an der Grafik sehen kann, sind die Speicherzellen "numeriert". Da die Nummer gleichzeitig die Adresse (diese wird "Physikalische Adresse" genannt) der Speicherzelle ist, können wir die Speicherstelle  recht einfach angeben, gäbe es da nicht ein kleines Problem. Aus Geschwindigkeitsgründen, besitzen Register diese Adresse. Da ein Register ja nur 16 Bit hat, haben wir nur 2 hoch 16, also 64 KB,  zur Adressierung zur Verfügung. Die Adressierung des Datenbusses hat aber 20 Bit. Das sind 2 hoch 20, also 1 MB. Befinden wir uns im "Real Mode", wie es z.B. unter DOS (nicht mit der Eingabeaufforderung in Windows verwechseln) ist, können wir die Adresse als 16 Bit Wert angeben. Unter Windows befinden wir uns jedoch nicht im "Real Mode" und müssen eine 20 Bit Adresse übergeben. Wie machen wir das denn nun? Der Speicher wird nun in 65.536 Paragraphen (Abschnitte) unterteilt, mit einer Größe von jeweils 16 Bit (64 KB). Die Paragraphenadresse gibt ein  Segment an und eine Stelle im Segment nennt man "Offset Adresse". Die Adresse wird immer im folgenden Format angegeben: Segmentadresse:Offsetadresse
Diese Adresse bezeichnet man nun als "Logische Adresse". Der Computer rechnet diese immer in die Physikalische Adresse um. Man multipliziert einfach die Segmentadresse mit 16 und zählt die Offsetadresse hinzu.

Wenn wir bei der Grafik hier von links oben zu zählen beginnen würden, würde die "Logische Adresse" folgend lauten: >> 1:B << , was übersetzt >> 1 Segment:Speicherzelle 11 << bedeutet. Das "B" deshalb, weil die Adresse im Hexadezimalen System angegeben wird (zu dem kommen wir später noch). Da die "Logische Adresse" aus 2 Werten besteht, brauchen wir natürlich auch 2 Register. Das ist der Punkt, wo die Segmentregister ins Spiel kommen. Insgesamt gibt es sechs Segmentregister, die ich hier (in kurzer Form) mal beschreiben will:

> CS (Codesegment-Register)
Enthält die Adresse des Segmentes, wo sich der Code eines Programmes befindet

> DS (Datensegment-Register)
Enthält die Adresse des Segmentes, wo sich Variablen, Strings, etc... eines Programmes befinden

> SS (Stacksegment-Register)
Das Register zeigt immer auf den Anfang des Stacksegmentes, wo Daten zwischengespeichert werden (Stack wird später noch erklärt)

> ES, FS, GS
Diese Register haben keine besondere Bedeutung und könne frei zur Adressierung verwendet werden

 

Index- und Zeigeregister

Diese Register dienen als Adressierung innerhalb eines Segmentes und es gibt davon 5 Stück. Ganz schön nervig die vielen Register, oder? - aber leider brauchen wir sie. Also "Fire up your brain" und weiter geht's :)
Ich werde die Register nun wieder in kurzer Form erklären:

SI (Source Index Register)
Diese Register wird verwendet, wenn man zum Beispiel eine Zeichenkette (String) kopieren will. Es wird verwendet, um die Quelle (Source) anzugeben.

DI (Destination Index Register)
DI tritt auch in Aktion, wenn man einen String kopieren will. Der einzige Unterschied zu SI ist, dass hier das Ziel (Destination) angegeben will.

BP (Base Pointer)
Mit diesem Zeiger können wird auf den Stack zugreifen.

SP (Stack Pointer)
SP zeigt immer auf die letzte Stelle im Stack, wo etwas gespeichert wurde.

IP (Instruction Pointer)
Dieser Zeiger zeigt immer auf die nächste Instruktion im Code-Segement, also dem Befehl, der als nächstes kommt bzw. ausgeführt wird.

 

Flagregister

Nun ist es zeit, mal kräftig zu jubeln, da wir uns dem letzten Register nähern, nämlich dem Flagregister, welches leider auch das Schwierigste ist. Ich glaube ich sollte hier mal erwähnen, was überhaupt ein Flag ist. Hört sich irgendwie nach einer Flagge an. Wer das glaubt, liegt da aber leider falsch. Ein Flag ist eigentlich nichts anderes, als ein Bit, das entweder gesetzt ist (1), oder gelöscht ist (0). Da wir nun wissen, was überhaupt ein Flag ist, können wir uns zum "Flagregister" vorwagen. Tja... wie kann man das erklären... hier werden die Ergebnisse von bestimmten Operationen gespeichert. Jetzt werden sie einige unter euch denken, wie ich mit 0 und 1 ein Ergebnis speichern kann. Da hat man nicht ganz unrecht damit. Unter Ergebnis wird hier etwas anderes verstanden. Ich werde hier mal ein kleines Beispiel erläutern, wobei ich mich hier gleich auf die Funktion des Sing-Flag beziehen werde. Angenommen wir würden dem Computer die Rechnung 3 minus 8 rechnen lassen, dann würde er das SF (Sign-Flag) auf 1 setzen. Warum? Das Sign-Flag wird gesetzt, wenn bei einer Rechnung (arithmetischen Operation genannt) ein negativer Wert herauskommt. Das Ergebnis ist hier also nicht -5, sondern es wird einfach nur überprüft, ob das Ergebnis der Rechnung negativ, oder positiv ist. Ich hoffe, dass nun jeder begriffen hat, was ein Flag ist, da ich wieder mal eine kurze Aufzählung mit Erklärung mache :)

CF (Carry-Flag)
Dieses Flag wird benutzt, wenn bei einer Addition, oder Subtraktion der Wertbereich für das Register überschritten wird. Wenn ich z.B. in einem 8 Bit Register eine 16 Bit Zahl speichern will, wird der "Wertbereich" überschritten und das Flag gesetzt (1).

PF (Parity-Flag)
Dieses Flag wird heute nicht mehr benutzt, da die Funktion von I/O (Input/Output) Bausteinen übernommen wird. Es wurde früher zur überprüfung auf übertragungsfehler verwendet.

AF (Auxiliary-Flag)
Dieses Flag wird gesetzt, wenn bei einer BCD-Operation (BCD = Binary Coded Decimal) eine übertragung von Bit 3 nach Bit 4 stattfindet.

ZF (Zero-Flag)
Hier kann man es eigentlich erraten, welche Aufgabe dieses Flag hat. Das Flag wird gesetzt, wenn das Ergebnis der letzten Operation 0 war.

SF (Sign-Flag)
Dieses Flag haben wir oben bereits besprochen. Um keine halben Sachen zu machen, werde ich hier nochmals die Funktion dieses Flags beschreiben. Das Flag wird gesetzt, wenn das Ergebnis einer logischen, oder arithmetischen Operation negativ ist.

TF (Trap-Flag)
Beim Prozessor gibt es einen sogenannten Einzelschrittmodus, welcher in der Fachsprache als "Single Step Mode" bezeichnet wird. Wenn der Prozessor sich in diesem Modus befindet, führt er nach jedem Befehl ein spezielles Unterprogramm aus. Das könnte z.B. eine Fehlerüberprüfung sein.

IF (Interrupt-Flag)
Dieses Flag wird im Grunde vom Programmierer gesetzt, oder gelöscht. Wenn das Flag gesetzt (1) ist, dann werden Unterbrechungen des Programmes (z.B. über die Tastatur) ignoriert.

DF (Direction-Flag)
Wenn dieses Flag gesetzt ist, dann werden alle String-Operationen von rechts nach links durchgeführt, anstatt der Standardrichtung die von links nach rechts geht.

OF (Overflow-Flag)
Dieses Flag wird gesetzt, wenn nach einer Rechnung das Vorzeichenbit zerstört wurde. Falls ein übertrag erfolgt, wird das Carry-Flag gesetzt.

Ja, das war's. Ich muss zugeben, dass ich beim Flagregister alles ein wenig mickrig geschrieben habe, doch dass liegt daran, dass ich derzeit noch nicht mehr darüber gelernt habe und es als Anfänger in Assembler auch noch nicht wirklich benötigt habe. Das soll aber nicht bedeuten, dass das so bleibt. Ich werde diesen Abschnitt erweitern, sobald ich das benötige Wissen dafür erlangt habe.

 

*** Bonusmaterial ***

Da wir hier am Ende für den Abschnitt Register angekommen sind und es nicht gerade leicht ist, alles zu verstehen, empfehle ich, die folgende Seite mal durchzulesen. Ich habe sie im Internet auf einer anscheinend chinesischen (oder japanischen) Seite gefunden, welche aber in englisch geschrieben wurde. Ich hoffe nur, dass diese Seite keinem Copyright unterliegt und ich sie hier in diesem Tutorial einfügen darf.

Die Quelle der Seite:
http://www.culturecom.com.hk/HTML/intro/intro_d_e_9.html (nicht mehr online)

Hier klicken, um die Seite offline zu lesen

 

Eingabeeinheit

Zur Eingabeeinheit zählen beim PC z.B. die Tastatur, die Maus, oder ein Joystick. Hier gibt es natürlich auch noch andere Geräte, die man zur Eingabeeinheit zählen kann. Die Eingabeeinheit besteht also aus den Geräten, mit denen man Informationen in den Computer eingeben kann.

 

Ausgabeeinheit

Die Ausgabeeinheit ist das Gegenteil der Eingabeeinheit. Zur Ausgabe zählen alle Geräte, mit denen Informationen ausgegeben werden können. Solche Geräte können z.B. Drucker, oder Bildschirm sein.

 

Niederwertige und höherwertige Bytes

Ein 16 Bit Register besteht aus 2 mal 8 Bit, also aus 2 Bytes. Diese 2 Bytes bekommen nun die Bezeichnung "niederwertiges Byte" und "höherwertiges Byte". Nun stellt sich natürlich die Frage, welches das Niedere und welches das Höhere ist.

15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00

höherwertiges Byte

niederwertiges Byte

Wie man sieht, gehen wir von rechts nach links. Ganz rechts befindet sich das niederwertige Byte und ganz links ist das höherwertige Byte. Diese 2 Bytes zusammen, nennt man auch ein WORD. Ein WORD kann 2 hoch 16 Zustände annehmen, also 65.536. Ein Register mit 32 Bit besteht aus 2 Words, also einem DWORD (Double Word). Soviel zu den Bytes, doch der Vollständigkeit halber, möchte ich auch noch die Bits erwähnen. Ein Byte besteht ja aus 8 Bits. Hier gibt es auch ein höherwertiges Bit und ein niederwertiges Bit. Wie man sich denken kann, steht das niederwertige Bit ganz rechts und das höherwertige Bit ganz links.

7 6 5 4 3 2 1 0

 

Der Stack

Der Stack ist nichts anderes, als eine Art Schrank, mit lauter Schubladen. Wenn wir etwas kurz ablegen wollen, dann geben wir es auf den Stack. In Assembler heist das dann PUSH. Man kann es sich dann wieder zurückholen, wenn es benötigt wird. Das Zurückholen heist in Assembler POP. Aha... der Stack ist also eine Schublade, wo man was POPPEN (nicht falsch verstehen ;)) und PUSHEN kann. Damit man sich jetzt auch was darunter vorstellen kann, hab ich wieder eine kleine Grafik (eher Tabelle) dazu erstellt:

STACK

1
2
3
 
 

Angenommen, diese Grafik oben wäre unser Stack, dann sehen wir hier, dass in dem Stack 3 Werte abgelegt wurden. In der ersten Schublade liegt der Wert 1, in der 2ten der Wert 2 und in der 3ten der Wert 3. Nun kann man ja diese Werte nicht irgendwie in den Stack geben. Das funktioniert natürlich nach einem System, dem "LIFO Prinzip". Was ist denn nun bitte ein LIFO Prinzip??? LIFO steht für Last In First Out, was auf gut Deutsch bedeutet: Was zuletzt reingekommen ist, kommt als Erstes wieder raus. Nun wissen wir, in welcher Reihenfolge wir die 3 Werte ablegen müssten, damit sie so, wie oben in der Grafik zu sehen, eingeordnet werden würden. Zuerst kommt die 3, dann die 2 und am Ende die 1 in den Stack. Ja... das war's auch schon über den Stack. Ich glaube nicht, dass es kompliziert war, oder? - Darüber könnte man nun streiten. Den Stack zu benutzen, ist die eine Sache, aber ihn richtig zu benutzen, ist wieder eine andere Sache :) Es gibt in Assembler Unterprogramme, die Werte auf dem Stack ablegen und sich dann auch wieder holen. Das heißt, dass wir nicht einfach irgendwann was rauflegen können, da sonst das Unterprogramm unseren Wert rausholen würde. Wir müssen unseren Wert also vorher vom Stack wegnehmen, bevor das Unterprogramm sich wieder seine eigenen Werte holen will. Das ist nun schon komplizierter, aber dazu mehr, wenn es soweit ist :)

 

Zahlensysteme

Nun kommen wir zu einem der vielleicht wichtigsten Themen am Computer, nämlich den Zahlensystem. Das Wort Computer kommt ja von dem englischen Wort "compute", was soviel wie errechnen, berechnen bedeutet. Ein Computer ist nun mal nichts anderes als eine Rechenmaschine. Ob man es glaubt, oder nicht, der Computer kann eigentlich nicht wirklich rechnen, in dem Sinne, wie wir es verstehen. Er weis nicht einmal, dass nach 9 die 10 kommt. Er folgt nur einem System, dass nach bestimmten Regeln funktioniert, eben einem Zahlensystem. Vielleicht habt ihr schon mal was von der ASCII Tabelle gehört. ASCII steht für American Standard Code for Information Interchange. Wenn ich jetzt auf der Tastatur die Taste 1 drücke, dann schickt der Tastaturchip dem Prozessor den binären Tastencode. Der Computer schaut nun in der ASCII Tabelle nach, für welches Symbol dieser Code steht und verarbeitet dann dieses Symbol weiter. Somit ist eine 1 genau so ein Symbol, wie ein A, oder ein B. Es gibt für den Computer nur ein System, das "Binäre Zahlensystem". Er kann natürlich auch im Hexadezimalen- ,oder Dezimalsystem rechnen, was aber nur so aussieht, als ob, da er im Inneren wieder im Binären System rechnet. Beim Zählen, geht man nach einem bestimmten System vor, welches wir uns mal ansehen wollen.

a) Das Dezimalsystem
Unsere Zahlen, haben die folgenden Symbole: 0 1 2 3 4 5 6 7 8 9 0
Es sind deshalb 10 Symbole, weil der Mensch 10 Finger hat, und noch heute gerne damit rechnet :) Die Symbole dafür sind übrigens im Mittelalter entstanden. 

Wir dürfen unsere Zahlen nicht als Zahlen, sondern als Symbole sehen. Man könnte ja statt der 1 auch ein A schreiben. Trotzdem würde das beim Zählen nichts ändern. Wir haben nun halt eben nur ein anderes Symbol: 0 A 2 3 4 5 6 7 8 9  Die Zahl 10 würde dann eben die Form A0 annehmen. Trotzdem behält sie einen Wert, mit dem wir etwas anfangen können. Doch warum genau kommt eigentlich nach der 9 die 10 und nicht 11, oder warum kommt nach 99 100 und nicht A00? Es sind ja alles nur Symbole. Das ist deshalb so, weil die Symbole nach einem bestimmten System aneinandergereiht werden. Ich will es mal durch die folgende Grafik veranschaulichen:

Wie wir sehen, gibt es bei den Symbolen eine Rangordnung, was bedeutet, das z.B. das Symbol 2 einen niedrigeren Wert, als das Symbol 9 hat. Im Fall 1 sehen wir eine Taschenrechneranzeige, die den Wert 1 auf der Einerstelle anzeigt. Im 2ten Fall sehen wir den Wert 10. Nun will ich erklären, wie man genau mit dem System an den Wert kommt. 
Die Taschenrechneranzeige, die wir hier sehen, besitzt 9 Stellen. Diese werden von rechts nach links benutzt. Wir beginn ganz rechts an der ersten Stelle, unserer Einerstelle. Hier wird beim Zählen immer das Symbol mit der nächsthöheren Rangordnung angezeigt, bis man beim letzten Symbol, der 9 angekommen ist. Danach fängt man wieder bei dem Symbol mit der niedrigsten Rangordnung an, setzt aber zuvor die linke Stelle, in unserem Fall die 10er Stelle, um ein Symbol höher, also eine 1, womit wir beim Fall 2 wären. Hier wurden bei der Einerstelle alle Zeichen einmal angezeigt, womit die links davon liegende Stelle (die Zehnerstelle) um eine Rangordnung erhöht wurde und das Symbol 1 anzeigt. Kommt dann irgendwann mal die Zehnerstelle beim letzten Symbol, der 9, an, dann wird diese wieder auf 0 gesetzt und die Stelle links daneben, also die Hunderterstelle, um das Symbol mit der nächsten Rangordnung, der 1, erhöht:

0 0 0 0 0 0 1 0 0

Nun wissen wir, wie der Computer beim Zählen im Dezimalsystem vorgeht und wir haben somit auch die Grundlagen, um die anderen Zahlensystem zu verstehen, da hier nur andere Symbole verwendet werden. Vielleicht hat man schon mal was über die Basis eines Zahlensystems gehört. Die Basis ist immer die Anzahl der Symbole, die es in dem Zahlensystem gibt. In Assembler wird eine Dezimale Zahl immer mit einem d am Schluss gekennzeichnet, was so aussehen kann: 100d

Ja, dass war es auch schon zum Thema Dezimalsystem. Es ist wichtig zu wissen, dass unsere Zahlen für den Computer nichts anderes als Symbole sind, da wir uns sonst etwas schwerer tun würden, um die nächsten Zahlensysteme zu verstehen.

 

b) Das Hexadezimalsystem

Im Hexadezimalen System ist die Basis 16, womit wir wissen, dass es hier 16 Symbole gibt:
(Mit den Fingern kommen wir hier übrigens nicht mehr weiter, es sei denn, wir rechnen auch noch mit den Zehen *g*)

0 1 2 3 4 5 6 7 8 9 A B C D E F

Wir zählen also von 0 bis F und dann wird die Stelle links von uns um eine Rangordnung, erhöht. Es ist eigentlich immer das gleiche System. Nach F kommt also 10, was im Dezimalen den Wert 16 hätte. 

An dem nächsten Beispiel, will ich demonstrieren, wie wir eine Hexadezimale Zahl ins Dezimale umrechnen können. Wir wissen, dass die Basis des Hexadezimalen Systems 16 ist. Man muss jetzt nur die richtige Potenz, also die 16, nehmen und schon kann man umrechnen. Angenommen, wir wollen die Zahl 1FA3 umrechnen, dann benötigen wir die Potenzen von 16 hoch 0 bis 16 hoch 3.

160 = 1
161 = 16
162 = 256
163 = 4096

Das Ergebnis tragen wir von rechts nach links  in eine Tabelle ein und schreiben darunter unsere Hexadezimale Zahl.

4096

256

16

1

1

F (15)

A (10)

3

Wir haben uns nun eine Tabelle gemacht, und multiplizieren nun einfach die Zahlen der oberen Zeilen mal dem Wert der darunterliegenden Zeile und Zählen dann alles zusammen.

3 * 1 = 3
16 * 10 (A) = 160
256 * 15 (F) = 3840
4096 * 1 = 4096

Zusammengezählt ergibt das dann
8099, womit wir schon unseren Dezimalwert hätten :)

Der Vollständigkeit halber, werde ich auch noch erklären, wie wir von einer Dezimalen Zahl auf eine Hexadezimale Zahl umrechnen. Wenn wir das Ganze als Gleichung betrachten würden, müssten wir eigentlich nur dividieren und wir hätten es. Jetzt darf man wieder mal jubeln, denn es steckt auch nicht mehr dahinter :) Wir müssen einfach nur unsere Zahl durch die Basis des System dividieren, welches wir haben wollen und den Rest umwandeln. Im Hexadezimalen, haben wir, wie schon gesagt, 16 als Basis. Nehmen wir uns mal unsere Zahl 8099 her:

Rechenvorgang:
8099 / 16 = 506,1875
506 * 16 = 8096 REST:
3

Somit hätten wir schon mal unsere erste Zahl, die 3. Nun gehen wir immer weiter, bis wir nicht mehr dividieren können. Das Weitergerechnet wird übrigens immer mit dem letzten Ergebnis der Division, welches immer abgerundet wird.

506/16 ERGEBNIS: 31,625 REST:
10 (A)
31/16  ERGEBNIS: 1,9375 REST: 15 (F)
1      REST
1

Von unten nach oben gelesen, haben wir dann wieder unsere Hexadezimale Zahl 1FA3! In Assembler wird eine Hexadezimale Zahl am Ende immer mit einem h gekennzeichnet. Das könnte so aussehen: 1FA3h.

 

c) Das Binärsystem

Jetzt widmen wir uns dem Rechensystem des Computers, dem Binären Zahlensystem. In diesem System gibt es nur 2 Symbole, nämlich 0 und 1. Mann nennt sie auch Dualzahlen. Das Zählen funktioniert wieder nach dem gleichen System, wie wir es beim Dezimalsystem und beim Hexadezimalsystem hatten:

0000
0001
0010
0011
0100
0101
0110
0111
1000
...

Nun kommen wir wieder zum Umrechnen. Probieren wir mal eine die Binäre Zahl 1001 in eine Dezimalzahl umzuwandeln. Die Basis in diesem System ist 2, deshalb benötigen wir bei 4 Stellen, die Potenzen 2 hoch 0 bis 2 hoch 3.

20 = 1
21 = 2
22 = 4
23 = 8

8 4 2 1
1 0 0 1

Hier brauchen wir nicht zu multiplizieren, da es unnötig wäre, da 8*1=8 , 1*1=1, 4*0=0, ... was bedeutet, dass wir einfach nur die oberen Zahlen zusammenzählen müssen, wo eine 1 darunter steht:

- unter der 1 ist eine 1 deshalb +1
- unter der 2 ist eine 0, sie wird nicht dazugezählt
- unter der 4 ist eine 0, sie wird nicht dazugezählt
- unter der 8 ist eine 1, deshalb +8

Das Ergebnis ist 8+1, was 9 ergibt. Unsere Binäre Zahl 1001 ist im Dezimalen eine 9. Nun könnten wir die Dezimale ins Hexadezimale umrechnen, usw...
Das Zurückrechnen von einer Dezimalen in eine Binäre, funktioniert genau so, wie im Hexadezimalen:

Rechenvorgang:
9/2=4,5
4*2=8 REST: 1

Das machen wir nun wieder, bis wir nicht mehr dividieren können:

4/2 ERGEBNIS: 2 REST 0
2/2 ERGEBNIS: 1 REST 0
1   REST: 1

Von unten nach oben gelesen ergibt das wieder unsere ursprüngliche Binäre Zahl 1001. In Assembler werden binäre Zahlen immer mit einem b am Ende gekennzeichnet. Das könnte so aussehen: 1001b.

So, dass war's auch schon wieder zum Thema Zahlensysteme. Ist doch gar nicht so schwer, wenn man mal das Grundsystem verstanden hat. Es gäbe jetzt auch noch das Octale Zahlensystem, auf welches ich jetzt aber nicht näher eingehen möchte, da man sich sowieso schon denken kann, wie das Umrechnen, Zählen usw... funktioniert. Das Einzige was man braucht, ist die Basis. Im Octalen ist die Basis 8.

[Letzte Änderung: 02. März 2009]