Ricerca…


Microsoft Assembler - MASM

Dato che l'8086/8088 è stato utilizzato nel PC IBM e il sistema operativo in quel caso era il più spesso usato da Microsoft, il MASM assembler di Microsoft era di fatto lo standard per molti anni. Seguiva da vicino la sintassi di Intel, ma permetteva una sintassi comoda ma "allentata" che (a ben vedere) causava solo confusione ed errori nel codice.

Un esempio perfetto è il seguente:

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

L'ultima istruzione MOV inserisce il contenuto di Symbol in CX o l' indirizzo di Symbol in CX ? CX finisce con 0x1234 o 0x0102 (o qualsiasi altra cosa)? Si scopre che CX finisce con 0x1234 - se si desidera l'indirizzo, è necessario utilizzare l' OFFSET

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

Intel Assembler

Intel ha scritto le specifiche del linguaggio assembly 8086, un derivato dei precedenti processori 8080, 8008 e 4004. In quanto tale, l'assemblatore che hanno scritto ha seguito con precisione la propria sintassi. Tuttavia, questo assemblatore non è stato usato molto ampiamente.

Intel ha definito i propri opcode con zero, uno o due operandi. Le istruzioni a due operandi erano definite nell'ordine di dest , l' source , che era diverso da altri assemblatori al momento. Ma alcune istruzioni utilizzavano registri impliciti come operandi: bastava sapere cosa fossero. Intel ha anche utilizzato il concetto di opcode "prefisso": un opcode avrebbe influito sull'istruzione successiva.

; 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 ha anche infranto una convenzione utilizzata da altri assemblatori: per ogni opcode, è stato inventato un diverso codice mnemonico. Ciò richiedeva nomi sottilmente o distintamente diversi per operazioni simili: ad es. LDM per "Carica da memoria" e LDI per "Carica immediato". Intel ha utilizzato l'unico MOV mnemonico e ha previsto che l'assemblatore stabilisse quale opcode utilizzare dal contesto. Ciò ha causato molti insidie ​​e errori per i programmatori in futuro, quando l'assemblatore non ha potuto intuire ciò che il programmatore voleva davvero ...

Assemblatore AT & T - come

Sebbene l'8086 sia stato maggiormente utilizzato nei PC IBM insieme a Microsoft, c'erano anche altri computer e sistemi operativi che lo utilizzavano: in particolare Unix. Quello era un prodotto di AT & T, e aveva già Unix in esecuzione su una serie di altre architetture. Queste architetture utilizzavano una sintassi di assembly più convenzionale, in particolare che le istruzioni a due operandi le specificavano source , nell'ordine dest .

Quindi le convenzioni assembler AT & T ignoravano le convenzioni dettate da Intel, e un nuovo dialetto fu introdotto per la gamma x86:

  • I nomi dei registri erano prefissati da % :
    %al , %bx ecc.
  • I valori immediati erano prefigurati da $ :
    $4
  • Gli operandi erano in source , l'ordine dest
  • Gli opcode includevano le dimensioni dei loro operandi:
    movw $4, %ax ; Move word 4 into AX

Turbo Assembler di Borland - TASM

Borland ha iniziato con un compilatore Pascal che hanno chiamato "Turbo Pascal". Questo è stato seguito da compilatori per altre lingue: C / C ++, Prolog e Fortran. Hanno anche prodotto un assemblatore chiamato "Turbo Assembler", che, in seguito alla convenzione di denominazione di Microsoft, hanno chiamato "TASM".

TASM ha provato a risolvere alcuni dei problemi di scrittura del codice utilizzando MASM (vedere sopra), fornendo un'interpretazione più restrittiva del codice sorgente in una modalità IDEAL specificata. Di default assumeva la modalità MASM , quindi poteva assemblare direttamente la sorgente MASM, ma Borland scoprì che dovevano essere compatibili bug-for-bug con le idiosincrasie più "stravaganti" della MASM, così aggiunsero anche una modalità QUIRKS .

Poiché TASM era (molto) più economico di MASM, aveva una vasta base di utenti, ma non molte persone usavano la modalità IDEAL, nonostante i suoi vantaggi.

Assemblatore GNU - gas

Quando il progetto GNU aveva bisogno di un assemblatore per la famiglia x86, sono andati con la versione AT & T (e la sua sintassi) che era associata a Unix piuttosto che alla versione Intel / Microsoft.

Netwide Assembler - NASM

NASM è di gran lunga l'assemblatore più portato per l'architettura x86 - è disponibile praticamente per tutti i sistemi operativi basati su x86 (incluso anche con MacOS) ed è disponibile come assemblatore multipiattaforma su altre piattaforme.

Questo assemblatore utilizza la sintassi Intel, ma è diverso dagli altri perché si focalizza pesantemente sul proprio linguaggio "macro" - questo permette al programmatore di creare espressioni più complesse usando definizioni più semplici, permettendo di creare nuove "istruzioni".

Sfortunatamente questa potente funzione ha un costo: il tipo di dati si intromette nelle istruzioni generalizzate, quindi la digitazione dei dati non viene applicata.

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!

Tuttavia, la NASM ha introdotto una funzionalità che gli altri mancavano: i nomi dei simboli con scope. Quando si definisce un simbolo in altri assemblatori, quel nome è disponibile in tutto il resto del codice - ma che "usa" quel nome, "inquinando" lo spazio dei nomi globale con i simboli.

Ad esempio (usando la sintassi NASM):

       STRUC     Point
X      resw      1
Y      resw      1
       ENDSTRUC

Dopo questa definizione, X e Y sono definiti per sempre. Per evitare di "usare" i nomi X e Y , era necessario usare nomi più precisi:

       STRUC     Point
Pt_X   resw      1
Pt_Y   resw      1
       ENDSTRUC

Ma NASM offre un'alternativa. Sfruttando il suo concetto di "variabile locale", è possibile definire i campi di struttura che richiedono di nominare la struttura di contenimento in riferimenti futuri:

       STRUC      Point
.X     resw       1
.Y     resw       1
       ENDSTRUC

Cursor ISTRUC     Point
       ENDISTRUC

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

Sfortunatamente, poiché NASM non tiene traccia dei tipi, non è possibile utilizzare la sintassi più naturale:

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

Ancora un altro assemblatore - YASM

YASM è una riscrittura completa di NASM, ma è compatibile con entrambe le sintassi Intel e AT & T.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow