GNU Assembler

Programmierwerkzeug
Dies ist die gesichtete Version, die am 10. Dezember 2024 markiert wurde. Es existieren 6 ausstehende Änderungen, die noch gesichtet werden müssen.

Der GNU Assembler, auch bekannt als GAS, ist der Assembler des GNU-Projekts. Er ist das Standard-Backend der GNU Compiler Collection und wird folglich zum Assemblieren des Betriebssystems GNU, des Linux-Kernels und vieler anderer insbesondere als Quelltextpakete verfügbarer Applikationen verwendet. Er gehört zu den GNU Binary Utilities (binutils).

GNU Assembler

Basisdaten

Entwickler GNU-Projekt
Erscheinungsjahr 1986
Aktuelle Version toolset version of binutils[1]
Betriebssystem Cross-platform
Programmier­sprache C
Kategorie Assembler
Lizenz GNU General Public License v3
www.gnu.org/software/binutils

Die ausführbare Datei des GNU Assemblers wird wie der Assembler des ursprünglichen Unix von AT&T und Assembler späterer Unix-artiger Betriebssysteme mit as aufgerufen. GAS ist plattformübergreifend, und damit für eine große Anzahl von verschiedenen Rechnerarchitekturen sowohl lauf- als auch assemblierfähig. Als üblicher Assembler für die GCC ist er in u. a. vielen Linux-Distributionen und BSD-Abkömmlingen enthalten.

GAS wird unter der GNU General Public License v3 veröffentlicht und ist freie Software.

Kompatibilität

Bearbeiten

Für gängige Mikroprozessorarchitekturen wie AArch64[2], IBMs (bzw. AIMs) Enhanced RISC (IBM POWER und PowerPC) und x86 ab dem 80386 (dazu s. Abschnitt) ist der GNU Assembler nativ vorkompiliert erhältlich. Als Cross-Assembler etwa für vergleichsweise leistungsschwache oder veraltete Prozessoren wie die Motorola-68000er-Familie oder den Z80 muss er in vielen Fällen mit den geeigneten Werkzeugen erstellt werden; wobei abhängig von Betriebssystem, CPU und Assemblierungsziel (namentlich dem sehr bekannten Z80)[3] auch (ältere) binutils-Pakete fertig angeboten werden.

Der dem Betriebssystem eigene Assembler ist in der Shell gewöhnlich als /usr/bin/as über den voreingestellten Suchpfad aufrufbar (s. auch Filesystem Hierarchy Standard). Zusätzliche binutils werden gewöhnlich als /usr/binutils-<Zielrechner> angelegt worin die ausführbaren Datein sind. gas hat keine Schalter wie gcc, die ausführbare Datei des GNU C Compilers, für einen eigenen Suchpfad und den Aufruf anderer Ausgaben. Um einen Cross-Assembler in einer Shell bequem aufzurufen, kann z. B. in deren Konfigurationsdatei ein alias für /usr/binutils-<soundso>/as eingetragen werden.

GNU Assembler und Microsoft Windows

Bearbeiten

In Cygwin läuft gas ab Windows 7, binutils in neuester Fassung kann kompiliert für x86-64[4] und als Quellenpaket[5] vom Entwickler heruntergeladen werden.

Für MinGW gibt es eine eigene Ausgabe der binutils.

Optionen

Bearbeiten

Der GNU Assembler hat allgemeine und für das System, für das assembliert werden kann, verfügbare Aufrufparameter, von denen einige folgend aufgeführt sind. Dabei ist zu beachten, dass in der Unixwelt case sensitivity vorherrscht.

--help zeigt eine Zusammenfassung über die Optionsschalter, --target-help eine über die zielbezogenen.

--dump-config zeigt wie der Assembler eingestellt ist.

Mit -a, einer angehängten Folge bestimmter Kleinbuchstaben, einem abschließenden = und einem folgenden Dateinamen wird in der Datei ein Protokoll über bestimmte Eigenschaften der zu erfolgenden Assemblierung verfasst.

-v (-version) zeigt die Version von as an, --version beendet zudem die Ausführung.

-- weist formal darauf hin, dass as die Standardeingabe lesen soll und kann auch weggelassen werden. Ist diese das Terminal können Zeilen von Code eingegeben und die Eingabe mit <Strg> <D> beendet werden.

Jedes Befehlszeilenargument ohne festgelegte Bedeutung wird von as als zu assemblierende Datei aufgefasst. Die übergebene Folge von Dateien wird von links gelesen und in ein Maschinenprogramm übersetzt.

Wird gas vom gcc aufgerufen kann dieser mit dem Schalter -Wa jenes Parameter zu ihm durchreichen indem sie nach einem Komma von Kommata getrennt eingetragen werden, also gemäß

<Eingabeaufforderung> gcc <cparam1 cparam2 …> -Wa,<aparam1,aparam2,…> <cparamN …> <ctext1.c ctext2.c …>

in einer Befehlszeile.

Die Syntax des GNU Assemblers hat einen allgemeingültigen Teil für alle unterstützten Architekturen. Er ist ähnlich vielen anderen Assemblern und von früheren Unix-Assemblern beeinflusst. Er beinhaltet u. a. Anweisungen für den Assembler, sog. Direktiven, Methoden zum Kommentieren und Darstellung von Zahlenwerten („Konstanten“).

Maschinenabhängige Ausdrücke wie insbesondere Befehle und Register sind der Herstellerbeschreibung zu entnehmen.

Assembler-Direktiven

Bearbeiten

Der GNU Assembler verwendet Assembler-Direktiven (auch als pseudo-ops bekannt), welche aus einem Schlüsselwort beginnend mit einem Punkt gebildet werden. Die meisten verfügbaren Direktiven sind architekturunabhängig, einige wenige hardwarespezifisch.[6]

Kommentare

Bearbeiten

Kommentare können allgemein zwischen /* und */ geschrieben werden. Zeilenkommentare einleitende Zeichenfolgen wie /, //, ; usw. sind zielabhängig.

Für die x86-Mikroarchitektur nutzt GAS standardmäßig das Rautezeichen (#) für einen Einzelzeilenkommentar. Beispiel:

pop �x # alles hinter der Raute ist Kommentar
#AX und DX sind 86er Register
movl �x,�x

Konstanten

Bearbeiten

Werte können auf verschiedene Weisen geschrieben werden, die außer für dezimale Ganzzahlen von Vorsätzen bestimmt werden: 0b für Binär-, 0 für Oktal-, 0x für hexadekadische Zahlen; Fließkommazahlen kann zielabhängig z. B. 0f vorgesetzt werden.

Wird einem Wert der Operator - vorangestellt ist das Ergebnis sein Zweierkomplement; entsprechend erzeugt ~ sein bitweises Komplement.

Eine Quelle negativer Kritik an GAS ist, dass für die Zielsysteme x86-32 und x86-64 (als „80386“ zusammengefasst) anstelle der meistens verwendeten Syntax nach Art des eingestellten ASM86 von Intel die im Umfeld Unix-artiger Betriebssysteme bevorzugte AT&T-Assembler-Syntax voreingestellt ist.[7] Das ist allerdings in der Kompatibilität zur GCC begründet[8] denn so können beispielsweise Ausdrücke in C übersichtlicher eingefügt werden. Seit binutils 2.10 von Juni 2000[9][10] kann die vorgegebene Syntax über die Direktiven .intel_syntax geändert bzw. .att_syntax wiederhergestellt werden.[11] Die ausführbare Datei von gas für x86 hat auch den Schalter -msyntax= mit den Werten intel und att mit denen jeweils die vorrangige Syntax bestimmt werden kann.

Das obige Beispiel in Intel-Syntax:

.intel_syntax noprefix #mit Argument dass Register als Operanden den Vorsatz '%' nicht benötigen
pop edx
mov eax, edx
.att_syntax prefix

Inline Assembler

Bearbeiten

Der GNU Assembler zeichnet sich gegenüber anderen Assemblern auch durch eine Inline-Syntax aus, die es ermöglicht, den Assembler-Teil effektiv in einen Hochsprachenteil einzubinden. Dies geschieht durch eine Liste der Eingabe-, Ausgaberegister und der im Assembler-Teil verwendeten Register.[12] Hierdurch kann der Compiler einen Assembler-Teil während der Optimierung ohne Übergabe-Overheads an den Hochsprachenteil anbinden.

Das obige Beispiel als C-Inline-Assembler in Intel-Syntax:

  __asm__ __volatile__  (".intel_syntax noprefix \n\t"
      "pop edx         ;Intel-syntax kommentar \n\t"
      "mov eax, edx                            \n\t"
      ".att_syntax prefix                      \n\t"
      : /* no output operands  */
      : "d" (save_var), "a" (temp_var) /* inputs operands*/
      : "eax", "edx" /* intern verwendete register (clobber list)*/);

Infolge der Wortlänge von 2 Bytes der Intel 8086, 80286 u. ä. kann der GNU Assembler auf ihnen nicht laufen. Um Programme für sie (oder den Real oder Virtual 8086 Mode) zu assemblieren, kann die Direktive .code16 zur Voreinstellung verwendet werden. Das gewährleistet nicht, dass das Programm auf den alten Prozessoren läuft. Dazu muss auf alle 32- und 64-Bit-Ausdrücke verzichtet werden, sonst werden sie mit den Maschinensprachenvorsätzen 66h oder 67h für die entsprechenden Operanden- bzw. Arbeitsspeicheradressenlängen zur Übersteuerung der Real-Mode-Voreinstellung assembliert. Es dürfen daher insbesondere nur die Befehlsanhänge -b für 1 byte oder -w für 2 bytes („word“) lange Operanden in AT&T-Ausdrucksweise wie bei movb und Registernamen wie %ax statt �x oder %rax (s. Register des 8086) verwendet werden.

Bearbeiten

Einzelnachweise

Bearbeiten
  1. sourceware.org. (abgerufen am 8. Februar 2021).
  2. binutils 2.42. Arch Linux ARM, abgerufen am 27. November 2024.
  3. binutils-z80 2.31.1. Debian, abgerufen am 29. November 2024. Komprimierte Archive für amd64, ARM64, i386 und ARMhf.
  4. Package: binutils. Red Hat, 24. August 2024, abgerufen am 8. Dezember 2024.
  5. Source Package: binutils. Red Hat, 24. August 2024, abgerufen am 8. Dezember 2024.
  6. The GNU Assembler – Assembler Directives. In: sourceware.org. Abgerufen am 27. März 2022.
  7. Susan Welsh: AT&T Assembly Syntax (Memento vom 7. Januar 2020 im Internet Archive). Sig 9, 17. Juli 2017.
  8. AT&T Syntax versus Intel Syntax abgerufen am 13. November 2019.
  9. GAS. Sourceforge, abgerufen am 21. November 2024.
  10. Index der binutils-Archive. GNU-Projekt, abgerufen am 21. November 2024.
  11. Ram Narayan: Linux assemblers: A comparison of GAS and NASM bei IBMDeveloper vom 17. Oktober 2007, abgerufen am 13. November 2019.
  12. 5. Extended Asm. www.ibiblio.org, 1. März 2003, abgerufen am 27. Juli 2011 (englisch): „[...]we can also specify the operands. It allows us to specify the input registers, output registers and a list of clobbered registers