
- •Программирование эвм
- •Int 21h ;кодом возврата 0 прерывания 21h
- •Работа с битами
- •Порядок выполнения работы
- •Устройства ввода-вывода
- •Ввод исходных данных с клавиатуры и вывод результатов на дисплей
- •Inc di ;смещение в видеопамяти на следующий символ
- •Порядок выполнения работы
- •Контрольные задания
- •Система команд процессора
- •Способы адресации
- •Влияние команд на регистр флагов
- •Расширенные регистры и типы данных процессоров x86
- •Система команд процессоров ia-32 и Intel 64
- •Int 21h ;системного прерывания 21h
- •Использование дальней подпрограммы
- •X dw 0aabBh, 0abbAh, 0baaBh, 0bbaAh ;исходные данные
- •Использование подпрограмм для ввода-вывода
- •Порядок выполнения работы
- •Контрольные задания
- •Дескрипторы
- •Порядок работы процессора в защищенном режиме
- •Использование дальней подпрограммы в защищенном режиме
- •Использование idt. Ввод данных с клавиатуры в защищенном режиме
- •Порядок выполнения работы
Система команд процессоров ia-32 и Intel 64
Формат команды процессоров IA-32 и Intel 64
Общий формат команды процессоров IA-32 и Intel 64 включает шесть полей (перечисляются слева направо, от старших байтов к младшим):
-
префиксы команды, 0-4 префикса размером в один байт каждый, по одному из каждой группы (см. ниже);
-
код операции, 1-3 байта;
-
байт ModR/M (Mode, Register/Memory), присутствует во многих командах, операнды которых находятся в памяти, включает три поля:
-
биты 7, 6 — Mod — способ адресации, в комбинации с полем R/M (биты 2-0) дает 32 возможных значения: 8 регистров и 24 способа адресации;
-
биты 5-3 — Reg/Opcode — содержит имя регистра или дополнительную часть кода операции в зависимости от значения первичного кода операции;
-
биты 2-0 — R/M — регистр или ячейка памяти, определяет используемый регистр или в комбинации с полем Mod — способ адресации;
-
байт SIB (Scale, Index, Base), присутствует в команде при определенных значениях байта ModR/M для полного определения способа адресации, включает три поля:
-
биты 7, 6 — Scale, коэффициент масштабирования;
-
биты 5-3 — Index, имя индексного регистра;
-
биты 2-0 — Base, имя базового регистра;
-
поле Displacement, смещение операнда при прямой адресации, 0-4 байта;
-
поле Immediate, непосредственный операнд, 0-4 байта.
Только поле кода операции всегда присутствует в команде, остальные поля могут отсутствовать.
Максимальная длина команды — 15 байтов.
Трехбайтный код операции имеют некоторые команды SSE и SSE2.
Префиксы
Префиксы делятся на четыре группы:
1. Блокировки и повторения:
F0H — LOCK;
F2H — REPNE/REPNZ;
F3H — REP/REPE/REPZ.
LOCK переводит одноименный сигнал в активный уровень на время выполнения команды, снабженной данным префиксом.
Префиксы повторения приводят к тому, что команда выполняется множество раз для заданного количества элементов строки. Префиксы повторения используются только со строковыми командами. Если они используются вместе с escape-кодом 0FH, то обрабатываются как обязательные префиксы для некоторых SIMD-команд.
2. Префиксы замены сегмента:
26H — ES;
2EH — CS;
36H — SS;
3EH — DS;
64H — FS;
65H — GS.
Префиксы указания ветвления:
2E — ветвление не принимается;
3E — ветвление принимается.
Префиксы указания ветвления позволяют программе давать указание процессору о наиболее вероятном пути хода программы. Они введены в Pentium 4 как часть SSE2.
Первые шесть префиксов могут быть использованы с любыми командами управления программой, последние два используются только с командами условных переходов.
3. Префикс замены размера операнда 66H. Если используется вместе с escape-кодом 0FH, то обрабатывается как обязательный префикс для некоторых SIMD-команд.
4. Префикс замены размера адреса 67H.
Примеры.
Команда преобразования двух упакованных знаковых двойных слов из регистра XMM или памяти в два упакованных числа с плавающей точкой удвоенной точности в регистре XMM:
CVTDQ2PD — F3 0F E6.
Здесь первый байт — обязательный префикс команд SSE/SSE2/SSE3, а не префикс повторения, второй байт — escape-код, третий — код операции.
Таким образом, код операции этой команды занимает два байта.
Команда горизонтального сложения 16-разрядных знаковых целых с упаковкой в регистр XMM:
PHADDW — 66 0F 38 01.
Здесь первый байт — обязательный префикс команд SSE/SSE2/SSE3, а не префикс замены размера операнда, второй байт — escape-код, третий и четвертый байты — собственно код операции.
Таким образом, код операции этой команды занимает три байта.
В 64-битном режиме в команде может быть использован еще один префикс — REX (коды 40-4FH), который должен стоять непосредственно перед кодом операции. При этом ограничение на длину команды в 15 байтов остается в силе.
Пример.
MOV RAX,1122334455667788H — 48 B8 8877665544332211
В каждой команде может быть использовано по одному префиксу из каждой группы в любом порядке. Действие избыточных префиксов (более одного из группы) является неопределенным и меняется от процессора к процессору.
Формат кода операции
Код операции содержит, в свою очередь, более мелкие поля, которые определяют:
-
тип операции;
-
направление операции, т. е. куда записывается результат — в первый операнд или второй (d);
-
размер данных (w) — байт или полный размер (2 или 4 байта);
-
имя используемого регистра (reg, sreg2, sreg3, eee (CR или DR));
-
условие (cond (tttn));
-
расширение со знаком непосредственных данных (s).
Формат кода операции зависит от типа команды.
Способы адресации в процессорах IA-32 и Intel 64
Некоторые способы адресации в процессорах IA-32 и Intel 64 требуют присутствия в команде смещения или непосредственных данных. Каждое из этих полей может занимать 1, 2 или 4 байта.
Можно выделить следующие типы адресации:
1. Регистровая:
MOV reg1, reg2 : 1000 100w : 11reg1reg2 : reg2 reg1
1000 101w : 11reg1reg2 : reg1 reg2
MOV AX, BX : 1000 1011 : 11000011 (8B C3) : AX BX
2. Непосредственная:
MOV reg, im : 1011w reg : immediate data
MOV CX, 0003 : 10111001 : 0300 (B9 03 00)
Адресация со стороны источника непосредственная, со стороны приемника — регистровая.
3. Прямая:
MOV AX, Var
4. Косвенная:
MOV AX, [BX]
5. По базе со сдвигом:
MOV AX, [BX+2]
6. Косвенная с масштабированием (и сдвигом):
MOV AX, [ESI*2]+2
7. По базе с индексированием (и сдвигом):
MOV AX, [BX+SI+2]
8. По базе с индексированием и масштабированием.
Последние четыре способа адресации представляют собой комбинации двух базовых типов: прямой и косвенной адресации.
Группы команд процессоров Intel 64 и IA-32
Команды процессоров Intel 64 и IA-32 делятся на следующие группы:
-
команды общего назначения (general purpose);
-
x87 FPU — начиная с i486;
-
MMX — Pentium MMX;
-
SSE — Pentium III;
-
SSE2 — Pentium 4;
-
SSE3 — Pentium 4 с технологией HT;
-
SSSE3 — Xeon 5100, Core;
-
системные;
-
режима IA-32e (64-битного);
-
VMX (Intel Virtualization Technology).
Команды общего назначения процессоров Intel 64 и IA-32
Команды общего назначения делятся на следующие подгруппы:
-
Команды передачи данных.
-
Команды целочисленной двоичной арифметики.
-
Команды десятичной арифметики.
-
Команды логических операций.
-
Команды сдвига.
-
Команды битовых и байтовых операций.
-
Команды передачи управления.
-
Команды строковых операций.
-
Команды ввода-вывода.
-
Команды управления флагами.
-
Команды операций над сегментными регистрами.
-
Другие команды.
Примеры программ
Использование ближней подпрограммы
Следующая программа иллюстрирует использование подпрограммы, находящейся в одном сегменте с основной программой. Такая подпрограмма называется ближней. Для простоты подпрограмма осуществляет линейное преобразование Y=A*X+B.
Команды вызова подпрограммы (CALL) отличаются от команд перехода (JMP) тем, что после выполнения последней команды подпрограммы, управление передается команде, следующей за командой вызова подпрограммы. Для этого необходимо сохранить адрес этой команды, который называется адресом возврата. При ближнем вызове адрес возврата представляет собой смещение данной команды или текущее значение регистра IP после чтения команды CALL. Адрес возврата сохраняется в стеке. Соответственно, в программе используется сегмент стека.
Параметры в этом примере передаются подпрограмме через регистры и через стек. Указатель базы указывает на кадр параметров со старшего адреса.
;LinearP.asm
;программа линейного преобразования Y=A*X+B
;сегмент стека
stck segment stack
dw 10h dup(0) ;16 слов, инициализированных нулем
stck ends
;сегмент данных
data segment
A dw 5Fh ;коэффициент A
B dw 0Fh ;коэффициент B
X db 7Ah, 1Bh, 6Ch, 4Dh ;исходные данные
Y dw 4 dup(?) ;результаты
data ends
;сегмент команд
code segment
assume cs:code, ds:data, es:data, ss:stck
;подпpогpамма линейного преобразования
lnr proc
mov bp, sp ;направление указателя базы на верхушку стека
add bp, 4 ;направление указателя базы на кадр параметров
mov bx, [bp] ;передача в BX коэффициента A
imul bl ;AX=A*X
add ax, [bp-2] ;AX=A*X+B
ret 2*2 ;возврат из подпрограммы с очисткой стека
lnr endp ;конец подпрограммы линейного преобразования
;основная пpогpамма
main: mov dx, data ;точка входа в программу
mov ds, dx ;инициализация регистра сегмента данных
mov es, dx ;инициализация регистра ES
lea si, X ;инициализация индекса источника
lea di, Y ;инициализация индекса приемника
mov cx, 4 ;инициализация счетчика цикла
;цикл чтения исходных данных, передачи их подпрограмме
;и записи результатов преобразования
mloop: lodsb ;загрузка аккумулятора исходным значением
push A ;помещение в стек коэффициента A
push B ;помещение в стек коэффициента B
call lnr ;вызов подпрограммы линейного преобразования
stosw ;размещение результата в памяти
loop mloop ;команда управления циклом
mov ax, 4C00h ;функция завершения программы