Система команд базового МП условно разделена на несколько групп:
1. Команды пересылок
2. Арифметические команды
3. Логические команды
4. Команды сдвигов
5. Команды переходов
6. Строковые команды
7. Команды управления МП.
1. Команды пересылок.
MOV - осуществляет пересылку данных.
MOV AX, BX
MOV AL, 8
MOV AL, [BX]
LEA - пересылает адрес в какой-либо регистр.
LEA регистр, имя переменной
LEA BX, MASS; переписать в BX адрес переменной MASS
PUSH - переслать содержимое какого-либо регистра в стек.
PUSH регистр
PUSH AX
POP - извлечь из стека содержимое и записать в регистр.
POP регистр
POP BX
PUSH AX аналогично MOV BX, AX
POP BX
PUSH AX извлекать в POP СX
PUSH ВX обратном порядке: POP BX
PUSH СX POP АX
XCHG (exchange) - обменять содержимое регистров.
Синтаксис согласно методам адресации.
XCHG AX, BX
XCHG AL, [BX]
2. Арифметические команды
ADD - сложить содержимое двух операндов и результат оставить в приемнике.
Синтаксис согласно методам адресации.
ADD AX, BX
AX + BX → AX
ADD AX, OFH
ADD AL, [BX]
ADD AL, VAR1
SUB - вычитаются операнд из другого операнда.
|
|
Результат в приемнике.
Синтаксис согласно методам адресации.
SUB AX, BX
AX - BX → AX
MUL - умножение двух операндов.
Один из них - предполагается в аккумуляторе.
Результат в аккумуляторе.
MUL BX (AX * BX → AX)
DIV - разделить один операнд на другой, один из них в аккумуляторе, второй - согласно методам адресации.
Если делятся байтовые числа, то целая часть записывается в AL, а остаток в AH. Если двухбайтовые, то целая часть - AX, остаток в DX.
DIV BX (AX/BX → AX или см. выше)
INC - прибавить единицу к операнду.
INC BX
(BX + 1 → BX)
INC VAR (VAR - ячейка)
(VAR + 1 → VAR)
DEC - вычесть единицу из операнда.
DEC BX
(BX - 1 → BX)
DEC VAR1
(VAR1 - 1 → VAR1)
3. Логические команды
AND - команда логического “и” над двумя операндами.
AND AL, BL результат в AL
AL → 01101110
BL → 01110111
результат: 01100110 → AL
AND AL, [BX]
OR - логическое «или» над двумя операндами.
Синтаксис по методам адресации.
AL → 01101110
BL → 01110111
результат: 01111111 → AL
XOR - исключающее «или» (сложение по mod2).
Синтаксис по методам адресации.
AL → 01101110 одинаковые биты: 0
BL → 01110111 разные биты: 1
результат: 00011001 → AL
XOR AL, AL → даст 0.
(для обнуления регистра)
XOR AL, AL → быстрее, чем MOV AL, 0
TEST - логическое «и» над двумя операндами.
TEST AL, MASK
TEST AL, 10; AL – проверяемое значение, 10 – маска.
Отличается от AND тем, что результат не будет записан в первый операнд. Результатом команды является установка значения флага нуля ZF:
Если в результате логического умножения получился ненулевой результат, т.е. хотя бы один единичный бит маски совпал с соответствующим единичным битом первого операнда, то ZF = 0;
Если в результате логического умножения получился нулевой результат, т.е. ни один единичный бит маски не совпал с соответствующим единичным битом первого операнда, то ZF = 1.
|
|
CMP - сравнить два операнда.
CMP AL, [BX]
CMP AL, BL
CMP AL, 07
Результат сравнения во флагах.
CMP AL, BL
AL - приемник; BL - источник.
Если AL < BL → выставляется флаг с = 1
AL < BL → с = 1 и z = 0
AL > BL → с = 0 и z = 0
AL = BL → z = 1 (выст. флаг zero)
c - будет тем же, каким остав.
4. Команды сдвигов.
Используется для проверки содержимого того или иного бита в регистре (0 или 1).
Делятся на логический сдвиг и арифметический сдвиг.
Арифметический сдвиг:
ROL (Rotate on Left) - циклический сдвиг влево содержимого регистра.
ROR - вправо.
ROL регистр, 1; на один бит сдвигается
ROL регистр, CX (СL); на количество битов, записывается в CX предварительно.
RCL - циклический сдвиг влево с использованием флага carry.
RCR - циклический сдвиг вправо с использованием флага carry.
|
SHR - логический сдвиг вправо.
SHL - логический сдвиг влево.
5. Команды переходов.
Синтаксис команды безусловного перехода без сохранения информации о точке возврата:
JMP [модификатор] адрес_перехода
Модификаторы:
§ NEAR PTR – прямой переход на метку внутри текущего сегмента кода, при этом модифицируется только регистр IP на основе указанного в команде адреса или выражения, использующего символ извлечения значения счетчика адреса команд ($);
§ FAR PTR – прямой переход на метку в другом сегменте кода, при этом адрес перехода задается в виде непосредственного операнда или адреса и состоит из 16-разрядного селектора и 16-разрядного смещения, которые загружаются, соответственно в регистры CS и IP;
§ WORD PTR – косвенный переход на метку внутри текущего сегмента кода, при этом модифицируется только регистр IP значением смещения размером 16 бит из памяти по указанному в команде адресу или из регистра;
§ DWORD PTR – косвенный переход на метку в другом сегменте кода, при этом модифицируются оба регистра, CS и IP значением из памяти (из регистра нельзя). При этом первое слово адреса перехода, представляющее собой смещение загружается в IP, второе слово – в CS.
Пр.: JMP m1; прямой переход
JMP FAR PTR m1; прямой переход на метку m1 в другом сегменте
LEA BX, m1
JMP BX; косвенный переход
Команда CALL осуществляет вызов процедуры (подпрограммы). Синтаксис команды:
CALL [модификатор] имя_процедуры.
Подобно команде JMP команда CALL передает управление по адресу с символическим именем, но при этом в стеке сохраняется адрес возврата (то есть адрес команды, следующей после команды CALL).
Команда RET считывает адрес возврата из стека и загружает его в регистры CS и IP, тем самым возвращая управление на команду, следующую в программе за командой CALL. Синтаксис команды:
RET [число]
Необязательный параметр [число] обозначает количество элементов, удаляемых из стека при возврате из процедуры.
Команды условного перехода имеют одинаковый синтаксис:
JCC метка_перехода
Как видно, мнемокод всех команд начинается с символа «J» – от слова jump (прыжок). Вместо символов «CC» указывается конкретное условие, анализируемое командой.
Значение аббревиатур в названии команды JCC:
Мнемоническое обозначение | Оригинальный термин | Перевод | Тип операндов |
E | Equal | Равно | Любые |
N | Not | Не | Любые |
G | Greater | Больше | Числа со знаком |
L | Less | Меньше | Числа со знаком |
A | Above | Выше (больше) | Числа без знака |
B | Below | Ниже (меньше) | Числа без знака |
Флаги, устанавливаемые командой CMP, можно анализировать специальными командами условного перехода. Перечень команд условного перехода для команды CMP:
Типы операндов | Мнемокод команды условного перехода | Критерий условного перехода | Значения флагов для перехода |
Любые | JE | операнд1 = операнд2 | ZF = 1 |
Любые | JNE | операнд1!= операнд2 | ZF = 0 |
Со знаком | JL/JNGE | операнд1 < операнд2 | SF!= OF |
Со знаком | JLE/JNG | операнд1 <= операнд2 | SF!= OF или ZF = 1 |
Со знаком | JG/JNLE | операнд1 > операнд2 | SF = OF и ZF = 0 |
Со знаком | JGE/JNL | операнд1 >= операнд2 | SF = OF |
Без знака | JB/JNAE | операнд1 < операнд2 | CF = 1 |
Без знака | JBE/JNA | операнд1 <= операнд2 | CF = 1 или ZF = 1 |
Без знака | JA/JNBE | операнд1 > операнд2 | CF = 0 и ZF = 0 |
Без знака | JAE/JNB | операнд1 >= операнд2 | CF = 0 |
|
|
Мнемоническое обозначение некоторых команд условного перехода отражает название флага, с которым они работают, и имеет следующую структуру: первым идет символ «J», вторым – либо обозначение флага, либо символ отрицания «N», после которого стоит название флага. Такая структура команды отражает ее назначение. Если символа «N» нет, то проверяется состояние флага на равенство 0 и в случае успеха производится переход на метку перехода. Эти команды можно использовать после любых команд, изменяющих указанные флаги.
Команды условного перехода и флаги
Название флага | Номер бита в регистре FLAGS | Команда условного перехода | Значение флага для осуществления перехода |
Переноса CF | JC | CF = 1 | |
Четности PF | JP | PF = 1 | |
Нуля ZF | JZ | ZF = 1 | |
Знака SF | JS | SF = 1 | |
Переполнения OF | JO | OF = 1 | |
Переноса CF | JNC | CF = 0 | |
Четности PF | JNP | PF = 0 | |
Нуля ZF | JNZ | ZF = 0 | |
Знака SF | JNS | SF = 0 | |
Переполнения OF | JNO | OF = 0 |
JCXZ – переход, если CX = 0
LOOP метка_перехода – команда перехода с автоматическим уменьшением счетчика цикла. Команда реализует следующие действия:
- Декремент регистра CX;
- Сравнение регистра CX с нулем:
- если CX > 0, то управление передается на метку перехода;
- если CX = 0, то управление передается на следующую после LOOP команду
LOOPE/LOOPZ – повторить цикл пока CX!= 0 или ZF = 0
LOOPNE/LOOPNZ – повторить цикл пока CX!= 0 или ZF = 1
СИНТАКСИС АССЕМБЛЕРА
Программа на ассемблере представляет собой совокупность блоков памяти, называемых сегментами. Программа может состоять из одного или нескольких таких блоков-сегментов. Сегменты программы имеют определенное назначение. Каждый сегмент состоит из совокупности отдельных строк, называемых предложениями языка. Для языка ассемблера предложения, составляющие программу, могут представлять собой синтаксические конструкции четырех типов.
|
|
Команды представляют собой символические аналогии машинных команд. В процессе трансляции инструкции ассемблера преобразуются в соответствующие команды системы команд процессора.
Макрокоманды - это оформляемые определенным образом предложения текста программы, замещаемые во время трансляции другими предложениями.
Директивы являются указанием транслятору ассемблера на выполнение некоторых действий. У директив нет аналогов в машинном представлении.
Комментарии содержат любые символы, в том числе и буквы русского алфавита.
СЕГМЕНТЫ
В общем случае в любой программе на ассемблере имеется три главных сегмента:
1. Сегмент кодов. Сегмент кодов содержит машинные команды, которые будут выполняться. Обычно первая выполняемая команда находится в начале этого сегмента и операционная система передает управление по адресу данного сегмента для выполнения программы. Регистр сегмента кодов (CS) адресует данный сегмент.
2. Сегмент данных. Сегмент данных содержит определенные данные, константы и рабочие области, необходимые программе. Регистр сегмента данных (DS) адресует данный сегмент.
3. Сегмент стека. Стек содержит адреса возврата как для программы для возврата в операционную систему, так и для вызовов подпрограмм для возврата в главную программу. Регистр сегмента стека (SS) адресует данный сегмент.
Директива SEGMENT
Любые ассемблерные программы содержат по крайней мере один сегмент - сегмент кода. В некоторых программах используется сегмент для стековой памяти и сегмент данных для определения данных. Ассемблерная директива для описания сегмента SEGMENT имеет следующий формат:
Имя Директива Операнд
имя SEGMENT [параметры]
.
.
имя ENDS
Имя сегмента должно обязательно присутствовать и быть уникальным. Директива ENDS обозначает конец сегмента. Обе директивы SEGMENT и ENDS должны иметь одинаковые имена. Директива SEGMENT может содержать три типа параметров, определяющих выравнивание, объединение и класс.
1. Выравнивание. Данный параметр определяет границу начала сегмента. Обычным значением является PARA, по которому сегмент устанавливается на границу параграфа. В случае отсутствия этого операнда ассемблер принимает по умолчанию PARA.
2. Объединение. Этот элемент определяет объединяется ли данный сегмент с другими сегментами в процессе компоновки после ассемблирования. Возможны следующие типы объединений:
PRIVATE - сегмент не будет объединяться с другими сегментами с тем же именем вне данного модуля;
PUBLIC - заставляет компоновщик объединить все сегменты с одинаковым именем.
COMMON - располагает все сегменты с одним и тем же именем по одному адресу
STACK - определение сегмента стека.
Сегмент стека определяется следующим образом:
имя SEGMENT PARA STACK
3. Класс. Данный элемент, заключенный в апострофы, используется для группирования относительных сегментов при компоновке:
имя SEGMENT PARA STACK 'Stack'
Директива ASSUME
Процессор использует регистр SS для адресации стека, регистр DS для адресации сегмента данных и регистр CS для адресации сегмента кода. Ассемблеру необходимо сообщить назначение каждого сегмента. Для этой цели служит директива ASSUME, кодируемая в сегменте кода следующим образом:
Директива Операнд
ASSUME SS:имя_стека,DS:имя_сегмента_данных,CS:имя_сегмента_кода
Например, SS:имя_стека указывает, что ассемблер должен ассоциировать имя сегмента стека с регистром SS. Операнды могут записываться в любой последовательности.
Как уже показано, директива ENDS завершает сегмент. Директива END в свою очередь полностью завершает всю программу: