IT-Basics: Was ist Assembler?

Die Assemblersprache, kurz auch Assembler genannt (von engl. to assemble ‚montieren‘), ist eine Programmiersprache, die eine eindeutige Beziehung zur einem Prozessor und dessen Befehlssatz hat. In diesem Beitrag möchte ich Assembler vorstellen und erklären wie die Programmiersprache funktioniert.

Assembler ist eine Abstraktion zu der direkten Programmierung des Prozessors in Zahlencodes. Anstelle eines Programmes zu schreiben, welches so aussieht:

0000000 177 105 114 106 002 001 001 000 000 000 000 000 000 000 000 000
0000010 001 000 076 000 001 000 000 000 000 000 000 000 000 000 000 000
0000020 000 000 000 000 000 000 000 000 100 000 000 000 000 000 000 000
0000030 000 000 000 000 100 000 000 000 000 000 100 000 007 000 003 000
0000040 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
...

Kann man es auch so schreiben:

SECTION .DATA
hello:	db 'Hello world!',10
helloLen:  equ $-hello

SECTION .TEXT
GLOBAL _start

_start:
mov eax,4
mov ebx,1
mov ecx,hello
mov edx,helloLen
int 80h

mov eax,1
mov ebx,0
int 80h

Bevor der erste Assembler von Nathaniel Rochester zwischen 1948 und 1950 für die IBM 701 Plattform entwickelt wurde, mussten die Computer mit direkten Maschineninstruktionen programmiert werden. Anhand des Beispiels ist leicht zu erkennen, dass es viel leichter ist im ersten Beispiel einen Fehler zu machen. Auch die Lesbarkeit und damit das Verständnis, was das Programm machen soll, wird gefördert.

Heute ist es mit wenigen Ausnahmen nicht mehr notwendig ein ganzes Programm in Assembler zu schreiben. Die Programme werden in höheren Programmiersprachen
wie zum Beispiel C, C++ oder C# entwickelt. Ein Compiler sorgt dafür, dass ein Programm, welches in einer höheren Programmiersprache verfasst wurde, in Maschinensprache übersetzt wird und entsprechend auf der Zielplattform lauffähig ist.

Welche Assemblerbefehle gibt es?

Technisch ist es machbar heute noch Routinen in Assembler zu schreiben, die besser sind als wenn aus einem Quelltext einer Programmiersprache entsprechend der Maschinencode erzeugt wird. Aus betriebswirtschaftlicher Sicht rechnet sich das fast nie und wird meist nur noch in sehr begrenzten Einsatzszenarios gemacht. Selbst im Embedded Device/IoT-Umfeld haben viele Anbieter für die Geräte mit z.B. ARM-Prozessoren komplette Entwicklungsumgebungen. Innerhalb einer Prozessorarchitektur sind die Maschineninstruktionen kompatibel. Mit weiteren Revisionen kommen in der Regel neue Befehle hinzu.

Bis heute funktionieren alle x86-kompatiblen CPUs nach dem Prinzip des i80386. Der x86 Prozessor kennt die folgenden Register, die je nach Typ entsprechend mit Assemblerbefehlen für die Speicherung von Daten verwendet werden können:

  • AX/EAX/RAX: Akkumulator*
  • BX/EBX/RBX: Basis
  • CX/EDX/RDX: Zähler
  • DX/EDX/RDX: Daten/Allzweck
  • SI/ESI/RSI: Quellindex (Zeichenketten)
  • DI/EDI/RDI: Zielindex (Zeichenketten)
  • SP/ESP/RSP: Stapelzeiger
  • BP/EBP/RBP: Stapelsegment (Anfangsadresse oder BasePointer)
  • IP/EIP/RIP: Befehlszeiger

* Ein Akkumulator ist ein Register, welches die Ergebnisse der Recheneinheit (ALU) speichert, also alle arithmetisch-logische Einheiten wie beispielsweise Addition, Subtraktion, Division, Multiplikation oder Vergleichen.

Hier gibt es eine Übersicht aller auf x86 verfügbaren Maschineninstruktionen.

Wie erstelle ich eine Assembler-Datei?

Als Erstes erstellt man eine leere Assembler-Datei mit dem Linux Befehl touch hello.asm. Anschließend öffnet man die Datei mit nano hello.asm und schreibt folgenden Quelltext hinein:

Anschließend kompiliert man das Programm mit dem Befehl nasm -f elf64 hello.asm -o hello.o. Jetzt muss man nur noch den Linker setzen, welcher die Bibliotheken mit der Datei verknüpft ld hello.o -o hello. Jetzt kann man das Assembler Programm laufen lassen. Viel Spaß damit.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

CAPTCHA *