CodeNet / Языки программирования / Ассемблер / СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
Зарезервированные слова
-----------------------------------------------------------------
Зарезервированные или ключевые слова предназначены только
для использования Турбо Ассемблером. Их нельзя использовать для
определения присваиваний, меток или имен процедур. Ключевые слова
следует рассматривать как элементы построения программы на Ас-
семблере. Эти слова приведены в Таблице 5.1 (включая операции +,
*, -, директивы .386, ASSUME, MASM, QUIRKS) и предопределенные
идентификаторы ??time, ??version, @WordSize).
Зарезервированные слова Турбо Ассемблера Таблица 5.1
-----------------------------------------------------------------
: @datasize @filename NAME RADIX
; ??date ??filename NE .RADIX
= DB FWORD NEAR RECORD
? %DEPTH GE %NEWPAGE REPT
[] DF GLOBAL %NOCONDS .SALL
/ DISPLAY GROUP %NOCREF SEG
() DOSSEG GT %NOCTLS SEGMENT
+ DP HIGH NOEMUL .SEQ
- DQ IDEAL %NOINCL .SFCOND
* DT IF NOJUMPS SHL
. DUP IF1 %NOLIST SHORT
.186 DW IF2 NOLOCALS SHR
.286 DWORD IFB %NOMACS SIZE
.286C ELSE IFDEF NOMASM51 SIZESTR
.286P ELSEIF IFDIF NOMULTERRS SMALL
.287 EMUL IFDIF1 NOSMART SMART
.386 END IFE %NOSYMS STACK
.386C ENDIF IFIDN NOT .STACK
.387 ENDM IFIDNI NOTHING STRUC
.8086 ENDP IFNB %NOTRUNC SUBSTR
.8087 ENDS IFNDEF NOWARN SUBTTL
ALIGN EQ %INCL OFFSET %SUBTTL
.ALPHA EQU INCLUDE OR %SYMS
AND ERR INCLUDELIB ORG SYMTYPE
ARG .ERR INSTR %OUT %TABSIZE
ASSUME .ERR1 IRP P186 TBYTE
%BIN .ERR2 IRPC P286 %TEXT
BYTE .ERRB JUMPS P286N .TFCOND
CATSTR .ERRDEF LABEL P287 THIS
@CODE ERRDIF .LALL P386 ??time
CODESEG ERRDIFI LARGE P386N TITLE
@CODESIZE ERRE LENGTH P386P %TITLE
COMM ERRIDN .LFCOND P387 %TRUNC
COMMENT ERRIDNI %LINUM P8086 TYPE
%CONDS ERRIFNB %LIST P8087 .TYPE
.CONST ERRIFNDEF .LIST PAGE UDATASEG
@Cpu ERRNB LOCAL %PAGESIZE UFARDATA
%CREF ERRNDEF LOCALS PARA UNION
.CREF ERRNZ LOW %PNCT UNKNOWN
%CREFALL EVEN LT PNO87 USES
%CREFREF EVENDATA MACRO %POPLCTL ??version
%CREFUREF EXITM %MACS PROC WARN
%CTLS EXTRN MASK PTR WITH
@curseg FAR MASM PUBLIC WORD
@data FARDATA MASM51 PURGE @WordSize
.DATA @fardata MOD %PUSHLCTL .XALL
.DATA? .FARDATA MODEL PWORD .XLIST
DATAPTR @fardata? .MODEL QUIRKS XOR
DATASEG .FARDATA? MULTERRS QWORD
-----------------------------------------------------------------
Формат строки
-----------------------------------------------------------------
Строки исходного кода на языке Ассемблера имеют следующий
формат:
<метка> <инструкция/директива> <операнды> <;комментарий>
где <метка> представляет собой необязательное имя идентификатора,
<инструкция/директива> - это мнемоника инструкции или директивы,
<операнды> - содержат сочетание 0, 1 или 2 (иногда более) конс-
тант, ссылок на память или регистры, или текстовых строк, как это
требуется в каждой конкретной инструкции или директиве, <;коммен-
тарий> - необязательный комментарий.
В любом месте в строки качестве символа продолжения строки
можно поместить символ обратной косой черты (\). Однако данный
символ нельзя использовать для разбиения идентификаторов. Обрат-
ная косая черта означает: "считать следующую строку, и продолжить
обработку с данной точки". При этом вы можете комментировать каж-
дую строку. Например:
foo mystructure \ ; Начать заполнение структуры
<0, \ ; Сначала - нулевое значение
1, \ ; Затем - единица
2> \ ; Cтруктура завершается значением 2
В двух контекстах символы продолжения строки не распознают-
ся. В общем случае они не распознаются в любом контексте, где
символы обрабатываются как текст, а не как идентификаторы, числа
или строки, либо в режиме MASM, когда продолжение строки исполь-
зуется в первых двух идентификаторах оператора. Например:
ifdif <123\>,<456\>
Здесь два вложенных символа "\" не распознаются, как продол-
жение строки.
comment \
:
начинает блок комментария, а не определяет идентификатор ближнего
типа с именем COMMENT.
Символ продолжения строки не распознается также внутри мак-
роопределений. Однако он распознается при расширении макрокоман-
ды.
Давайте рассмотрим каждый из этих элементов более подробно.
Метки
-----------------------------------------------------------------
Метки - это ни что иное, как имена, использующиеся в прог-
рамме для ссылки на числа и строки символов или ячейки памяти.
Метки позволяют вам присваивать имена переменным в памяти, значе-
ниям и адресам, где находятся конкретные инструкции. Например, в
следующей программе, которая вычисляет факториал 5, используется
несколько меток:
DOSSEG
.MODEL SMALL
.STACK 200h
.DATA
FactorialValue DW ?
Factorial DW ?
.CODE
FiveFactorial PROC
mov ax,@Data
mov ds,ax
mov [FactorialValue],1
mov [Factorial],2
mov cx,4
FiveFactorialLoop:
mov ax,[FactorialValue]
mul [Factorial]
mov [FactorialValue],ax
inc [Factorial]
loop FiveFactorialLoop
ret
FiveFactorial ENDP
END
Метки FactorialValue и Factorial эквивалентны адресам двух
16-битовых переменных. Они используются для последующей ссылки в
программе на эти две переменные. Метка FiveFactorial - это имя
подпрограммы (процедуры или функции), содержащей код. Она позво-
ляет вызывать этот код в других частях программы. Наконец, метка
FiveFactorialLoop эквивалентна адресу инструкции:
mov ax,[FactorialValue]
благодаря которой оператор LOOP в конце программы может осуще-
ствлять обратный переход на эту инструкцию.
Метки могут состоять из следующих символов:
A - Z a - z _ @ $ ? 0 - 9
В режиме MASM допускается также точка (.) (см. Главу 11), но
только в качестве первого символа. Цифры 0 - 9 не могут использо-
ваться в качестве первых символов метки. Символы $ и ? имеют
специальное значение, поэтому их не следует использовать в именах
ваших идентификаторах.
Каждая метка должна определяться только один раз, то есть
метки должны быть уникальными. (Из этого правила есть исключения.
Например, специальные метки, определенные с помощью директивы =,
локальные метки в макрокомандах и подпрограммы режима Ideal). Как
операнды метки могут использоваться любое число раз.
Метка может занимать всю строку, то есть на этой строке кро-
ме метки может отсутствовать инструкция или директива. В этом
случае значением метки является адрес инструкции или директивы на
следующей строке программы. Например, во фрагменте программы:
.
.
jmp DoAddition
.
.
.
DoAddition:
add ax,dx
.
.
.
следующей инструкцией, выполняемой после инструкции JMP, которая
выполняет переход на метку DoAddition, является инструкция ADD
AX,DX. Предыдущий пример эквивалентен следующему:
.
.
jmp DoAddition
.
.
.
DoAddition: add ax,dx
.
.
.
(Список директив приведен в Главе 3 "Справочного руководс-
тва", а о регистрах процессора 8086 рассказывается в Главе 4.)
В размещении каждой метки на своей собственной строке имеют-
ся два преимущества. Во-первых, когда вы размещаете каждую метку
на отдельной строке, легче использовать длинные метки без наруше-
ния структуры (формата) программы на Ассемблере, что сделало бы
ее менее читабельной. Во-вторых, справа от метки легче добавить
новую инструкцию, если метка не находится на той же строке, что и
инструкция. Чтобы преобразовать последний пример к виду:
.
.
jmp DoAddition
.
.
.
DoAddition: mov dx,[MemVar]
add ax,dx
.
.
.
вам пришлось бы разделить строку с меткой DoAddition и добавить
новый текст. Если же DoAddition находится на отдельной строке, вы
можете просто добавить после этой метки новую строку.
Метка не может совпадать с любым из используемых в выраже-
ниях встроенных символов, включая имена регистров (AX, BX и т.д.)
и операторы, используемые в выражениях (PTR, BYTE, WORD и т.д.).
В качестве меток нельзя также использовать любую из директив
IFxxx или .ERRxxx. Несколько других зарезервированных в Турбо Ас-
семблере идентификаторов могут использоваться только в определен-
ных контекстах. Эти идентификаторы включают в себя NAME, INCLUDE
и COMMENT. Данные имена могут использоваться, как имена элементов
структур, но не в качестве общих идентификаторов (более подробно
о структурах рассказывается в Главе 9).
Лучший подход - это избежать необходимости использования в
качестве меток любого из встроенных имен идентификаторов. Напри-
мер, метки:
bx DW 0
PTR:
были бы неприемлемы, так как BX - это регистр, а PTR - операция в
выражении. Однако метка:
Old_BX DW 0
вполне допустима.
Приведем еще примеры допустимых меток:
MainLoop
calc_long_sum
Error0
Iterate
Draw$Dot
Delay_100_milliseconds
Метки в коде программы (и содержащиеся на отдельной строке,
и после которых на той же строке следуют директивы или инструк-
ции) должны заканчиваться двоеточием (:). Двоеточие просто завер-
шает метку и не является ее частью. Например, в следующем фраг-
менте программы:
.
.
.
LoopTop:
mov al,[si]
inc si
and al,al
jz Done
jmp LoopTop
Done: ret
.
.
.
метки LoopTop и Done определены с двоеточиями, но в ссылках на
эти метки двоеточия не указываются.
Другие метки в общем случае не должны завершаться двоеточи-
ем. В примере программы в начале данного раздела содержатся нес-
колько меток без двоеточий.
Имена меткам следует назначать так, чтобы они имели смысл.
Сравните:
.
.
cmp al,'a'
jb NotALowerCaseLetter ; не строчная буква
cmp al,'z'
ja NotALowerCaseLetter
sub al,20h ; преобразовать в верхний
; регистр (прописную
; букву)
NotALowerCaseLetter:
.
.
и следующий фрагмент программы:
.
.
cmp al,'a'
jb P1
cmp al,'z'
ja P1
sub al,20h ; преобразовать в верхний
; регистр
P1:
.
.
Вариант с описательной меткой (особенно для владеющих ан-
глийским языком, для русскоязычных программистов, возможно, лучше
использовать варианты типа Ne_strochnaja_bukva) гораздо более по-
нятен, в то время как второй с первого взгляда, мягко говоря, за-
гадочен. Метки могут содержать символы подчеркивания. В зависи-
мости от вашего предпочтения можно использовать метки типа not_a_
lower_case_ letter или Not _A_Lower_Case_Letter.
