КОСВЕННАЯ АДРЕСАЦИЯ
ДВУХОПЕРАНДНЫЕ КОМАНДЫ
7 0 7 6 5 3 2 0
┌────────────┬───┬───┐ ┌─────┼─────┼─────┐ ┌ ─ ─ ┐ ┌ ─ ─ ┐
│ КОП │ d │ w │ │ mod │ reg │ r/m │ displ disph
└────────────┴─┬─┴─┬─┘ └──┬──┴───┬─┴─┬───┘ └ ─ ─ ┘ └ ─ ─ ┘
бит направления │ │ режим │ │ │ смещение адреса
────────────────┘ │ ──────┘ │ │
бит слова │ поле определения │ │ поле определения
───────────┘ второго операнда │ │ первого операнда
─────────────────┘ └───────────────────
┌──────────────┐ d=0, условное направление ┌───────────────┐
│ │ из МП 1 │ │
│ 2-й ├───────────────────────────>│ 1-й │
│ операнд reg │ │ операнд r/m │
│ │ d=1, условное направление │ │
│ │ в МП │ │
│ │<───────────────────────────┤ │
└──────────────┘ 2 └───────────────┘
W=1, если операнд слово
W=0, если байт
d=1, - передача результата в МП
d=0, - передача результата из МП
Пример:
ADD AX,B AX:=AX+B -> результат в МП - d=1
ADD B,BX B:=B+BX -> результат в память - d=0
ADD AX,BX AX:=AX+BX -> результат в МП - d=1
Условное обозначение ОР1 и ОР2 не согласуются с мнемоникой:
Мнемоника: КОП ОР1 , ОР2
/ \
может быть 1-й или 2-й операнд
Таблица. Определение первого операнда в постбайте.
┌─────┬────────────────────────────────────────────────────────┐
│ r/m │ mod │
│ ├───────────┬──────────────┬───────────────┬─────────────┤
│ │ 00 │ 01 │ 10 │ 11 │
│ │ │ │ ├───────┬─────┤
│ │ │ │ │ w=0 │ w=1 │
├─────┼───────────┼──────────────┼───────────────┼───────┼─────┤
│ 000 │ (BX)+(SI) │ (BX)+(SI)+D8 │ (BX)+(SI)+D16 │ AL │ AX │
│ 001 │ (BX)+(DI) │ (BX)+(DI)+D8 │ (BX)+(DI)+D16 │ CL │ CX │
│ 010 │ (BP)+(SI) │ (BP)+(SI)+D8 │ (BP)+(SI)+D16 │ DL │ DX │
│ 011 │ (BP)+(DI) │ (BP)+(DI)+D8 │ (BP)+(DI)+D16 │ BL │ BX │
│ 100 │ (SI) │ (SI)+D8 │ (SI)+D16 │ AH │ SP │
│ 101 │ (DI) │ (DI)+D8 │ (DI)+D16 │ CH │ BP │
│ 110 │ (D16) * │ (BP)+D8 │ (BP)+D16 │ DH │ SI │
│ 111 │ (BX) │ (BX)+D8 │ (BX)+D16 │ BH │ DI │
└─────┴───────────┴──────────────┴───────────────┴───────┴─────┘
* исключение - прямая адресация.
Если MOD=11 то адресация регистровая.
Каждому регистру можно присвоить свой номер. Второй операнд задается полем REG, т. е. это всегда номер регистра. Значение этого поля определяется последними 2-мя колонками.
Если MOD<>11, то первый операнд находится в памяти.
Каждый квадрат таблицы определяет способ вычисления исполнительного адреса, например, ЕА=(BX)+(DI)+d16 -> r/m=001, mod=10
ЕА – исполнительный адрес, беззнаковая величина.
D8 или D16 это знаковое смещение адреса, которое содержится в команде и как компонент участвует в вычислении исполнительного адреса EA. Например
EA = (BP) + (DI) + D16
Компоненты адреса – BX,DI,d16 – знаковые величины, однако после их сложения с ЕА получается беззнаковая величина, иначе – ошибка.
С другой стороны, EA является смещением относительно начала сегмента.
Колонки MOD = 00,01,10 имеют регулярную структуру. Нарушение только в одном квадрате:
r/m = 110
MOD = 00, что соответствует прямой адресации.
Код команды MOV X,BP
d w mod reg r/m
┌───────┬───┬───┐ ┌───┬───┬───┐┌─────────┐ - прямой исполнительный
│ KOП │ 0 │ 1 │ │ 00│101│110││ disp │ адрес переменной Х
└───────┴───┴───┘ └───┴───┴───┘└─────────┘
ЕА = disp
MOD = 00 – косвенная адресация
r/m = 100,101,111
EA = (BX) MOV AX,[BX]
EA = (SI) ADD AL,[SI]
EA = (DI) SUB [DI],BP
При косвенной регистровой адресации выполняется обращение к одному из регистров (BX,SI,DI) откуда извлекается прямой адрес операнда в памяти.
Команды, использующие косвенную адресацию, всегда адресуются по DS
Физический адрес = DS + EA -> адрес в сегменте данных.
Косвенная адресация через BP не реализована т.к. имеется [d16] (прямая адресация), однако косвенная адресация через BP моделируется через:
EA = (BP) + d8
MOV [BP],AX
MOV BX,[BP]
Адресация выполняется по умолчанию через регистр SS, физический адрес равен = SS + EA, т. е. выполняется обращение к сегменту стека.
┌─< MOV [BP],AX
│ d w mod reg r/m dispL
┌───────┬───┬───┐ ┌───┬───┬───┐┌─────────┐
│ KOП │ 0 │ 1 │ │ 01│000│110││ 00 │ -> смещение = 0
└───────┴───┴───┘ └───┴───┴───┘└─────────┘
└─> MOV [BP+0],AX