Intel x86 Assembly Language & Microarchitecture
Монтажники
Поиск…
Microsoft Assembler - MASM
Учитывая, что 8086/8088 использовался на ПК IBM, а операционная система, которая чаще всего принадлежала Microsoft, ассемблер MASM от Microsoft был стандартом де-факто в течение многих лет. Он внимательно следил за синтаксисом Intel, но допускал некоторый удобный, но «свободный» синтаксис, который (в ретроспективе) вызывал только путаницу и ошибки в коде.
Идеальный пример:
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 ; ????
Включает ли последняя инструкция MOV содержимое Symbol в CX или адрес Symbol в CX ? 0x1234 ли CX 0x1234 или 0x0102 (или что-то еще)? Оказывается, CX заканчивается 0x1234 - если вам нужен адрес, вам нужно использовать спецификатор OFFSET
MOV AX, [Symbol] ; Contents of Symbol
MOV CX, OFFSET Symbol ; Address of Symbol
Ассемблер Intel
Intel написала спецификацию языка ассемблера 8086, производную от предыдущих 8080, 8008 и 4004 процессоров. Таким образом, ассемблер, который они писали, точно следовал их синтаксису. Однако этот ассемблер не использовался очень широко.
Intel определила свои коды операций, чтобы иметь либо нулевой, либо один, либо два операнда. Инструкции два операнда были определены , чтобы быть в dest , source порядок, который отличается от других монтажников в то время. Но некоторые инструкции использовали неявные регистры в качестве операндов - вам просто нужно было знать, что они собой представляют. Intel также использовала концепцию опкодов «префикс» - один код операции повлиял бы на следующую инструкцию.
; 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 также нарушила соглашение, используемое другими ассемблерами: для каждого кода операции была изобретена другая мнемоника. Для этого требовались тонко или явно разные имена для подобных операций: например, LDM для «Load from Memory» и LDI для «Load Immediate». Intel использовала один мнемонический MOV - и ожидала, что ассемблер сможет определить, какой код операции использовать из контекста. Это вызвало много ошибок и ошибок для программистов в будущем, когда ассемблер не смог понять, что действительно хотел программист ...
AT & T - как
Несмотря на то, что 8086 был наиболее употребительным в IBM PC вместе с Microsoft, в нем также использовался ряд других компьютеров и операционных систем: в первую очередь Unix. Это был продукт AT & T, и у него уже был Unix, работающий на ряде других архитектур. В этих архитектурах использовался более традиционный синтаксис сборки - особенно, что инструкции из двух операндов указывали их в source , dest порядке.
Таким образом, AT & T ассемблерные соглашения перечеркнули соглашения, продиктованные Intel, и был введен целый новый диалект для диапазона x86:
- Названия регистра были префиксом
%:
%al,%bxи т. д. - Непосредственные значения были получены в
$:
$4 - Операнды были в
source,destпорядке - Коды операций включали в себя размеры операндов:
movw $4, %ax ; Move word 4 into AX
Турбокомпрессор Borland - TASM
Borland начал с компилятора Pascal, который они назвали «Turbo Pascal». За этим следовали компиляторы для других языков: C / C ++, Prolog и Fortran. Они также создали ассемблер под названием «Turbo Assembler», который, следуя соглашению об именах Microsoft, называется «TASM».
TASM попытался исправить некоторые проблемы написания кода с помощью MASM (см. Выше), предоставив более строгую интерпретацию исходного кода в указанном режиме IDEAL . По умолчанию он принял режим MASM , поэтому он мог напрямую собрать источник MASM, но затем Borland обнаружил, что они должны быть ошибкой для ошибок, совместимыми с более «причудливыми» идиосинкратиями MASM, поэтому они также добавили режим QUIRKS .
Поскольку TASM был (намного) дешевле, чем MASM, у него была большая пользовательская база, но не многие люди использовали режим IDEAL, несмотря на его преувеличенные преимущества.
Ассемблер GNU - газ
Когда проекту GNU нужен ассемблер для семейства x86, они пошли с версией AT & T (и ее синтаксисом), которая была связана с Unix, а не с версией Intel / Microsoft.
Netwide Assembler - NASM
NASM на сегодняшний день является самым портированным ассемблером архитектуры x86 - он доступен практически для каждой операционной системы на базе x86 (даже будучи включенным в MacOS) и доступен в качестве кросс-платформенного ассемблера на других платформах.
Этот ассемблер использует синтаксис Intel, но он отличается от других, поскольку он в значительной степени фокусируется на собственном «макро» языке - это позволяет программисту создавать более сложные выражения с использованием более простых определений, позволяя создавать новые «инструкции».
К сожалению, эта мощная функция стоит дорого: тип данных мешает обобщенным инструкциям, поэтому ввод данных не выполняется.
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 представила одну из функций, которой не хватало другим: имена символов в скобках. Когда вы определяете символ в других ассемблерах, это имя доступно во всей остальной части кода, но это «использует» это имя, «загрязняя» глобальное пространство имен символами.
Например (используя синтаксис NASM):
STRUC Point
X resw 1
Y resw 1
ENDSTRUC
После этого определения X и Y навсегда определены. Чтобы избежать «использования» имен X и Y , вам нужно было использовать более определенные имена:
STRUC Point
Pt_X resw 1
Pt_Y resw 1
ENDSTRUC
Но NASM предлагает альтернативу. Используя концепцию «локальная переменная», вы можете определить поля структуры, которые требуют, чтобы вы назначили содержащую структуру в будущих ссылках:
STRUC Point
.X resw 1
.Y resw 1
ENDSTRUC
Cursor ISTRUC Point
ENDISTRUC
mov ax,[Cursor+Point.X]
mov dx,[Cursor+Point.Y]
К сожалению, поскольку NASM не отслеживает типы, вы не можете использовать более естественный синтаксис:
mov ax,[Cursor.X]
mov dx,[Cursor.Y]
Еще один ассемблер - YASM
YASM - это полная перезапись NASM, но совместима с синтаксисами Intel и AT & T.