Формат команд языка Assembler — КиберПедия 

Эмиссия газов от очистных сооружений канализации: В последние годы внимание мирового сообщества сосредоточено на экологических проблемах...

Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьше­ния длины пробега и улучшения маневрирования ВС при...

Формат команд языка Assembler

2022-10-05 24
Формат команд языка Assembler 0.00 из 5.00 0 оценок
Заказать работу

Прежде чем начать рассматривать формат команд, следует сделать некоторое уточнение: в языке Assembler имеются мнемонические команды (или просто команды) и команды-директивы (или просто директивы).

Определение 3.2

Мнемоническая команда указывает ассемблеру, какое действие должен выполнить данный оператор.

Мнемоническая команда компилируется ассемблером в машинный код, который является выполняемой инструкцией для процессора. Мнемонические команды должны располагаться только в сегментах кода.

Определение 3.3

Директивы являются инструкциями не для процессора, а для самого компилятора и позволяют управлять процессом ассемблирования и формирования листинга.

Директивы не компилируются в какие-либо машинные коды и действуют только в процессе ассемблирования программы.

Основной формат кодирования команд языка Assembler имеет следующий вид:

[<метка>] <команда> [<операнд>]

Метка (если имеется), команда и операнд (если имеется) разделяются по крайней мере одним пробелом или символом табуляции. Максимальная длина строки - 132 символа, однако предпочтительно работать со строками в 80 символов (по ширине экрана).

Метка в языке Assembler может содержать следующие символы:

Буквы: от A до Z и от a до z;
Цифры: от 0 до 9
Специальные символы: знак вопроса (?), точка (.) (только первый символ), знак @, подчеркивание (_), доллар ($).

Первым символом в метке должна быть буква или специальный символ. Максимальная длина метки - 31 символ.

Если метка стоит перед мнемонической командой, то она должна завершаться знаком двоеточия (:). Метки перед директивами записываются без двоеточия.

Примеры кодирования:

метка команда операнды  
COUNT db 1 ;кодирование директивы;определения байта
m25: mov AX,0 ;кодирование команды;пересылки

Замечание 3.1

Компилятор не делает различия между строчными и прописными буквами.

Замечание 3.2

Все имена регистров являются зарезервированными и используются только для указания соответствующих регистров.

Основные директивы компилятора

Директива SEGMENT

Любые ассемблерные программы содержат по крайней мере один сегмент - сегмент кода. Кроме того, в программе могут быть сегменты данных и сегмент стека. Ассемблерная директива для описания сегмента имеет следующий формат:

Метка Директива Операнд
<имя> segment [<параметры>]
  .  
  .  
<имя> ends  

Имя сегмента должно обязательно присутствовать и быть уникальным. Директива ends означает конец сегмента. Обе директивы segment и ends должны иметь одинаковые имена.

Параметры в данной директиве могут быть трех типов:

<параметры>::=
[<выравнивание>] [<объединение>] ['<класс>']

Выравнивание. Параметр выравнивания определяет начальную границу сегмента:

Параметр Граница  
page xxx00  
para xxxx0 (граница по умолчанию)
word xxxxe (четная граница)
byte xxxxx .

Здесь x - любая шестнадцатеричная цифра, e - четная шестнадцатеричная цифра.

Объединение. Операнд объединения указывает способ обработки сегмента при компоновке:

Параметр Назначение
none Значение по умолчанию. Сегмент должен быть логически отделен от других сегментов, хотя физически он может быть смежным. Предполагается, что сегмент имеет собственный базовый адрес.
public Все сегменты этого типа, имеющие одинаковое имя и класс загружаются компоновщиком в смежные области и имеют один общий базовый адрес.
stack Служит для объявления сегмента стека. Для компоновщика этот параметр аналогичен параметру public. Если в компонуемой программе объявлено более одного стека, то стековый указатель устанавливается на начало первого сегмента.
common Сегменты этого типа с одинаковыми именами и классами компоновщик располагает в одной общей области памяти и устанавливает один общий базовый адрес. При выполнении происходит наложение второго сегмента на первый. Размер общей области определяется самым длинным сегментом.
at <адрес> Размещает сегмент по заданному абсолютному адресу. Адрес должен быть адресом начала параграфа без указания нуля в младшем шестнадцатеричном разряде.

Класс. Этим операндом может быть любое правильное имя, заключенное в апострофы. Данный операнд используется компоновщиком для обработки сегментов, имеющих одинаковые имена и классы.

Для объединения сегментов в группы можно использовать директиву group.

Пример:

DTSG segment para public 'Data'
x1 dw 0
x2 dw 10
A db 100 dup(?)
DTSG ends
STSG segment para stack 'Stack'
db 200 dup(?)
STSG ends

Директива GROUP

Программа может содержать несколько сегментов одного типа (код, данные, стек). Назначение директивы group - собрать однотипные сегменты под одно имя так, чтобы они поместились в один сегмент. Формат директивы:

Метка Директива Операнды
<имя> group <имя сегмента>{,<имя сегмента>}

В следующем примере директива group объединяет сегменты SEG1 и SEG2 в один:

GROUPX group     SEG1,SEG2
SEG1 segment para 'Data'
    .
             .
SEG1 ends
SEG2 segment para 'Data'
    .
             .
SEG2 ends

Директива ASSUME

Назначение директивы - установить для ассемблера связь между сегментами и сегментными регистрами. Формат директивы:

assume <сегментный регистр>:<имя>
       {,<сегментный регистр>:<имя>}

В директиве <имя>::=<имя сегмента>|<имя группы>. Одна директива assume может назначить до четырех сегментных регистров в любой последовательности.

Замечание 3.3

Назначение регистра не означает автоматическую загрузку в него адреса сегмента. Эту операцию необходимо выполнять отдельно.

Для отмены ранее назначенного в директиве assume сегментного регистра необходимо использовать ключевое слово nothing. Например,

assume ES:nothing.

Если, например, регистр DS оказался не назначен или отменен, то для доступа к элементу в сегменте данных в адресных кодах команд необходимо явно указать сегментный регистр:

mov AX,DS:[BX]

mov AX,DS:x1.

Конечно, сегментный регистр должен содержать правильное значение сегментного адреса.

Директивы определения данных

Ассемблер обеспечивает два способа определения данных: во-первых, через указание длины данных и, во-вторых, по их содержимому. Формат директивы следующий:

Метка Директива Операнд
[<имя>] dn <выражение>

 

Имя элемента данных необязательно, но если в программе имеются ссылки на некоторый элемент, то это делается посредством имени.

Для определения элементов данных имеются директивы: db - определить байт, dw - определить слово, dd - определить двойное слово, dq - определить учетверенное слово, dt - определить десятибайтный элемент.

Выражение может содержать константу, задающую начальное значение в поле, например

FLD1 db 25,

или знак вопроса для неопределенного значения, например
FLD2 db?

Выражение может содержать несколько констант, разделенных запятыми:

FLD3 db 11,23,14,15.

Ассемблер определяет эти константы в виде последовательности смежных байтов. Ссылка по имени FLD3 указывает на первый элемент, 11, ссылка по FLD3+1 - на второй, 23 и т.д.
Выражение допускает также повторение константы в следующем формате:

Метка Дир-ва Операнд
[<имя>] dn <число повторений> dup(<выражение>)

 

Например

dw 10 dup(?);Десять неопределенных
                                                      ; слов.

db 5 dup(14);Пять байт,
                                          ;содержащих число 14.

db 3 dup(4 dup(8));Двенадцать восьмерок.

Выражение может содержать символьную строку или числовую константу.

Символьная строка используется для описания символьных данных. Содержимое строки отмечается апострофами, например 'PC', или кавычками - "PC". Символьная строка определяется только директивой db.

Числовые константы применяются для арифметических значений и для адресов памяти. Числовые константы могут быть записаны в десятичном формате, шестнадцатеричном формате, двоичном формате, восьмеричном формате и десятичном формате с плавающей точкой.

Десятичный формат допускает десятичные цифры от 0 до 9 и обозначается последней буквой d, которую можно не указывать, например 125 или 125d.

Шестнадцатеричный формат допускает цифры от 0 до F и обозначается в конце буквой h. Так как ассемблер полагает, что с буквы начинаются идентификаторы, то первой цифрой шестнадцатеричной константы должна быть цифра от 0 до 9. Например, F1C0h - неверно записанная константа, она должна быть записана следующим образом: 0F1C0h.

Двоичный формат допускает цифры 0 и 1 и обозначается в конце буквой b, например, 1101b.

Восьмеричный формат допускает цифры от 0 до 7 и обозначается последней буквой q.

Директива EQU

Директива equ в отличие от директив определения данных не отводит места в сегменте памяти, а всего лишь устанавливает соответствие между идентификатором и константой:

Метка Директива Операнд
[<идентификатор>] equ <константа>

Эти идентификаторы можно использовать в качестве непосредственных значений в других командах. Везде в программе, где встретится объявленный в директиве идентификатор, он будет заменен на соответствующую константу.

Директива PROC

Любая программа языка Assembler состоит из совокупности процедур. Каждая процедура представляет собой последовательность кодов, начинающуюся директивой proc и завершающуюся директивой endp:

Метка Директива Операнд
<имя процедуры> proc [ near | far]
  ...  
  <коды>  
  ...  
<имя процедуры> endp  

Ассемблер допускает переход на процедуру командой перехода, например командой jmp, но обычно на практике используются команда call для вызова процедуры и команда ret - для возврата из процедуры.

Процедура, находящаяся в одном сегменте с вызывающей процедурой может иметь тип near (тип по умолчанию). Если процедура является внешней по отношению к вызывающему сегменту, то ее вызов может осуществляться только командой call, а сама процедура должна быть объявлена директивой public. Более того, если в вызываемой процедуре используется другое значение assume CS, то необходимо процедуру кодировать с атрибутом far. При вызове любой процедуры с помощью команды call необходимо обеспечить возврат по команде ret.

Директивы EXTRN и PUBLIC

Назначение директивы public - информировать ассемблер, что на указанные имена имеются ссылки из других ассемблерных модулей. Формат директивы:

Директива Операнды
public <имя>{,<имя>}

Назначение директивы extrn - информировать ассемблер о переменных и метках, которые определены в других модулях, но имеют ссылки из данного модуля. В других модулях соответствующие имена должны быть определены и идентифицированы как public. Формат директивы:

 

Директива Операнды
Extrn <имя>:<тип>{,<имя>:<тип>},

где <тип>::= near | far | byte | word | dword | abs.

Рассмотрим, например, основную программу MAINPROG, которая вызывает подпрограмму SUBPROG с помощью межсегментного вызова call (листинг 3.1):

Листинг 3.1

; Модуль 1
              extrn SUBPROG:far
MAINPROG proc far
             .
              call SUBPROG
    .
             .
MAINPROG endp
; Модуль 2
SUBPROG proc far
                   public SUBPROG
             .
             .
              ret
SUBPROG endp

 

Команда call в MAINPROG должна знать, что SUBPROG существует вне данного модуля (иначе ассемблер выдаст сообщение о том, что идентификатор SUBPROG не определен). Для этого с помощью директивы extrn можно указать ассемблеру, что имя на SUBPROG имеет атрибут far и определено в другом ассемблерном модуле. Директива public в модуле 2 дает указания ассемблеру подготовить информацию компоновщику для установления связи между ссылками на имя SUBPROG в других модулях и этим именем в модуле 2. На основании этой информации компоновщик (редактор связей) впоследствии установит необходимые связи. Если же имя SUBPROG в директиве public объявлено не будет, то редактор связей выдаст сообщение об ошибке.

Директива END

Как уже показано ранее, директива ends завершает сегмент, а директива endp завершает процедуру. Директива end в свою очередь полностью завершает модуль:

Директива Операнд
end [<имя процедуры>]

В качестве операнда должно быть имя процедуры, с которой начинается выполнение программы (имя главной процедуры). Главная процедура обязательно должна иметь атрибут far. Операнд может быть опущен, если модуль не предназначен для выполнения, например, если ассемблируются только определения данных, или этот модуль должен быть скомпонован с другим (главным) модулем.

Мнемонические команды

Мнемонические команды (или просто команды) языка ассемблер имеют двухадресную, одноадресную и безадресную структуры. Общий формат их имеет вид:

[<метка>:] <мнемокод> [<операнд1> [,<операнд2>]].

Сочетание операндов в командах не может быть произвольным. Например, нет ни одной команды, в которой оба операнда были бы ссылками на оперативную память. Операнды мы будем подразделять следующим образом: операнды, ссылающиеся на регистры, которые обозначим символом «r»; операнды, ссылающиеся на память путем прямой или индексной (косвенной) адресации, - символом «m»; операнды - непосредственные значения - символом «v».

По своему функциональному назначению команды классифицируем следующим образом:

- команды арифметических операций;

- команды сравнения;

- команды побитовых операций;

- команды работы со стеком;

- команды работы с флагами;

- команды передачи управления;

- команды загрузки и пересылки данных;

- команды работы с портами и вызова прерывания.

Часть команд (например, арифметические операции, операции сравнения и т.д.) при выполнении воздействуют на те или иные разряды регистра флагов. Ход выполнения других команд (например, команд передачи управления или пересылки) может зависеть от состояния тех или иных разрядов регистра флагов.

В приложении B содержится перечень команд с указанием возможных комбинаций операндов и с флагами, которые могут изменяться командами.

Структура программы

Существует два основных типа загрузочных программ: EXE и COM. Система предъявляет различные требования к структуре этих типов программ и их инициализации.


Поделиться с друзьями:

Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...

Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...

Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...

Типы оградительных сооружений в морском порту: По расположению оградительных сооружений в плане различают волноломы, обе оконечности...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.04 с.