Лекции по курсу "Проектирование ассемблеров, компоновщиков, макропроцессоров
7. Операнды
Операнды — это объекты, над которыми или при помощи которых выполняются действия, задаваемые инструкциями или директивами. Машинные команды могут либо совсем не иметь операндов, либо иметь один или два операнда. Большинство команд требует двух операндов, один из которых является источником, а другой — приемником (операндом назначения). В двухоперандной машинной команде возможны следующие сочетания операндов:
- регистр — регистр;
- регистр — память;
- память — регистр;
- непосредственный операнд — регистр;
- непосредственный операнд — память.
Здесь важно подчеркнуть, что один операнд может располагаться в регистре или памяти, а второй операнд обязательно должен находиться в регистре или непосредственно в команде. Непосредственный операнд может быть только источником.
Для приведенных ранее правил сочетания типов операндов есть исключения, которые касаются:
- команд работы со стеком, которые могут переносить данные из памяти в стек, также находящийся в памяти;
- команд типа умножения, которые, кроме операнда, указанного в команде, неявно используют еще и второй операнд.
Операндами могут быть числа, регистры, ячейки памяти, символьные идентификаторы. При необходимости для расчета некоторого значения или определения ячейки памяти, на которую будет воздействовать данная команда или директива, используются выражения, то есть комбинации чисел, регистров, ячеек памяти, идентификаторов с арифметическими, логическими, побитовыми и атрибутивными операторами.
Рассмотрим классификацию операндов, поддерживаемых транслятором ассемблера.
- Операнд задается неявно на микропрограммном уровне. В этом случае команда явно не содержит операндов. Алгоритм выполнения команды использует некоторые объекты по умолчанию (регистры, флаги в FLAGS и т. д.). Например, команда XLAT неявно обращается к регистру AL и строке в памяти по адресу, определяемому парой регистров DS:BX.
- Операнд задается в самой команде (непосредственный операнд). Это может быть число, строка, имя или выражение, имеющее некоторое фиксированное (константное) значение. Физически непосредственный операнд находится в коде команды, то есть является ее частью. Для его хранения в команде выделяется поле длиной до 32 битов. Непосредственный операнд может быть только вторым операндом (источником). Операнд-приемник может находиться либо в памяти, либо в регистре. Например, команда mov ax,0ffffh пересылает в регистр АХ шестнадцатеричную константу 0ffffh. Команда add sum,2 складывает содержимое поля по адресу sum с целым числом 2 и записывает результат по месту первого операнда, то есть в память. Если непосредственный операнд — имя, то оно не должно быть перемещаемым, то есть зависеть от адреса загрузки программы в память. Такое имя можно определить оператором EQU или "=". Например:
num equ 5 ;вместо num ассемблер
;везде подставляет 5
imd = num-2 ;вместо num ассемблер
;везде подставляет 3
mov al,num ;эквивалентно mov al,5,
;здесь 5 - непосредственный операнд
add [si],imd ;сложение [si]:= [si]+3,
;здесь imd - непосредственный операнд
mov ax,0000h
mov ds,ax
mov ax,ds:0000h ;записать слово в ах из области
;памяти по физическому
;адресу 0000:0000
data segment
mas_w dw 25 dup (0)
...
code segment
...
lea si,mas_w ; mas_w - перемещаемый операнд
...
В этом фрагменте mas_w — символьное имя, значением которого является адрес первого байта области памяти размером 25 слов. Полный физический адрес этой области памяти будет известен только после загрузки программы в память для выполнения.
jmp $+3 ; безусловный переход на команду mov
cld ; длина команды cld составляет 1 байт
mov al,1
При формировании выражения для перехода, подобного $+3, нужно помнить о длине самой команды, в которой это выражение используется, так как значение счетчика адреса соответствует смещению в сегменте команд данной, а не следующей за ней команды. В нашем примере команда JMP занимает два байта. Нужно быть осторожным, длина этой и других команд зависит от того, какие в ней используются операнды. Команда с регистровыми операндами будет короче команды, один из операндов которой расположен в памяти. В большинстве случаев эту информацию можно получить, зная формат машинной команды и анализируя колонку файла листинга с объектным кодом команды.
- 16-разрядные регистры АХ, ВХ, СХ, DX, SI, DI, SP, ВР;
- 8-разрядные регистры АН, AL, BH, BL, CH, CL, DH, DL;
- сегментные регистры CS, DS, SS, ES.
Регистры, адресуемые с помощью порта ввода-вывода, могут иметь разрядность 8 или 16 бит, но для конкретного порта разрядность регистра фиксирована. Команды IN и OUT работают с фиксированной номенклатурой объектов. В качестве источника информации или получателя применяются так называемые регистры-аккумуляторы АХ, AL. Выбор регистра определяется разрядностью порта. Номер порта может задаваться непосредственным операндом в командах IN и OUT или значением в регистре DX. Последний способ позволяет динамически определить номер порта в программе. Например,
in al,60h ; ввести байт из порта 60h
mov dx,20h ;записать номер порта 20h в регистр dx
mov al,20h ;записать значение 20h в регистр al
out dx,al ;вывести значение 20h в порт 20H
Причины использования языка ассемблер
Причины неиспользования языка ассемблер
Синтаксис ассемблера
Системное программное обеспечение и структура ЭВМ
Программная модель процессора Intel 8086
Организация работы памяти
Операнды
Адресация операндов
Формат машинных команд
Команды переходов
Типы ассемблеров. Функции ассемблера
Ассемблер по схеме 1А / ОП
Ассемблер по схеме 1А / МД
Двухпросмотровый ассемблер
Многопросмотровый ассемблер
Загрузчик
Структура объектных файлов. Основные понятия
Идентификация модуля и атрибуты
Концепция привязки
Объектный файл. Последовательность записей
Объектный файл. Формат записей
Формат записей THEADR и LHEADR
Формат записи LNAMES
Формат записи SEGDEF
Формат записи GRPDEF
Формат записи PUBDEF
Формат записи COMDEF
Формат записи LOCSYM
Формат записи EXTDEF
Формат записи LINNUM
Формат записи LEDATA
Формат записи LIDATA
Формат записи FIXUPP
Формат записи MODEND
Формат записи комментариев