3.4 Режимы адресации
Формат команды микропроцессора
Инструкция микропроцессора может содержать следующие поля:
префикс | КОП | Mod R/M | SIB | смещение | непосредственный операнд |
0/1 байт | 1/2 байта | 0/1 байт | 0/1 байт | 0/1/2/4 байта | 0/1/2/4 байта |
Префикс - необязательная часть инструкции, позволяет изменить некоторые особенности ее выполнения. В команде может быть использовано сразу несколько префиксов разного типа. Типы префиксов:
- командные префиксы (префиксы повторения) REP, REPE/REPZ, REPNE/REPNZ;
- префикс блокировки шины LOCK;
- префиксы размера (см. далее);
- префиксы замены сегмента.
КОП - код операции.
Байт "Mod R/M" определяет режим адресации, а также иногда дополнительный код операции. Необходимость байта "Mod R/M" зависит от типа инструкции.
Байт SIB (Scale-Index-Base) определяет способ адресации при обращении к памяти в 32-битном режиме. Необходимость байта SIB зависит от режима адресации, задаваемого полем "Mod R/M".
Кроме того, инструкция может содержать непосредственный операнд и/или смещение операнда в сегменте данных.
На размер инструкции накладывается ограничение в 15 байт. Инструкция большего размера может получиться при некорректном использовании большого количества префиксов. Микропроцессоры IA-32 в таком случае генерируют исключение #13.
Режимы адресации операндов
Если инструкция микропроцессора требует операнды, то они могут задаваться следующими способами:
- непосредственно в коде инструкции (только операнд-источник);
- в одном из регистров;
- через порт ввода-вывода;
- в памяти.
Для совместимости с 16-битными процессорами архитектура IA-32 использует одинаковые коды для инструкций, оперирующих как с 16-битными, так и 32-битными операндами. Новая архитектура предусматривает также новые возможности при указании адреса для операнда в памяти. Как процессор будет считать операнд или его адрес, зависит от эффективного размера операнда и эффективного размера адреса для данной команды. Эти значения определяются на основе режима работы, бита D дескриптора используемого сегмента и наличия в инструкции определенных префиксов.
RM, V86, SMM | ||||||||
бит D сегмента (PM) | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|---|
OpSize | нет | нет | есть | есть | нет | нет | есть | есть |
AddrSize | нет | есть | нет | есть | нет | есть | нет | есть |
Эфф. размер оп. | 16 | 16 | 32 | 32 | 32 | 32 | 16 | 16 |
Эфф. размер адр. | 16 | 32 | 16 | 32 | 32 | 16 | 32 | 16 |
OpSize - префикс смены размера операнда (код 66h), AddrSize - префикс смены размера адреса (код 67h)
Непосредственный режим адресации подразумевает включение операнда-источника в код инструкции. Операнд может быть 8-битным или 16-битным, если значение эффективного размера операнда - 16. Операнд может быть 8-битным или 32-битным, если значение эффективного размера операнда - 32. Обычно непосредственные операнды используются в арифметических инструкциях.
Регистровый режим адресации определят операнд-источник или операнд-приемник в одном из следующих регистров:
- регистры общего назначения (EAX/AX, EBX/BX, ECX/CX, EDX/DX, ESI/SI, ESP/SP, EBP/BP - 16-битный регистр, если эффективный размер операнда - 16, или 32-битный регистр в противном случае) или их младшие байты (AH, AL, BH, BL, CH, CL, DH, DL);
- сегментные регистры (CS, DS, SS, ES, FS, GS);
- регистр флагов (EFLAGS для 32-битных операндов или FLAGS для 16-битных);
- управляющие регистры (CR0/MSW, CR2, CR3, CR4) и регистры системных таблиц (GDTR, LDTR, IDTR, TR);
- регистры отладки (DR0-DR7);
- машинно-зависимые регистры (MSRs);
- регистры сопроцессора, MMX и XMM.
В некоторых случаях (например, в инструкциях DIV и MUL) могут использоваться пары 32-битных (или 16-битных) регистров (например, EDX:EAX), образуя 64-битный (32-битный) операнд.
Адресация через порт ввода-вывода подразумевает получение операнда или сохранение операнда через пространство портов ввода-вывода. Адрес порта ввода-вывода либо непосредственно включается в код инструкции, либо берется из регистра DX.
Очень распространенный способ адресации операнда - адресация через память. Таким образом может быть указан операнд-источник или операнд-приемник. Следует отметить, что процессор не позволяет одновременно задавать оба операнда через память (за исключением некоторых цепочечных команд).
Для получения операнда из памяти процессору необходимо знать селектор сегмента и смещение в сегменте. В некоторых командах селектор может быть указан непосредственно в коде инструкции. В других случаях процессор может явно или неявно использовать значение одного из сегментных регистров. Под неявным использованием сегментных регистров подразумевается то, что в зависимости от предназначения операнда процессор использует определенный сегментный регистр для обращения к памяти: CS - для выборки инструкций; SS - для работы со стеком или обращения к памяти через регистры ESP или EBP; ES - для получения адреса операнда-приемника в цепочечных командах; DS - при всех остальных обращениях к памяти. Явное использование сегментных регистров возможно, если в код инструкции включается префикс смены сегмента. Указание префикса смены сегмента допустимо не для всех команд: нельзя менять сегмент для команд работы со стеком (всегда используется SS), для цепочечных команд можно менять сегмент только операнда-источника (операнд-приемник всегда адресуется через ES).
Смещение в сегменте (эффективный или исполнительный адрес - EA) может быть вычислено на основе значений регистров общего назначения и/или указанного в коде инструкции относительного смещения, при этом любой или даже несколько из указанных компонентов могут отсутствовать:
Такая схема позволяет в языках высокого уровня и на языке ассемблера легко реализовать работу с массивами. В зависимости от значения размера адреса для команды на способы задания этих компонентов накладываются определенные ограничения:
Эфф. размер адреса | 32 | 16 |
---|---|---|
Base (база массива) |
EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI | BX, BP |
Index (индекс в массиве) |
EAX, EBX, ECX, EDX, EBP, ESI, EDI | SI, DI |
Scale (масштабный коэффициент) |
1, 2, 4 или 8 (включается в код инструкции) | не используется (всегда 1) |
Displacement (относительное смещение) |
8- или 32-битное число непосредственно в коде инструкции |
8- или 16-битное число непосредственно в коде инструкции |
Таким образом, различные способы вычисления эффективного адреса формируют еще несколько режимов адресации:
- EA=DISPLACEMENT (например, INC byte ptr [500h]);
- EA=BASE (например, MOV AL,[BX] для операнда-источника);
- EA=BASE+DISPLACEMENT (например, ADD AL,[ECX+1234h] для операнда-источника);
- EA=BASE+(INDEX*SCALE) (например, SUB EAX,[EBX+ECX*2] для операнда-источника);
- EA=INDEX*SCALE+DISPLACEMENT (например, MOV [EAX*4+TableOffset],BL для операнда-приемника);
- EA=BASE+(INDEX*SCALE)+DISPLACEMENT (например, DEC dword ptr [EAX+ECX*2+200h]) и др.