Beruflich Dokumente
Kultur Dokumente
● High-level language
○ Level of abstraction closer
to problem domain
○ Provides for productivity and
portability
● Assembly language
○ Textual representation of
instructions
● Hardware representation
○ Binary digits (bits)
○ Encoded instructions and
data
❓ For a given function, which programming language likely takes the most lines of code?
Put the three representations below in order.
A. Java
B. C
C. Legv8
Answer : Legv8, C, Java
Warum Assembler-Programmierung?
- hocheffizienten Code für eine bestimmte Hardware schreiben
- die Ausgabe des Compilers zu analysieren, um Leistungsprobleme zu erkennen
- Zugriff auf und Aktualisierung von hardwarespezifischen Registern
2
- Nutzung neuester Anweisungen, die vom Compiler noch nicht verwendet werden
- Fehlersuche, z. B. Analyse von Core-Dumps
- Reverse-Engineering von unbekanntem Binärcode
- Debugging von Systemcrashs, z. B. mithilfe von Core-Dumps
* Kenntnisse der Assembler Programmierung bzw. des ISA sind wesentlich für das
Verständnis von Computer Architekturen.
CISC: RISC:
● Intel x86 ● MIPS (Microprocessor without Interlocked Pipelined Stages)
● IBM Z ● SPARC (Scalable Processor Architecture)
Systems ● ARMv8 (LEGv8)
● RISC-V
● IBM Power Systems
3
ARMv8 operands:
Programmiersprachen haben einfache Variablen, die einzelne Datenelemente enthalten, wie
in diesen Beispielen, aber sie haben auch komplexere Datenstrukturen - Arrays und
Strukturen. Diese zusammengesetzten Datenstrukturen können viel mehr Datenelemente
enthalten als es Register in einem Computer gibt. Wie kann ein Computer solche großen
Strukturen darstellen und darauf zugreifen?
Erinnern Sie sich an die fünf Komponenten eines Computers, die in Kapitel 1 eingeführt
wurden. Der Prozessor kann nur eine kleine Menge von Daten in Registern speichern, aber
der Computermemory enthält Milliarden von Datenelementen. Daher werden
Datenstrukturen (Arrays und Strukturen) im Memory aufbewahrt .
4
Arithmetic operations:
Logical operations:
5
Data transfer:
Wie oben erläutert, finden arithmetische Operationen nur auf Registern in LEGv8
Anweisungen; daher muss LEGv8 Anweisungen enthalten, die Daten zwischen Speicher
und Registern übertragen. Solche Befehle werden als Datentransfer-Befehle bezeichnet.
Um auf ein Wort oder Doppelwort im memory zuzugreifen, muss der Befehl die memory
adresse liefern. Der memory ist ein großes, eindimensionales Feld, wobei die Adresse als
Index für dieses Array dient, beginnend bei 0. Zum Beispiel ist in Abbildung unten, ist die
Adresse des dritten Datenelements 2, und der Wert des Speichers [2] ist 10.
Der Datentransfer-Befehl, der Daten aus dem Speicher in ein Register kopiert, wird
traditionell als Load bezeichnet. Das Format des Ladebefehls ist der Name der Operation,
gefolgt von dem zu ladenden Register, dann das Register und eine Konstante, die für den
Speicherzugriff verwendet wird. Die Summe aus dem konstanten Teil des Befehls und dem
Inhalt des zweiten Registers bildet die Speicheradresse. Der eigentliche LEGv8-Name für
diesen Befehl lautet LDUR und steht für Register laden.
Beispiel1:
Kompilieren einer Zuweisung, wenn sich ein Operand im Speicher befindet. Nehmen wir an,
dass A ein Array von 100 doublewords ist und dass der Compiler die Variablen g und h wie
zuvor mit den Registern X20 und X21 verbunden hat.
6
Nehmen wir außerdem an, dass die Startadresse oder Basisadresse des Arrays in X22 liegt.
Kompilieren Sie diese C-Zuweisungsanweisung:
g = h + A[8];
Obwohl diese Zuweisungsanweisung eine einzige Operation enthält, befindet sich einer
der Operanden im Speicher, also müssen wir zuerst A[8] in ein Register übertragen. Die
Adresse dieses Array-Elements ist die Summe aus der Basis des Arrays A, die sich im
Register X22 befindet, plus der Zahl zur Auswahl von Element 8. Die Daten sollten in
einem temporären Register Register abgelegt werden, um im nächsten Befehl verwendet
zu werden.
→ Die erste kompilierte Anweisung lautet:
Die folgende Anweisung kann mit dem Wert in X9 (der A[8] entspricht) arbeiten, da er sich
in einem Register befindet. Die Anweisung muss h (enthalten in X21) zu A[8] (enthalten in
X9) addieren und die Summe in das Register das g entspricht (das mit X20 verbunden
ist):
Das Register, das zur Bildung der Adresse addiert wird (X22), wird als Basisregister
bezeichnet, und die Konstante in einem Datentransfer-Befehl (8) wird als Offset
bezeichnet.
Beispiel2:
Angenommen, die Variable h ist dem Register X21 zugeordnet und die Basisadresse des
Arrays A befindet sich in X22. Wie lautet der LEGv8-Assemblercode für die folgende
C-Zuweisungsannweisung unten?
A[12] = h + A[8];
Obwohl die C-Anweisung eine einzige Operation enthält, befinden sich nun zwei der
Operanden im Speicher, so dass wir noch mehr LEGv8-Anweisungen benötigen. Die
ersten Die ersten beiden Anweisungen sind die gleichen wie im vorherigen Beispiel, nur
dass wir diesmal den richtigen Offset für die Byte-Adressierung in der
Load-Register-Anweisung verwenden, damit wir A[8], und der ADD-Befehl setzt die
Summe in X9:
Der letzte Befehl speichert die Summe in A[12], wobei 96 (8 × 12) als Offset und das
Register X22 als Basisregister verwendet werden.
Conditional branch:
8
Unconditional branch:
unter der Annahme, dass X20 + AddrConstant4 die Speicheradresse der Konstante 4 ist.
Eine Alternative, die den Ladebefehl vermeidet, ist die Bereitstellung von Versionen der
arithmetischen Anweisungen anzubieten, bei denen ein Operand eine Konstante ist. Diese
schnelle Additionsanweisung mit einem konstanten Operanden wird add immediate oder
ADDI genannt. Um 4 zum Register X22 zu addieren, schreiben wir einfach
Konstante Operanden kommen häufig vor, und durch die Aufnahme von Konstanten in
arithmetischen Anweisungen sind die Operationen viel schneller und verbrauchen weniger
Energie, als wenn Konstanten aus dem Speicher geladen würden.
Die konstante Null hat eine weitere Funktion, nämlich die Vereinfachung des Befehlssatzes
durch nützliche Variationen anbietet. So ist beispielsweise die Operation Move nur ein
Additionsbefehl, bei dem ein Operand Null ist. Daher widmet LEGv8 ein Register XZR, das
fest mit dem Wert Null verdrahtet wird. (Es entspricht der Registernummer 31.) Die
Verwendung der Frequenz zur Rechtfertigung der Einbeziehung von Konstanten ist ein
weiteres Beispiel für die großartige Idee aus Kapitel 1, den Normalfall schnell zu
machen.ARMv8 Register Details
Im Gegensatz zu Programmen in Hochsprachen sind die Operanden von arithmetischen
Anweisungen eingeschränkt; sie müssen aus einer begrenzten Anzahl spezieller
Speicherplätze stammen, die direkt in die Hardware eingebaut sind und Register genannt
werden. Register sind Primitive, die bei der Konstruktion von Hardware verwendet werden
9
und auch für den Programmierer sichtbar sind, wenn der Computer fertiggestellt ist, so dass
man sich die Register als die Bausteine der Computerkonstruktion vorstellen kann.
Die Größe eines Registers in der LEGv8-Architektur beträgt 64 Bit; Gruppen von 64 Bit
kommen so häufig vor, dass sie in der LEGv8-Architektur als Doppelwort
“doubleword” bezeichnet werden. (Eine andere gängige Größe ist eine Gruppe von 32
Bits, die in der LEGv8-Architektur als Wort bezeichnet wird.)
Anweisungen werden im Computer als eine Reihe von hohen und niedrigen elektronischen
Signalen gespeichert und können als Zahlen dargestellt werden. In der Tat kann jeder Teil
einer Anweisung einer Anweisung als eine einzelne Zahl betrachtet werden, und die
Aneinanderreihung dieser Zahlen Aneinanderreihung bildet die Anweisung. Die 32 Register
der LEGv8 werden einfach durch ihre Nummer bezeichnet, von 0 bis 31.
LEGv8-Felder
Die Instrucktion sind binär kodiert,als Maschinencode bezeichnet
ARMv8/LEGv8-Befehle:
● Kodiert als 32-Bit-Befehlsworte
● Geringe Anzahl von kodierten Formaten
● Operationscode (Opcode), Registernummern, …
● Design principle: regularity!
● Opcode: Grundlegende Operation des Befehls, und diese Abkürzung ist seine
traditionelle Bezeichnung.
● Rm: Der zweite Register-Quelloperand.
● shamt: Verschiebungsbetrag. (In Abschnitt 2.6 werden Schiebebefehle und dieser
Begriff erklärt; er wird bis dahin nicht verwendet, daher enthält das Feld in diesem
Abschnitt Null). - : shift amount
● Rn: Der erste Register-Quelloperand.
● Rd: Der Zieloperand des Registers. Er erhält das Ergebnis der Operation.
ADD X9,X20,X21
1. Das erste Feld (das in diesem Fall 1112 enthält) teilt dem LEGv8-Computer mit,
dass dieser Befehl eine Addition durchgeführt.
2. Das zweite Feld gibt die Nummer des Registers an, das der zweite Quelloperand
der Additionsoperation ist (21 für X21),
3. (Das dritte Feld ist bei dieser Anweisung unbenutzt und wird daher auf 0 gesetzt.)
4. und das vierte Feld gibt den anderen Quelloperanden für die Addition an (20 für
X20).
5. Das fünfte Feld enthält die Nummer des Registers, das die Summe erhalten soll (9
für X9).
Diese Anweisung addiert also Register X20 zu Register X21 und legt die Summe in
Register X9 ab. Diese Anweisung kann auch als Felder mit Binärzahlen statt mit
Dezimalzahlen dargestellt werden statt dezimal:
This layout of the instruction is called the instruction format. As you can see from
counting the number of bits, this LEGv8 instruction takes exactly 32 bits—a word, or one
half of a doubleword. In keeping with our design principle that simplicity favors regularity,
all LEGv8 instructions are 32 bits long.
Example:
13
Vorlesungsbeispiele:
15
Check Yourself:
True
False
True
False