Assemblersprache
Eine Assemblersprache ist eine Programmiersprache, mit der dem Computer direkt mitgeteilt werden kann, was er tun soll. Eine Assemblersprache ist fast genau so wie der Maschinencode, den ein Computer verstehen kann, außer dass sie Wörter anstelle von Zahlen verwendet. Ein Computer kann ein Assemblerprogramm nicht wirklich direkt verstehen. Er kann das Programm jedoch leicht in Maschinencode umwandeln, indem er die Wörter des Programms durch die Zahlen ersetzt, für die sie stehen. Ein Programm, das dies tut, wird als Assembler bezeichnet.
Programme, die in Assemblersprache geschrieben sind, bestehen in der Regel aus Anweisungen, die kleine Aufgaben sind, die der Computer ausführt, wenn er das Programm ausführt. Sie werden Instruktionen genannt, weil der Programmierer sie benutzt, um dem Computer Anweisungen zu geben, was er tun soll. Der Teil des Computers, der den Anweisungen folgt, ist der Prozessor.
Die Assemblersprache eines Computers ist eine Low-Level-Sprache, was bedeutet, dass sie nur für die einfachen Aufgaben verwendet werden kann, die ein Computer direkt verstehen kann. Um komplexere Aufgaben ausführen zu können, muss man dem Computer jede der einfachen Aufgaben, die Teil der komplexen Aufgabe sind, mitteilen. Beispielsweise versteht ein Computer nicht, wie ein Satz auf seinem Bildschirm ausgedruckt werden kann. Stattdessen muss ihm ein in Assembler geschriebenes Programm sagen, wie er all die kleinen Schritte ausführen soll, die zum Drucken des Satzes gehören.
Ein solches Versammlungsprogramm würde aus vielen, vielen Anweisungen bestehen, die zusammen etwas tun, das einem Menschen sehr einfach und grundlegend erscheint. Das macht es für Menschen schwer, ein Versammlungsprogramm zu lesen. Im Gegensatz dazu kann eine höhere Programmiersprache eine einzige Anweisung wie PRINT "Hallo, Welt!" haben, die dem Computer sagt, dass er all die kleinen Aufgaben für Sie ausführen soll.
Entwicklung der Versammlungssprache
Als Informatiker zum ersten Mal programmierbare Maschinen bauten, programmierten sie diese direkt in Maschinencode, d.h. in eine Reihe von Zahlen, die dem Computer Anweisungen gaben, was er zu tun hatte. Das Schreiben von Maschinensprache war sehr schwierig und dauerte sehr lange, so dass schließlich Assemblersprache entwickelt wurde. Assemblersprache ist für einen Menschen leichter zu lesen und kann schneller geschrieben werden, aber sie ist für einen Menschen immer noch viel schwieriger zu benutzen als eine höhere Programmiersprache, die versucht, die menschliche Sprache nachzuahmen.
Programmierung in Maschinencode
Um in Maschinencode zu programmieren, muss der Programmierer wissen, wie jede Anweisung in binärer (oder hexadezimaler) Form aussieht. Obwohl es für einen Computer einfach ist, schnell herauszufinden, was Maschinencode bedeutet, ist es für einen Programmierer schwierig. Jede Anweisung kann mehrere Formen haben, die für Menschen alle nur wie ein Haufen Zahlen aussehen. Jeder Fehler, den jemand beim Schreiben von Maschinencode macht, wird erst dann bemerkt, wenn der Computer das Falsche tut. Es ist schwierig, den Fehler herauszufinden, weil die meisten Menschen nicht erkennen können, was Maschinencode bedeutet, wenn sie ihn anschauen. Ein Beispiel dafür, wie Maschinencode aussieht:
05 2A 00
Dieser hexadezimale Maschinencode weist einen x86-Computerprozessor an, 42 zum Akkumulator hinzuzufügen. Es ist für eine Person sehr schwierig, ihn zu lesen und zu verstehen, selbst wenn diese Person den Maschinencode kennt.
Stattdessen Assemblersprache verwenden
Bei der Assemblersprache kann jede Anweisung als ein kurzes Wort geschrieben werden, das als Mnemonik bezeichnet wird, gefolgt von anderen Dingen wie Zahlen oder anderen kurzen Wörtern. Die Mnemonik wird verwendet, damit sich der Programmierer nicht die genauen Zahlen im Maschinencode merken muss, die benötigt werden, um dem Computer zu sagen, dass er etwas tun soll. Beispiele für Mnemoniken in Assembler sind Addieren, das Daten hinzufügt, und Bewegen, das Daten von einem Ort zum anderen bewegt. Da "mnemonisch" ein ungewöhnliches Wort ist, wird stattdessen manchmal, oft fälschlicherweise, die Phrase Anweisungstyp oder nur Anweisung verwendet. Die Wörter und Zahlen nach dem ersten Wort geben weitere Informationen darüber, was zu tun ist. Zum Beispiel könnten die Dinge, die auf ein Addieren folgen, sagen, was zwei Dinge zusammen zu addieren sind, und die Dinge, die auf ein Verschieben folgen, sagen, was zu verschieben und wohin es zu stellen ist.
Zum Beispiel kann der Maschinencode im vorigen Abschnitt (05 2A 00) in Assembler als geschrieben werden:
Assembler erlaubt es Programmierern auch, die eigentlichen Daten, die das Programm verwendet, auf einfachere Weise zu schreiben. Die meisten Assemblersprachen haben Unterstützung für die einfache Erstellung von Zahlen und Text. Im Maschinencode müsste jede verschiedene Art von Zahlen, wie positive, negative oder dezimale, manuell in binäre umgewandelt werden, und Text müsste Buchstabe für Buchstabe als Zahlen definiert werden.
Die Assemblersprache bietet eine so genannte Abstraktion des Maschinencodes. Bei der Verwendung von Assembler müssen Programmierer nicht im Detail wissen, was Zahlen für den Computer bedeuten; der Assembler findet das stattdessen heraus. Die Assembler finden das stattdessen heraus. Mit Assemblersprache kann der Programmierer tatsächlich immer noch alle Funktionen des Prozessors nutzen, die er mit Maschinencode nutzen könnte. In diesem Sinne hat die Assemblersprache eine sehr gute, seltene Eigenschaft: Sie hat die gleiche Fähigkeit, Dinge auszudrücken wie das, was sie abstrahiert (Maschinencode), und ist gleichzeitig viel einfacher zu benutzen. Aus diesem Grund wird Maschinencode fast nie als Programmiersprache verwendet.
Disassemblierung und Fehlerbeseitigung
Wenn die Programme fertig sind, sind sie bereits in Maschinencode umgewandelt, so dass der Prozessor sie tatsächlich ausführen kann. Manchmal jedoch, wenn das Programm einen Fehler (Irrtum) enthält, wollen Programmierer in der Lage sein zu erkennen, was jeder Teil des Maschinencodes tut. Disassembler sind Programme, die dem Programmierer dabei helfen, indem sie den Maschinencode des Programms zurück in Assembler transformieren, was viel leichter zu verstehen ist. Disassembler, die Maschinencode in Assembler umwandeln, tun das Gegenteil von Assemblern, die Assemblersprache in Maschinencode umwandeln.
Computer-Organisation
Um zu verstehen, wie Computer organisiert sind, wie sie auf einem sehr niedrigen Niveau zu arbeiten scheinen, ist ein Verständnis dafür erforderlich, wie ein Assemblerprogramm funktioniert. Auf der einfachsten Ebene haben Computer drei Hauptteile:
- Hauptspeicher oder RAM, der Daten und Befehle enthält,
- einem Prozessor, der die Daten verarbeitet, indem er die Anweisungen ausführt, und
- Input und Output (manchmal verkürzt auf I/O), die es dem Computer ermöglichen, mit der Außenwelt zu kommunizieren und Daten außerhalb des Hauptspeichers zu speichern, so dass er die Daten später wieder zurückholen kann.
Hauptspeicher
In den meisten Computern ist der Speicher in Bytes aufgeteilt. Jedes Byte enthält 8 Bit. Jedes Byte im Speicher hat auch eine Adresse, die eine Zahl ist, die angibt, wo sich das Byte im Speicher befindet. Das erste Byte im Speicher hat eine Adresse von 0, das nächste eine Adresse von 1 und so weiter. Die Unterteilung des Speichers in Bytes macht ihn byteadressierbar, da jedes Byte eine eindeutige Adresse erhält. Die Adressen von Byte-Speichern können nicht verwendet werden, um auf ein einzelnes Bit eines Bytes zu verweisen. Ein Byte ist der kleinste Teil des Speichers, der adressiert werden kann.
Auch wenn sich eine Adresse auf ein bestimmtes Byte im Speicher bezieht, können Prozessoren mehrere Bytes Speicher in einer Reihe verwenden. Die häufigste Verwendung dieser Funktion besteht darin, entweder 2 oder 4 Bytes in einer Reihe zu verwenden, um eine Zahl, normalerweise eine ganze Zahl, darzustellen. Einzelne Bytes werden manchmal auch zur Darstellung von ganzen Zahlen verwendet, aber da sie nur 8 Bit lang sind, können sie nur 28 oder 256 verschiedene mögliche Werte enthalten. Bei Verwendung von 2 oder 4 Bytes in einer Reihe erhöht sich die Anzahl der verschiedenen möglichen Werte auf 216, 65536 bzw. 232, 4294967296.
Wenn ein Programm ein Byte oder eine Anzahl von Bytes in einer Reihe verwendet, um etwas wie einen Buchstaben, eine Zahl oder etwas anderes darzustellen, werden diese Bytes als Objekt bezeichnet, weil sie alle Teil derselben Sache sind. Auch wenn alle Objekte in identischen Speicherbytes gespeichert sind, werden sie so behandelt, als hätten sie einen "Typ", der angibt, wie die Bytes zu verstehen sind: entweder als ganze Zahl oder als Zeichen oder als ein anderer Typ (wie ein nicht ganzzahliger Wert). Man kann sich Maschinencode auch als einen Typ vorstellen, der als Anweisungen interpretiert wird. Der Begriff "Typ" ist sehr, sehr wichtig, weil er definiert, was mit dem Objekt gemacht werden kann und was nicht und wie die Bytes des Objekts zu interpretieren sind. Zum Beispiel ist es nicht zulässig, eine negative Zahl in einem Objekt mit positiver Zahl zu speichern, und es ist nicht zulässig, einen Bruch in einer ganzen Zahl zu speichern.
Eine Adresse, die auf ein Multi-Byte-Objekt zeigt (ist die Adresse eines Multi-Byte-Objekts), ist die Adresse des ersten Bytes dieses Objekts - das Byte, das die niedrigste Adresse hat. Nebenbei bemerkt, eine wichtige Sache, die man beachten sollte, ist, dass man den Typ eines Objekts - oder auch nur seine Größe - nicht an seiner Adresse erkennen kann. Tatsächlich kann man nicht einmal anhand des Typs eines Objekts sagen, um welchen Typ es sich handelt, wenn man es betrachtet. Ein Assemblerprogramm muss im Auge behalten, welche Speicheradressen welche Objekte enthalten und wie groß diese Objekte sind. Ein Programm, das dies tut, ist typsicher, weil es nur Dinge mit Objekten macht, die auf ihrem Typ sicher sind. Ein Programm, das das nicht tut, wird wahrscheinlich nicht richtig funktionieren. Beachten Sie, dass die meisten Programme eigentlich nicht explizit speichern, was der Typ eines Objekts ist, sondern dass sie nur konsistent auf Objekte zugreifen - dasselbe Objekt wird immer als derselbe Typ behandelt.
Der Verarbeiter
Der Prozessor führt Instruktionen aus (führt sie aus), die als Maschinencode im Hauptspeicher gespeichert werden. Die meisten Prozessoren können nicht nur zur Speicherung auf den Speicher zugreifen, sondern verfügen auch über einige kleine, schnelle Speicherplätze fester Größe zur Aufnahme von Objekten, mit denen gerade gearbeitet wird. Diese Räume werden als Register bezeichnet. Prozessoren führen in der Regel drei Arten von Befehlen aus, obwohl einige Befehle eine Kombination dieser Typen sein können. Nachstehend finden Sie einige Beispiele für jeden Typ in der Assemblersprache x86.
Anweisungen, die Speicher lesen oder schreiben
Die folgende x86-Assembleranweisung liest (lädt) ein 2-Byte-Objekt aus dem Byte an Adresse 4096 (0x1000 in hexadezimaler Schreibweise) in ein 16-Bit-Register namens "ax":
In dieser Assemblersprache bedeuten eckige Klammern um eine Nummer (oder einen Registernamen), dass die Nummer als Adresse zu den zu verwendenden Daten verwendet werden soll. Die Verwendung einer Adresse, um auf Daten zu verweisen, wird als Indirektion bezeichnet. In diesem nächsten Beispiel, ohne die eckigen Klammern, erhält ein anderes Register, bx, tatsächlich den Wert 20 geladen.
Da keine Indirektion verwendet wurde, wurde der tatsächliche Wert selbst in das Register eingetragen.
Wenn die Operanden (die Dinge, die nach der Eselsbrücke kommen), in umgekehrter Reihenfolge erscheinen, wird eine Anweisung, die etwas aus dem Speicher lädt, es stattdessen in den Speicher schreibt:
Hier erhält der Speicher an Adresse 1000h den Wert von ax. Wenn dieses Beispiel direkt nach dem vorherigen Beispiel ausgeführt wird, sind die 2 Bytes an 1000h und 1001h eine 2-Byte-Ganzzahl mit dem Wert 20.
Anweisungen, die mathematische oder logische Operationen ausführen
Einige Anweisungen machen Dinge wie Subtraktion oder logische Operationen wie nicht:
Das Maschinencode-Beispiel weiter oben in diesem Artikel wäre dies in Assemblersprache:
Hier werden 42 und ax zusammengezählt und das Ergebnis wieder in ax gespeichert. In der x86-Assembly ist es auch möglich, einen Speicherzugriff und eine mathematische Operation wie diese zu kombinieren:
Diese Anweisung addiert den Wert der bei 1000h gespeicherten 2-Byte-Ganzzahl zu ax und speichert die Antwort in ax.
Diese Anweisung berechnet den oder der Inhalte der Register ax und bx und speichert das Ergebnis zurück in ax.
Anweisungen, die darüber entscheiden, was die nächste Anweisung sein wird
Normalerweise werden die Befehle in der Reihenfolge ausgeführt, in der sie im Speicher erscheinen, d.h. in der Reihenfolge, in der sie in den Assemblercode eingegeben werden. Der Prozessor führt sie einfach eine nach der anderen aus. Damit Prozessoren jedoch komplizierte Dinge tun können, müssen sie unterschiedliche Anweisungen ausführen, je nachdem, welche Daten ihnen gegeben wurden. Die Fähigkeit von Prozessoren, je nach dem Ergebnis eines Vorgangs unterschiedliche Anweisungen auszuführen, wird als Verzweigung bezeichnet. Anweisungen, die darüber entscheiden, was die nächste Anweisung sein soll, werden Verzweigungsanweisungen genannt.
Nehmen wir in diesem Beispiel an, jemand möchte die Farbmenge berechnen, die er benötigt, um ein Quadrat mit einer bestimmten Seitenlänge zu bemalen. Aufgrund von Größenvorteilen verkauft das Farbengeschäft jedoch nicht weniger als die Farbmenge, die zum Bemalen eines Quadrats von 100 x 100 benötigt wird.
Um herauszufinden, welche Farbmenge sie aufgrund der Länge des Quadrats, das sie malen wollen, benötigen, haben sie sich diesen Satz von Schritten ausgedacht:
- 100 von der Seitenlänge subtrahieren
- wenn die Antwort kleiner als Null ist, setzen Sie die Seitenlänge auf 100
- die Seitenlänge mit sich selbst multiplizieren
Dieser Algorithmus kann im folgenden Code ausgedrückt werden, wobei ax die Seitenlänge ist.
Dieses Beispiel führt einige neue Dinge ein, aber die ersten beiden Anweisungen sind vertraut. Sie kopieren den Wert von ax in bx und subtrahieren dann 100 von bx.
Eines der neuen Dinge in diesem Beispiel heißt Label, ein Konzept, das in Versammlungssprachen im Allgemeinen zu finden ist. Labels können alles sein, was der Programmierer will (es sei denn, es ist der Name einer Anweisung, was den Assembler verwirren würde). In diesem Beispiel ist das Label "continue". Es wird vom Assembler als die Adresse einer Anweisung interpretiert. In diesem Fall ist es die Adresse von mult ax.
Ein weiteres neues Konzept ist das der Flaggen. Auf x86-Prozessoren setzen viele Befehle 'Flags' im Prozessor, die vom nächsten Befehl verwendet werden können, um zu entscheiden, was zu tun ist. In diesem Fall, wenn bx kleiner als 100 war, wird sub ein Flag setzen, das besagt, dass das Ergebnis kleiner als Null war.
Die nächste Anweisung ist jge, was die Abkürzung für "Springen, wenn größer als oder gleich" ist. Es ist eine Verzweigungsanweisung. Wenn die Flags im Prozessor angeben, dass das Ergebnis größer oder gleich null war, springt der Prozessor nicht einfach zur nächsten Anweisung, sondern zur Anweisung mit dem continue label, das mul ax ist.
Dieses Beispiel funktioniert gut, aber es ist nicht das, was die meisten Programmierer schreiben würden. Der Subtraktionsbefehl setzt das Flag korrekt, aber er ändert auch den Wert, mit dem er arbeitet, was erforderte, dass die Achse nach bx kopiert werden musste. Die meisten Assemblersprachen erlauben Vergleichsbefehle, die keines der übergebenen Argumente ändern, aber trotzdem die Flags richtig setzen, und x86-Assembler sind keine Ausnahme.
Anstatt nun 100 von ax abzuziehen, zu sehen, ob diese Zahl kleiner als Null ist, und sie wieder ax zuzuordnen, wird ax unverändert gelassen. Die Fahnen werden immer noch auf die gleiche Weise gesetzt, und der Sprung wird in den gleichen Situationen immer noch durchgeführt.
Eingabe und Ausgabe
Obwohl Eingabe und Ausgabe ein grundlegender Teil der Datenverarbeitung sind, gibt es keine einzige Möglichkeit, sie in Assemblersprache durchzuführen. Das liegt daran, dass die Art und Weise, wie E/A funktioniert, von der Einrichtung des Computers und dem Betriebssystem abhängt, auf dem er läuft, und nicht nur davon, welche Art von Prozessor er hat. Im Beispielabschnitt verwendet das Hello World-Beispiel MS-DOS-Betriebssystemaufrufe und das Beispiel danach BIOS-Aufrufe.
Es ist möglich, E/A in Assemblersprache durchzuführen. Tatsächlich kann Assembler im Allgemeinen alles ausdrücken, wozu ein Computer in der Lage ist. Aber obwohl es Anweisungen zum Hinzufügen und Verzweigen in Assemblersprache gibt, die immer das Gleiche tun, gibt es keine Anweisungen in Assemblersprache, die immer E/A ausführen.
Es ist wichtig zu beachten, dass die Art und Weise, wie E/A funktioniert, nicht Teil irgendeiner Assemblersprache ist, weil sie nicht Teil der Arbeitsweise des Prozessors ist.
Montagesprachen und Portabilität
Auch wenn Assembler nicht direkt vom Prozessor ausgeführt wird - Maschinencode schon, hat er dennoch viel damit zu tun. Jede Prozessorfamilie unterstützt verschiedene Funktionen, Anweisungen, Regeln dafür, was die Anweisungen tun können, und Regeln dafür, welche Kombination von Anweisungen wo erlaubt ist. Aus diesem Grund benötigen verschiedene Prozessortypen immer noch verschiedene Assemblersprachen.
Weil jede Version der Assemblersprache an eine Prozessorfamilie gebunden ist, fehlt ihr etwas, das man Portabilität nennt. Etwas, das Portabilität besitzt oder portabel ist, kann leicht von einem Computertyp auf einen anderen übertragen werden. Während andere Arten von Programmiersprachen portabel sind, ist Assembler im Allgemeinen nicht portabel.
Versammlungssprache und Hochsprachen
Obwohl die Assemblersprache eine einfache Möglichkeit bietet, alle Funktionen des Prozessors zu nutzen, wird sie für moderne Softwareprojekte aus verschiedenen Gründen nicht verwendet:
- Es kostet viel Mühe, ein einfaches Programm in der Montage auszudrücken.
- Obwohl sie nicht so fehleranfällig wie Maschinencode ist, bietet Assembler immer noch sehr wenig Schutz vor Fehlern. Fast alle Assemblersprachen setzen die Typsicherheit nicht durch.
- Assemblersprache fördert keine guten Programmierpraktiken wie Modularität.
- Während jede einzelne Assembleranweisung leicht verständlich ist, ist es schwer zu sagen, was die Absicht des Programmierers war, der sie geschrieben hat. Tatsächlich ist die Assemblersprache eines Programms so schwer zu verstehen, dass Unternehmen sich keine Sorgen darüber machen müssen, dass Leute ihre Programme zerlegen (die Assemblersprache erhalten).
Als Folge dieser Nachteile werden stattdessen für die meisten Projekte Hochsprachen wie Pascal, C und C++ verwendet. Sie ermöglichen es den Programmierern, ihre Ideen direkter auszudrücken, anstatt sich darum kümmern zu müssen, dem Prozessor bei jedem Schritt zu sagen, was er zu tun hat. Sie werden Hochsprachen genannt, weil die Ideen, die der Programmierer in der gleichen Menge Code ausdrücken kann, komplizierter sind.
Programmierer, die Code in kompilierten Hochsprachen schreiben, verwenden ein Programm namens Compiler, um ihren Code in Assembler umzuwandeln. Compiler sind viel schwieriger zu schreiben als Assembler. Außerdem erlauben es Hochsprachen den Programmierern nicht immer, alle Funktionen des Prozessors zu nutzen. Das liegt daran, dass Hochsprachen so konzipiert sind, dass sie alle Prozessorfamilien unterstützen. Im Gegensatz zu Assemblersprachen, die nur einen Prozessortyp unterstützen, sind Hochsprachen portabel.
Auch wenn Compiler komplizierter als Assembler sind, sind sie durch jahrzehntelange Herstellung und Erforschung von Compilern sehr gut geworden. Nun gibt es nicht mehr viel Grund, Assembler für die meisten Projekte zu verwenden, da Compiler normalerweise auch oder besser als Programmierer herausfinden können, wie man Programme in Assembler ausdrücken kann.
Beispiel-Programme
Ein Hallo-Welt-Programm, geschrieben in x86 Assembly:
Eine Funktion, die mit Hilfe von BIOS-Interrupts, die in NASM x86-Assembly geschrieben wurden, eine Zahl auf den Bildschirm druckt. Modularer Code kann in Assembler geschrieben werden, erfordert aber zusätzlichen Aufwand. Beachten Sie, dass alles, was nach einem Semikolon in einer Zeile steht, ein Kommentar ist und vom Assembler ignoriert wird. Das Einfügen von Kommentaren in Assembler-Code ist sehr wichtig, da große Assembler-Programme so schwer zu verstehen sind.
Fragen und Antworten
F: Was ist eine Assemblersprache?
A: Eine Assemblersprache ist eine Programmiersprache, mit der man dem Computer direkt sagen kann, was er tun soll. Sie ist fast genau wie der Maschinencode, den ein Computer verstehen kann, nur dass sie Wörter anstelle von Zahlen verwendet.
F: Wie kann ein Computer ein Assemblerprogramm verstehen?
A: Ein Computer kann ein Assemblerprogramm nicht wirklich direkt verstehen, aber er kann das Programm leicht in Maschinencode umwandeln, indem er die Wörter des Programms durch die Zahlen ersetzt, für die sie stehen. Dieser Vorgang wird mit einem Assembler durchgeführt.
F: Was sind Anweisungen in einer Assemblersprache?
A: Anweisungen in einer Assemblersprache sind kleine Aufgaben, die der Computer ausführt, wenn er das Programm ausführt. Sie werden Anweisungen genannt, weil sie dem Computer sagen, was er tun soll. Der Teil des Computers, der für die Befolgung dieser Anweisungen verantwortlich ist, wird Prozessor genannt.
F: Welche Art von Programmiersprache ist Assembler?
A: Assembler ist eine Low-Level-Programmiersprache, was bedeutet, dass sie nur für einfache Aufgaben verwendet werden kann, die ein Computer direkt verstehen kann. Um komplexere Aufgaben auszuführen, muss man jede Aufgabe in ihre einzelnen Komponenten zerlegen und für jede Komponente separate Anweisungen bereitstellen.
F: Worin besteht der Unterschied zu Hochsprachen?
A: Hochsprachen können einzelne Befehle enthalten, wie z.B. PRINT "Hallo, Welt!", die dem Computer sagen, dass er all diese kleinen Aufgaben automatisch ausführen soll, ohne sie einzeln angeben zu müssen, wie Sie es bei einem Assemblerprogramm tun müssten. Dadurch sind Hochsprachen für Menschen leichter zu lesen und zu verstehen als Assemblerprogramme, die aus vielen einzelnen Anweisungen bestehen.
F: Warum kann es für Menschen schwierig sein, ein Assemblerprogramm zu lesen?
A: Weil für eine komplexe Aufgabe, wie z.B. etwas auf dem Bildschirm auszudrucken oder Berechnungen mit Datensätzen durchzuführen - Dinge, die in natürlicher menschlicher Sprache sehr grundlegend und einfach erscheinen -, viele einzelne Anweisungen angegeben werden müssen, so dass es für Menschen, die nicht wissen, wie Computer intern auf einer so niedrigen Ebene funktionieren, schwierig ist, zu folgen und zu interpretieren, was in ihnen vorgeht.