Suche…


Microsoft Assembler - MASM

Da der 8086/8088 im IBM PC verwendet wurde und das Betriebssystem meist von Microsoft stammte, war der Assembler MASM von Microsoft der De-facto-Standard für viele Jahre. Es folgte Intels Syntax genau, erlaubte jedoch eine praktische, aber "lose" Syntax, die (im Nachhinein) nur Verwirrung und Fehler im Code verursachte.

Ein perfektes Beispiel ist wie folgt:

MaxSize      EQU     16          ; Define a constant
Symbol       DW      0x1234      ; Define a 16-bit WORD called Symbol to hold 0x1234

             MOV     AX, 10      ; AX now holds 10
             MOV     BX, MaxSize ; BX now holds 16
             MOV     CX, Symbol  ; ????

Setzt der letzte MOV Befehl den Inhalt von Symbol in CX oder die Adresse von Symbol in CX ? 0x1234 CX mit 0x1234 oder 0x0102 (oder was auch immer)? Es stellt sich heraus, dass CX mit 0x1234 endet - wenn Sie die Adresse wünschen, müssen Sie den OFFSET

             MOV     AX, [Symbol]      ; Contents of Symbol
             MOV     CX, OFFSET Symbol ; Address of Symbol

Intel Assembler

Intel schrieb die Spezifikation der 8086-Assemblersprache, einer Ableitung der früheren 8080-, 8008- und 4004-Prozessoren. Der Assembler, den sie geschrieben haben, folgte genau ihrer eigenen Syntax. Dieser Assembler wurde jedoch nicht sehr häufig verwendet.

Intel hat ihre Opcodes so definiert, dass sie entweder null, einen oder zwei Operanden haben. Die Zwei-Operanden - Befehle wurden in der so definiert dest , source um, die von anderen Assemblern zu der Zeit anders war. Einige Befehle verwendeten jedoch implizite Register als Operanden - man musste nur wissen, was sie waren. Intel verwendete auch das Konzept der "Präfix" -Opcodes - ein Opcode würde den nächsten Befehl beeinflussen.

; Zero operand examples
NOP             ; No parameters
CBW             ; Convert byte in AL into word in AX
MOVSB           ; Move byte pointed to by DS:SI to byte pointed to by ES:DI
                ; SI and DI are incremented or decremented according to D bit

; Prefix examples
REP   MOVSB     ; Move number of bytes in CX from DS:SI to ES:DI
                ; SI and DI are incremented or decremented according to D bit

; One operand examples
NOT      AX     ; Replace AX with its one's complement
MUL      CX     ; Multiply AX by CX and put 32-bit result in DX:AX

; Two operand examples
MOV      AL, [0x1234] ; Copy the contents of memory location DS:0x1234 into AL register

Intel hat auch eine Konvention gebrochen, die von anderen Assemblern verwendet wird: Für jeden Opcode wurde eine andere Mnemonik erfunden. Dies erforderte subtil oder deutlich unterschiedliche Namen für ähnliche Vorgänge: zB LDM für "Load from Memory" und LDI für "Load Immediate". Intel nutzte den One-Mnemonic- MOV - und erwartete, dass der Assembler herausfand, welchen Opcode er aus dem Kontext verwenden sollte. Das verursachte in der Zukunft viele Fehler und Fehler für Programmierer, wenn der Assembler nicht verstehen konnte, was der Programmierer eigentlich wollte ...

AT & T Assembler - als

Obwohl der 8086 zusammen mit Microsoft am häufigsten in IBM-PCs verwendet wurde, gab es auch eine Reihe anderer Computer und Betriebssysteme, insbesondere: Unix. Dies war ein Produkt von AT & T, und Unix lief bereits auf einer Reihe anderer Architekturen. Diese Architekturen konventionelleren Montage Syntax verwendet - vor allem , dass zwei Operanden - Befehle spezifiziert sie in source , dest Reihenfolge.

AT & T-Assembler-Konventionen überschreiben also die von Intel vorgegebenen Konventionen, und für die x86-Reihe wurde ein neuer Dialekt eingeführt:

  • Registernamen wurden mit % vorangestellt:
    %al , %bx usw.
  • Unmittelbare Werte wurden mit $ vorbelegt:
    $4
  • Operanden waren in source , dest Reihenfolge
  • Opcodes enthalten ihre Operandengröße:
    movw $4, %ax ; Move word 4 into AX

Borlands Turbo Assembler - TASM

Borland startete mit einem Pascal-Compiler, den sie "Turbo Pascal" nannten. Es folgten Compiler für andere Sprachen: C / C ++, Prolog und Fortran. Sie stellten auch einen Assembler namens "Turbo Assembler" her, den sie nach der Namenskonvention von Microsoft "TASM" nannten.

TASM versuchte, einige der Probleme beim Schreiben von Code mit MASM (siehe oben) zu beheben, indem der Quellcode in einem bestimmten IDEAL Modus strenger interpretiert wurde. Standardmäßig wurde der MASM Modus angenommen, sodass er die MASM-Quelle direkt zusammenstellen konnte. Borland stellte jedoch fest, dass sie Bug-for-Bug-kompatibel mit MASMs "eigenartigeren" Eigenheiten sein mussten, und fügte außerdem einen QUIRKS Modus hinzu.

Da TASM (viel) billiger als MASM war, hatte es eine große Benutzerbasis - aber trotz der angepriesenen Vorteile nutzten nicht viele Leute den IDEAL-Modus.

GNU Assembler - Gas

Als das GNU-Projekt einen Assembler für die x86-Familie benötigte, nutzten sie die AT & T-Version (und ihre Syntax), die mit Unix und nicht mit der Intel / Microsoft-Version verknüpft war.

Netwide Assembler - NASM

NASM ist bei weitem der am meisten portierte Assembler für die x86-Architektur - er ist für praktisch jedes Betriebssystem verfügbar, das auf dem x86 basiert (sogar im Lieferumfang von MacOS enthalten ist) und ist als plattformübergreifender Assembler auf anderen Plattformen verfügbar.

Dieser Assembler verwendet die Intel-Syntax, unterscheidet sich jedoch von anderen, da er sich stark auf seine eigene "Makrosprache" konzentriert. Dadurch kann der Programmierer komplexere Ausdrücke mit einfacheren Definitionen erstellen, wodurch neue "Anweisungen" erstellt werden können.

Leider ist diese leistungsstarke Funktion mit Kosten verbunden: Die Art der Daten behindert allgemeine Anweisungen, sodass die Datentypisierung nicht erzwungen wird.

response:    db       'Y'     ; Character that user typed

             cmp      response, 'N' ; *** Error! Unknown size!
             cmp byte response, 'N' ; That's better!
             cmp      response, ax  ; No error!

NASM führte jedoch eine Funktion ein, die bei anderen nicht vorhanden war: Symbolnamen. Wenn Sie ein Symbol in anderen Assemblern definieren, steht dieser Name im gesamten Code zur Verfügung. Dieser Name "verbraucht" diesen Namen und "verschmutzt" den globalen Namensraum mit Symbolen.

Zum Beispiel (mit NASM-Syntax):

       STRUC     Point
X      resw      1
Y      resw      1
       ENDSTRUC

Nach dieser Definition sind X und Y vorläufig definiert. Um zu vermeiden, dass die Namen X und Y "verbraucht" werden, müssen Sie genauere Namen verwenden:

       STRUC     Point
Pt_X   resw      1
Pt_Y   resw      1
       ENDSTRUC

NASM bietet jedoch eine Alternative. Durch das Konzept der "lokalen Variablen" können Sie Strukturfelder definieren, in denen Sie die enthaltende Struktur in zukünftigen Referenzen angeben müssen:

       STRUC      Point
.X     resw       1
.Y     resw       1
       ENDSTRUC

Cursor ISTRUC     Point
       ENDISTRUC

       mov        ax,[Cursor+Point.X]
       mov        dx,[Cursor+Point.Y]

Da NASM die Typen nicht verfolgt, können Sie leider nicht die natürlichere Syntax verwenden:

       mov        ax,[Cursor.X]
       mov        dx,[Cursor.Y]

Noch ein Assembler - YASM

YASM ist eine vollständige Neufassung von NASM, ist jedoch sowohl mit Intel- als auch mit AT & T- Syntax kompatibel.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow