Szukaj…


Microsoft Assembler - MASM

Biorąc pod uwagę, że 8086/8088 był używany w komputerze IBM, a system operacyjny na nim najczęściej pochodzi od Microsoftu, asembler MASM Microsoftu był de facto standardem na wiele lat. Śledził ściśle składnię Intela, ale dopuszczał pewną wygodną, ale „luźną” składnię, która (z perspektywy czasu) powodowała jedynie zamieszanie i błędy w kodzie.

Doskonały przykład jest następujący:

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  ; ????

Czy ostatnia instrukcja MOV umieszcza zawartość Symbol w CX , czy adres Symbol w CX ? Czy CX kończy się na 0x1234 lub 0x0102 (lub cokolwiek innego)? Okazuje się, że CX kończy się na 0x1234 - jeśli chcesz adres, musisz użyć specyfikatora OFFSET

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

Asembler Intel

Intel napisał specyfikację języka asemblera 8086, pochodnej wcześniejszych procesorów 8080, 8008 i 4004. W związku z tym asembler, który napisali, dokładnie przestrzegał własnej składni. Jednak ten asembler nie był szeroko stosowany.

Intel zdefiniował swoje kody operacyjne tak, aby miały zero, jeden lub dwa operandy. Instrukcje z dwoma operandami zostały zdefiniowane w kolejności dest , source , która różniła się w tym czasie od innych asemblerów. Ale niektóre instrukcje wykorzystywały rejestry niejawne jako operandy - wystarczyło wiedzieć, co to są. Intel zastosował także koncepcję „prefiksów” kodów - jeden kod będzie miał wpływ na następną instrukcję.

; 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 złamał również konwencję używaną przez inne asemblery: dla każdego kodu operacyjnego wynaleziono inną mnemonikę. Wymagało to subtelnie lub wyraźnie różnych nazw dla podobnych operacji: np. LDM dla „Load from Memory” i LDI dla „Load Natychmiastowe”. Intel użył jednego mnemonicznego MOV - i spodziewał się, że asembler obliczy, który kod operacji ma być użyty z kontekstu. To spowodowało wiele pułapek i błędów dla programistów w przyszłości, gdy asembler nie mógł zrozumieć, czego tak naprawdę chciał programista ...

Asembler AT&T - as

Chociaż 8086 był najczęściej używany w komputerach IBM wraz z Microsoftem, wiele innych komputerów i systemów operacyjnych również z niego korzystało: przede wszystkim Unix. To był produkt AT&T i miał już system Unix działający na wielu innych architekturach. W tych architekturach zastosowano bardziej konwencjonalną składnię asemblera - zwłaszcza, że instrukcje składające się z dwóch argumentów określały je w kolejności source , dest .

Konwencje asemblera AT&T zastąpiły konwencje dyktowane przez Intela i wprowadzono zupełnie nowy dialekt dla zakresu x86:

  • Nazwy rejestrów były poprzedzone przez % :
    %al , %bx itp.
  • Natychmiastowe wartości były poprzedzone przez $ :
    $4
  • Operandy były w kolejności source , dest
  • Opcodes zawierały rozmiary operandów:
    movw $4, %ax ; Move word 4 into AX

Borland's Turbo Asembler - TASM

Borland zaczął od kompilatora Pascal, który nazwali „Turbo Pascal”. Następnie pojawiły się kompilatory dla innych języków: C / C ++, Prolog i Fortran. Wyprodukowali również asembler o nazwie „Turbo Asembler”, który zgodnie z konwencją nazewnictwa Microsoftu nazwali „TASM”.

TASM próbował rozwiązać niektóre problemy z pisaniem kodu za pomocą MASM (patrz wyżej), zapewniając bardziej ścisłą interpretację kodu źródłowego w określonym trybie IDEAL . Domyślnie zakładał tryb MASM , więc mógł bezpośrednio składać źródło MASM - ale potem Borland stwierdził, że muszą być kompatybilne z błędami z bardziej „dziwacznymi” QUIRKS MASM - więc dodali również tryb QUIRKS .

Ponieważ TASM był (znacznie) tańszy niż MASM, miał dużą bazę użytkowników - ale niewiele osób korzystało z trybu IDEAL, pomimo jego reklamowanych zalet.

Asembler GNU - gaz

Kiedy projekt GNU potrzebował asemblera dla rodziny x86, wybrał wersję AT&T (i jej składnię), która była powiązana z Uniksem, a nie z wersją Intel / Microsoft.

Netwide Assembler - NASM

NASM jest zdecydowanie najbardziej portowanym asemblerem dla architektury x86 - jest dostępny dla praktycznie każdego systemu operacyjnego opartego na x86 (nawet dołączony do MacOS) i jest dostępny jako asembler dla wielu platform na innych platformach.

Ten asembler używa składni Intela, ale różni się od innych, ponieważ mocno koncentruje się na swoim własnym języku „makro” - pozwala to programiście tworzyć bardziej złożone wyrażenia przy użyciu prostszych definicji, umożliwiając tworzenie nowych „instrukcji”.

Niestety ta potężna funkcja ma swoją cenę: typ danych przeszkadza w uogólnionych instrukcjach, więc typowanie danych nie jest wymuszane.

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!

Jednak NASM wprowadził jedną cechę, której innym brakowało: nazwy symboli o zasięgu. Kiedy definiujesz symbol w innych asemblerach, nazwa ta jest dostępna w pozostałej części kodu - ale to „zużywa” tę nazwę, „zanieczyszczając” globalną przestrzeń nazw symbolami.

Na przykład (przy użyciu składni NASM):

       STRUC     Point
X      resw      1
Y      resw      1
       ENDSTRUC

Po tej definicji X i Y są na zawsze zdefiniowane. Aby uniknąć „używania” nazw X i Y , musisz użyć bardziej określonych nazw:

       STRUC     Point
Pt_X   resw      1
Pt_Y   resw      1
       ENDSTRUC

Ale NASM oferuje alternatywę. Wykorzystując koncepcję „zmiennej lokalnej”, możesz zdefiniować pola struktury, które wymagają nominowania struktury zawierającej w przyszłych odniesieniach:

       STRUC      Point
.X     resw       1
.Y     resw       1
       ENDSTRUC

Cursor ISTRUC     Point
       ENDISTRUC

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

Niestety, ponieważ NASM nie śledzi typów, nie można użyć bardziej naturalnej składni:

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

Yet Another Asembler - YASM

YASM to kompletne przepisanie NASM, ale jest kompatybilne zarówno ze składniami Intela, jak i AT&T.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow