Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Архитектура вычислительных систем и Ассемблер с приложением методических указаний к лабораторным работам. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
3.6. Структура команды и методы адресации 131
3.6. Структура команды и методы адресации
Тот ли идёт прямо по дороге, кто ходит потупив лице своё? Или тот на прямом пути, кто ходит, держа себя прямо?
Коран. 67.22
Набор команд процессоров семейства x86 имеет тип CISC. Он создавался в условиях жёсткой экономии памяти, так что команды имеют максимально ком­пактную (и, соответственно, сложную для декодирования и понимания) структуру и используют разнообразные методы адресации операндов.
Необходимость программирования в машинных кодах возникает крайне редко, но знание формата команды помогает лучше представлять себе возможности и ограничения архитектуры.
3.6.1. Методы адресации
Я, конечно, не в курсе, но знаю одно мурло, которое знает одно чучело, которое знает одного обормота, который может что-то знать...
А. В. Жвалевский, И. Е. Мытько.
Здесь вам не причинят никакого вреда
Адрес операнда в машинной команде может быть задан одним из следующих способов [54]. Они называются методами адресации операндов.
1. Неявная
кодом операции.
2. Непосредственная
непосредственно в команду.
3. Прямая абсолютная
по фиксированному адресу (глобальная или статическая). Этот адрес включа-
ется непосредственно в команду.
4. Прямая относительная
прибавляется к значению указателя команд ip.
Этот режим используется в командах передачи управления и позволяет за-
гружать код в память по произвольному адресу без нарушения корректности
переходов.
Шестидесятичетырёхбитное расширение позволяет использовать прямую отно-
сительную адресацию также и для данных.
5. Регистровая
В команду включается номер этого регистра.
6. Косвенно-регистровая
мяти и её адрес находится в регистре (регистрах) общего назначения.
адресация. Местоположение операнда фиксировано и определяется
адресация. Операнд — константа, которая включается
(прямая) адресация. Операнд — переменная в памяти
адресация. В команде содержится смещение, которое
адресация. Операнд находится в регистре общего назначения.
(косвенная) адресация. Операнд — переменная в па-
132 Глава 3. Архитектура команд семейства x86
Иногда выделяют следующие виды косвенной адресации:
базовая адресация — адрес операнда в регистре (базовом регистре, базе);
– –
базовая адресация со смещением — адрес операнда вычисляется как сум­ма базового регистра и константы (смещения); базово-индексная адресация — адрес операнда вычисляется как сумма
двух регистров — базового регистра и индексного; базово-индексная адресация со смещением — адрес операнда вычисляет-
ся как сумма двух регистров и константы. Если необходимо обработать значение, адрес которого получается более сложным образом (в частности, переменная в памяти, указатель на которую также находится в памяти), этот адрес надо вычислить отдельно и поместить в регистр.
3.6.2. Структура команды
Наше знание — сила и оружие.
В. В. Маяковский. Владимир Ильич Ленин
Команды процессоров семейства x86 имеют переменную длину. Структура
команды показана на рис. 3.12.
Префиксы
Произвольное
количество (от 0)
по 1 байту
Код операции:
1, 2 или 3 байта
Mod
76
Опкод
Reg/
продолжение
опкода
53
ModR/M
Адресация операндов:
0 или 1 байт
R/M
20
операнд в памяти:
SIB
Указатель на
0 или 1 байт
Scale
76
Displacement
Смещение
операнда в памяти:
0, 1, 2 или 4 байта
Index
53
20
Immediate
Непосредственный
операнд:
0, 1, 2 или 4 байта
Base
Рис. 3.12. Структура команды в архитектуре x86
Все поля, кроме кода операции, необязательны [17, 37].
Команда может предваряться одним или несколькими префиксами, изменя­ющими её поведение. Из префиксов x86 следует отметить префикс изменения размера операнда
и префикс изменения размера адреса
0x67
. Для трид-
0x66
цатидвухбитного режима (и его шестидесятичетырёхбитного расширения) они уменьшают разрядность операнда или адреса соответственно до 16 бит, для шест­надцатибитного — повышают до 32. Восьмибитные варианты команд, как правило, представлены отдельными опкодами.
Далее идёт код операции (опкод), занимающий один, два или три байта (и, может быть, ещё три бита в байте
Mod R/M
). Следующий байт,
Mod R/M
согласно [17], задаёт адресацию операндов. За ним следует необязательный байт
SIB
, уточняющий расположение операнда в памяти, если такой есть и для него
,
3.6. Структура команды и методы адресации 133
используется косвенная базово-индексная адресация. Каждый из байтов
ModR/M
и SIB состоит из трёх полей.
Поле
Displacement
содержит смещение адреса при косвенной адресации. Оно трактуется как знаковое тридцатидвухбитное (при использовании понижающе­го разрядность адреса префикса 0x67 — шестнадцатибитное) или восьмибитное число.
Поле
Immediate
— непосредственное значение («магическое число», вклю­чённое непосредственно в команду). Оно присутствует, если опкод соответствует операции с непосредственным операндом.
3.6.3. Общие для тридцатидвухбитного и шестидесятичетырёхбитного
режимов сведения об адресации
Это не костыль — это уже экзоскелет.
Программистский фольклор
Адресация в системе команд x86 частично задаётся опкодом. Это относится не только к неявной адресации (что логично), но и к непосредственной. Более того, для самых компактных команд номер операнда-регистра также может быть указан
mov
внутри опкода. Так, тот вариант команды ное значение в регистр, состоит из однобайтового опкода и поля
, который записывает непосредствен-
Immediate
; при этом собственно код операции занимает пять старших бит опкода, а последние три бита задают регистр-приёмник.
При этом, если опкодом задаётся использование только одного операнда или
двух операндов, один из которых непосредственный, а второй адресуется полем
R/M
, то в освободившееся поле часть опкода. В частности, однобайтовый опкод (в зависимости от значений
ModиR/M
соответствует, в зависимости от поля командам:
inc,dec,callиpush
Reg
байта
Mod R/M
FF
, требующий поля
также возможны
Reg
, четырём различным однооперандным
может быть записана
ModR/M
SIBиDisplacement
. Таким образом, полный код операции в этом
случае занимает не восемь, а одиннадцать бит и записывается в двух полях.
Кроме непосредственного, команда может иметь два операнда, расположение
которых задаётся байтом
Mod R/M
и при необходимости уточняется байтом
SIB и полем Displacement.
Поле
Reg
байта
ModR/M
содержит трёхбитовый номер операнда-регистра. Является ли он источником или приёмником, определяет специальный бит опко­да — поле направления.
Поле
R/M
в зависимости от поля
Mod
может как содержать номер второго операнда-регистра, так и определять адрес операнда в памяти. При необходимо­сти совместно с полями
R/MиMod
используются также
SIBиDisplacement
(таблица 3.3).
)
134 Глава 3. Архитектура команд семейства x86
Адресация операнда при помощи полей Modи R/M
Таблица 3.3
Dis
Mod
place
ment
11
01 Disp8
10 Disp32
00
Disp32
R/M
Reg2
Base = 100
100
100
Base = 100
100
100
Base /
{100, 101}
100
100
100
101
SIB Операнд
Reg2
Base + Disp8
(Scale, Index, Base)
(Scale,
(Scale, Index, Base)
(Scale,
(Scale, Index, Base)
(Scale, Index, 101)
(Scale,
=
100
100,
Base + Disp32
=
100
100,
Base
=
100
=
100
100,
∗Base +2
Base)
∗Base +2
Base)
=
101
∗2
101)
зависит от разрядности режима
32-битный: Disp32
64-битный: rip + Disp32
Scale
∗Base + Disp8
Scale
∗Base + Disp32
∗Base +2
Scale
Scale
· Index + Disp32
∗Disp32
· Index + Disp8
· Index + Disp32
· Index
При
Mod =11
возможных значения
поле
Mod
R/M
— номер второго операнда-регистра. Остальные три
соответствуют косвенной адресации, то есть операнд
находится в памяти по некоторому адресу.
Адрес операнда в памяти в общем случае может включать до четырёх компо-
нент:
Адрес = Base +2
Scale
· Index+ Displacement (3.1)
где масштаб Scale [0, 3] — константа, Base и Index— регистры.
Каждая из компонент может быть опущена; таким образом, прямая адресация
в x86 является частным случаем косвенной.
Значения поля длины (при содержащего смещение. При
Mod01и10
Mod =01
показывают наличие поля
— восьмибитное, при
Mod =00
смещение может отсутствовать или быть
Mod =10
Displacement
различной
— тридцатидвухбитное),
тридцатидвухбитным в зависимости от значения других полей.
Байт
SIB
ное значение
следует за байтом
100
. Первые два его бита — масштаб — целое число
ModR/M
, если поле
R/M
принимает специаль-
Scale [0, 3]
,
3.6. Структура команды и методы адресации 135
определяющее коэффициент, на который умножается индексный регистр (соот­ветственно номера регистров. Значение поля случае считается Таким образом, индексный регистр в
1, 2, 4
или8), далее следуют трёхбитные поля
Index = 100
Index =0
(то есть получается базовая адресация без индекса).
(3.1)
IndexиBase
является специальным, в этом
не может иметь код
100
, хранящие
ни при каких
значениях прочих полей.
Если значение поля R/M отлично от 100, байт SIB отсутствует.
При
Mod =01
номер базового регистра операнда в памяти равен
100
. При
R/M = 100
Base+2
Scale
зуя специальное значение смещением; в этом случае базовый регистр
или
Mod =10
Base
любое значение
в базовой адресации со смещением, то есть адрес
Base + Displacement
используется базово-индексная адресация со смещением
·Index+ Displacement Index = 100
R/M = 100
,где
Base
,где
(Scale, Index, Base) SIB
трактуется как
не может иметь код
. Исполь-
, можно получить базовую адресацию со
Base SIB
может быть любым,
включая Base = 100.
Режим
Mod =00
адресация без смещения (поле базового регистра (безразлично, записанного в поле
является специальным и соответствует отсутствию в
101
(
Base =0
) и одновременно — присутствию в команде тридцатидвухбитного
— самый запутанный. По умолчанию используется косвенная
Displacement
отсутствует). При этом значение
R/M
или в поле
(3.1)
SIB)Base =
базового регистра
смещения. Таким образом, базовый регистр в адресации без смещения не может иметь код
Mod =01
101
(но обратиться к подобному адресу можно — например, используя
,где
101
является допустимым номером базового регистра, и указав
восьмибитное смещение, равное нулю).
В шестидесятичетырёхбитном режиме случай
трактуется как особый случай и соответствует адресации относительно адреса
00
следующей команды (специального регистра адрес операнда в памяти равен
rip + Displacement[3
R/M = Base = 101
rip
— указателя команд), то есть
при
]. В тридцатидвухбитном
Mod =
режиме аналога этой адресации нет.
В шестидесятичетырёхбитном режиме разрядность номеров регистров может
быть увеличена с помощью префиксов расширения регистра. Разрядность поля Displacement в шестидесятичетырёхбитном режиме не повышается до 64 бит.
Таким образом, всего у команды x86 может быть не более трёх явных операн­дов, среди которых не более одного непосредственного значения, не более одного значения в памяти и не более двух регистров, причём два операнда-регистра ис­ключают операнд в памяти.
Адрес операнда в памяти складывается из четырёх компонент по базово­индексной схеме со смещением, причём базовым может быть любой регистр общего назначения (в шестидесятичетырёхбитном режиме — ещё и указатель команд, но только в базовой адресации без индекса), индексным не может быть регистр с ко­дом 100.
136 Глава 3. Архитектура команд семейства x86
3.6.4. Адресация в тридцатидвухбитном режиме
Какая ни на есть вчерашняя, но техника! Серьёзное дело.
В. В. Маяковский. Париж. Быт
В тридцатидвухбитном режиме номера операндов-регистров задаются только трёхбитовыми полями байтов
ModR/MиSIB
. Каждому трёхбитному номеру со­ответствует определённый регистр общего назначения с учётом типа и разрядности команды (таблица 3.4).
Номера (коды) регистров
Таблица 3.4
Регистр
32 бита 16 бит 8 бит Команда MMX Команда XMM
Код
eax ax al mm0 xmm0 000 ecx cx cl mm1 xmm1 001 edx dx dl mm2 xmm2 010 ebx bx bl mm3 xmm3 011
esp sp ah mm4 xmm4 100 ebp bp ch mm5 xmm5 101 esi si dh mm6 xmm6 110 edi di bh mm7 xmm7 111
В зависимости от разрядности команды и от того, входит ли команда в ос­новной набор инструкций или в какое-либо из расширений, один и тот же номер адресует разные регистры. Из таблицы 3.4 видно, что в тридцатидвухбитном ре­жиме младшие байты регистров
sp, bp, si, di
не могут иметь имён, потому что
соответствующие номера уже заняты ahdh.
В качестве компонент адреса операнда можно без ограничений использовать регистры
A, B, C, D, si, di, bp
необходимой разрядности. Указатель стекаspмо­жет быть базовым, что широко используется при адресации элементов стека, но не индексным, так как его код совпадает со специальным значением
100
поля
Index
Адресация собственно операнда относительно указателя командыip(прямая относительная адресация) в тридцатидвухбитном режиме недоступна. Для адресов команд прямая относительная адресация неявно реализуется так называемыми командами ближнего перехода, которые трактуют операнд как смещение относи­тельноip, но само это смещение адресуется описанными выше средствами. Также
.
3.6. Структура команды и методы адресации 137
для адресов команд доступна и прямая абсолютная адресация (дальние переходы). Ближние и дальние переходы соответствуют разным опкодам.
3.6.5. Расширение регистров в шестидесятичетырёхбитном режиме
В последний момент Мари отдавала команду «Двоись!», и близняшки разбегались в разные стороны.
А. В. Жвалевский, И. Е. Мытько.
Здесь вам не причинят никакого вреда
В шестидесятичетырёхбитном режиме между историческими префиксами и оп­кодом может находиться специальный однобайтовый префикс расширения ре-
REX
гистров кументации как
(рис. 3.13). Его младшие три бита (биты 0-2, обозначаемые в до-
B,X,R
) используются для увеличения разрядности номеров регистров, следующий (третий) битWопределяет, используются ли шестидесяти­четырёхбитные операнды ( (
REX.W =0
). Старшие четыре бита равны Таким образом, префиксы команды с опкодами
REX.W =1
REX
40 4F
) или разрядность операндов не изменяется
0100
и служат для идентификации.
— байты в диапазоне
40 4F
(это однобайтовые формы команд
. Соответственно,
incиdec
) в ше­стидесятичетырёхбитном режиме недоступны (при этом доступны двухбайтовые формы
incиdec
с полем
ModR/M
, так что изменения в программы, написанные
на ассемблере, вносить не нужно).
7
REX
Повышение
разрядности
до64
и расширение
регистров:
0 или 1 байт
0405160
Опкод
1, 2
или 3 байта
ModR/M
0 или 1 байт
B
0X1R2W3
Префиксы
Произвольное
количество
(от 0)
по 1 байту
Рис. 3.13. Префикс расширения регистров REX в структуре
команды x86-64
Бит 2 префикса
бит 1 (
REX.X
мости от используемой адресации — к полю
REX(REX.R
) — к полю
Index
) добавляется к полю
байта
SIB
, младший бит 0 (
R/M
байта SIB или номеру регистра внутри опкода.
SIB
0 или 1 байт
байта
Displacement
0, 1, 2
или 4 байта
Reg
байта
REX.B
ModR/M
Immediate
0, 1, 2
или 4 байта
Mod R/M
), в зависи-
, полю
Base
,
138 Глава 3. Архитектура команд семейства x86
Таким образом, количество адресуемых регистров общего назначения возрас­тает до шестнадцати. Номера регистров ветствуют отсутствию префикса (в последнем случае с учётом Единица в
REX
в сочетании с трёхбитовым полем в команде даёт номера реги-
REX
REX
Adi
, указанные в таблице 3.4, соот-
или нулю в соответствующем бите
получаем четырёхбитовые коды
REX
01000111
стров 10001111, то есть r8r15 (таблица 3.5).
Номера (коды) регистров общего назначения при
использовании REX
Таблица 3.5
).
Регистр
64
бита32бита16бит8бит
Код
64
бита32бита16бит8бит
Регистр
Код
rax eax ax al 0000 r8 r8dr8wr8b 1000 rcx ecx cx cl 0001 r9 r9dr9wr9b 1001 rdx edx dx dl 0010 r10 r10dr10wr10b 1010 rbx ebx bx bl 0011 r11 r11dr11wr11b 1011 rsp esp sp spl 0100 r12 r12dr12wr12b 1100 rbp ebp bp bpl 0101 r13 r13dr13wr13b 1101
rsi esi si sil 0110 r14 r14dr14wr14b 1110 rdi edi di dil 0111 r15 r15dr15wr15b 1111
Изменяя бит 3 префикса до 64 как для в сочетании с
r8r15 REX
, так и для
с нулевым третьим битом (то есть разрядность не изменяется и операнды занимают 8 бит) коды регистров регистров
spdi
— в документации и коде программы они обозначаются Таким образом, в шестидесятичетырёхбитном режиме доступны как и
spldil
и
sil
. При этом в одной и той же команде нельзя адресовать, например,
, так как для первого требуется обязательное отсутствие у команды префикса
REX(REX.W
Adi
. При использовании восьмибитной команды
), можно получить разрядность от 8
01000111
описывают младшие байты
spldil
ahdh
, так
ah
REX, а для второго — наличие REX с нулевым третьим битом.
— не единственный префикс расширения регистров. В частности, коман-
REX
ды расширения AVX (YMM) Intel используют двух- или трёхбайтовый префикс
VEX
, одной из функций которого также является расширение номеров реги-
стров
ymm
; расширение AVX512 (ZMM) — префикс
(XOP) AMD также используется похожий, но при этом несовместимый с
EV EX
. В расширении SSE5
VEX
префикс [4].
.
3.6. Структура команды и методы адресации 139
3.6.6. Операнды и адресация в шестидесятичетырёхбитном режиме
Эта техника не застоялась, эта техника растёт.
В. В. Маяковский. Моё открытие Америки
Шестидесятичетырёхбитный режим процессоров семейства x86 является рас­ширением тридцатидвухбитного и отличается от него менее существенно, чем трид­цатидвухбитный защищённый режим от шестнадцатибитного реального. В частно­сти, структура команды аналогична описанной ранее. Режимы адресации также в основном сохраняются. Основным новшеством шестидесятичетырёхбитной адре­сации является возможность адресовать данные относительно указателя команд.
Количество доступных регистров общего назначения в шестидесятичетырёх­битном режиме увеличено за счёт возможности использования префикса
REX
хранящего дополнительный бит номера регистра. При этом при формировании адреса операнда в памяти вначале определяются его компоненты, для чего трёхби­товые поля байтов значениям, а затем уже рассматривается префикс
ModR/MиSIB
проверяются на соответствие специальным
REX
для определения номеров используемых регистров. Таким образом, в шестидесятичетырёхбитном режиме индексным не может быть ни один регистр, младшие три бита номера которого равны специальному значению
100
. Это указатель стекаspс номером
0100иr12
обозначаемый номером 1100.
Разрядность операндов в регистрах и памяти
,
,
Для большинства команд в шестидесятичетырёхбитном режиме размер опе­ранда по умолчанию — 32 бита. Разрядность операндов может быть понижена до 16 бит соответствующим префиксом или повышена до 64 префиксом
REX
с единичным третьим битом REX.W [1, 17].
В шестидесятичетырёхбитном режиме есть две группы команд, которые по умолчанию (без указания префикса
REX
) используют шестидесятичетырёхбитные операнды: это команды, работающие с указателями (условные и безусловные пере­ходы) и команды, неявно использующие указатель стека (по умолчанию это
rsp
Команды вызова и возврата из функций относятся к обеим группам, так что они по умолчанию используют шестидесятичетырёхбитные адреса и шестидесятиче­тырёхбитный указатель стека
rsp
. Разрядность операндов этих команд может быть понижена с 64 бит до 16 указанием соответствующего префикса, но способа понизить её до 32 бит не существует [3].
).
140 Глава 3. Архитектура команд семейства x86
Разрядность непосредственных операндов и смещения
Размер полей
чения в регистр) и
Immediate
Displacement
(кроме команды пересылки непосредственного зна-
в шестидесятичетырёхбитном режиме не повы-
шается до 64 бит даже при использовании префикса REX.
Таким образом, непосредственные операнды занимают 1, 2 или 4 байта. Если непосредственный операнд (обычно тридцатидвухбитный) присутствует в шести­десятичетырёхбитной команде, он расширяется до 64 бит во время исполнения команды.
Единственная команда, включающая непосредственный операнд размером 8 байт — команда пересылки непосредственного операнда в регистр в сочетании с единичным кументации Intel эта форма команды обозначается мнемоникой
REX.W
(что повышает разрядность регистра-приёмника до 64). В до-
mov
, как и другие
варианты пересылки значения. Синтаксис AT&T выделяет форму с шестидесяти­четырёхбитным непосредственным операндом как мнемонику movabs.
3.6.7. Адресация относительно указателя команды
В ней есть одна странная черта — снаружи, внешне эта техника производит недоделанное, временное впечатление.
В. В. Маяковский. Моё открытие Америки
В тридцатидвухбитном режиме, как указано в таблице 3.3, существует два способа прямой адресации (указания на фиксированный адрес
Displacement
в памяти):
– без использования байта SIB, при R/M = 101; –
с использованием
SIB
со специальными значениями как поля базы, так и поля
индекса, то есть при R/M = 100,Base = 101,Index = 100. Оба они доступны при Mod =00, так что адрес Displacement тридцатидвухраз- ряден.
В шестидесятичетырёхбитном режиме к фиксированному адресу можно об­ратиться, только указав специальные значения байта
SIB
, а при
R/M = 101
используется адресация относительно счётчика командip(в шестидесятичетырёх­битном режиме — rip) [3]:
Адрес =
ip + Displacement, R/M = 101 Displacement, R/M = 100,Base = 101,Index = 100
(3.2)
Таким образом, хотя шестидесятичетырёхбитный указатель команд
rip
по-прежнему
не является регистром общего назначения и не имеет собственного номера, он может быть базовым при Mod =00без байта SIB.
Адресация относительно ip используется для решения двух задач:
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]