Расширение системы команд в процессорах 80286 и 80386

advertisement
Системное программное обеспечение
Лекция № 6 «Расширение системы команд в процессорах 80286 и 80386»
Расширение системы команд в процессоре 80286
В систему команд процессора 80286 был введен ряд
специальных команд, которые можно разбить на следующие группы:
1.
Команды
для
использования
компиляторами
языков
высокого уровня, хотя, безусловно, их можно применять в чисто
ассемблерном коде.
bound regW, memDW
Команда bound проверяет, находится ли индекс в заданном
диапазоне — и иногда называется проверкой диапазона в языках
высокого уровня. Поскольку большинство таких языков выполняет
вызов специальных подпрограмм для проверки индексов массивов,
использование bound может увеличить скорость программы, сохраняя
безопасность проверки диапазонов, которую многие программисты
запрещают для увеличения скорости.
Расширение системы команд в процессоре 80286
Команда bound требует два операнда. Первый из операндов
должен
быть
16-битовым
регистром
и
должен
содержать
проверяемое индексное значение. Второй операнд - это адрес 32битового двойного слова в памяти, содержащего младшее и старшее
значение диапазона индекса. Если величина первого операнда не входит
в установленный диапазон, процессор осуществляет прерывание 5. В
программе необходимо установить соответствующую процедуру
перехвата и обслуживания этого прерывания.
Прерывание 5 в BIOS – это печать экрана, что приводит к
конфликту: если при проверке индекса он оказывается за пределами
диапазона, а клавиша <PrtScr> не запрещена, то возникновение
ошибки приведет к печати содержимого экрана и будет происходить
снова и снова, до тех пор пока не будет перезагружена система.
Расширение системы команд в процессоре 80286
Эта команда не меняет флаги.
; в сегменте данных
BoundMas
label
word
Low_Bound
dw
0
Upp_Bound
dw
20
mas
10 dup (?)
dw
; в сегменте кода
xor
di,di
;очистка индексного регистра
mov
ax,mas[di]
add
di,2
bound
di,BoundMas
cycl:
;перебор элементов массива
; если значение в di не будет попадать в границы, то будет вызван
; обработчик прерывания 5, где можно скорректировать
; значение ip в стеке с тем, чтобы выйти
; из бесконечного цикла, например, на метку М2 или
; выполнить другие действия
jmp
М2:
cycl
Расширение системы команд в процессоре 80286
enter n, level
Команда предназначена для выделения соответствующего
пространства в стеке для локальных переменных процедуры.
Такие переменные динамические — они существуют только во
время работы подпрограммы. Эти методы обычно применяются в
языках
высокого
уровня
как
составная
часть
их
методов
использования функций и процедур, но при желании их можно
применять и в чисто ассемблерном коде.
Команда enter обычно первая строка процедуры. enter
требует двух операндов, каждый из которых должен быть числом.
Первый операнд представляет собой число байтов, которые
необходимо зарезервировать в стеке. Второй операнд представляет
собой уровень вложения процедуры.
Расширение системы команд в процессоре 80286
Если 3 процедуры включаются одна в другую, самая
внутренняя находится на уровне 2, средняя — на уровне 1, а внешняя —
на уровне 0. Уровни вложения нужны для поддержки таких языков, как
Паскаль, который позволяет дочерним процедурам получать доступ к
локальным переменным, описанным в родительских процедурах.
Команда enter аналогична трем командам процессора 8086:
push bр
; Сохранить текущее значение bр
mov
bp,sp ; Записать указатель стека в bр
sub
sp,n ; Выделить стековое пространство для переменных
Вначале bр засылается в стек для сохранения его исходной величины.
Затем в bр устанавливается значение указателя стека sp, что
позволит командам использовать регистр для адресации локальных
переменных. Затем выделяется место под переменные путем
вычитания первого параметра команды enter из указателя стека.
Расширение системы команд в процессоре 80286
В любой процедуре, использующей enter, перед выходом из
процедуры командой ret необходимо выполнить команду
leave
для освобождения стекового пространства, выделенного enter, и для
восстановления sp и bр. Команда leave выполняет те же действия,
что и две команды процессора 8086:
mov
sp,bp
; Восстановить указатель стека из bр
pop
bр
; Восстановить значение bр
Копирование bр в sp освобождает пространство, занятое в
стеке
перед
восстановлением
величины
bр,
которая
могла
использоваться другими процедурами для адресации их собственных
локальных переменных. В качестве примера полной процедуры,
использующий enter и leave, можно привести подпрограмму:
Расширение системы команд в процессоре 80286
proc1
proc
;зарезервировать в стеке место для локальных переменных
;proc1 16 байт
;лексический уровень вложенности 0
enter
16,0
...
leave
ret
proc1
endp
Эти команды не меняют флаги.
2. Новые команды для работы со стеком.
Команда
pusha
сохраняет регистры ах, cx, dx, bx, sp, bp, si и di в стеке в
перечисленном порядке. Обратите внимание, что указатель стека
также
сохраняется.
Но
величина
sp,
копируемая
соответствует значению sp перед выполнением pusha.
в
стек,
Расширение системы команд в процессоре 80286
Команда
рора
удаляет все регистры основного назначения из стека. Выполнение рора
(обычно после предшествующей pusha) извлекает регистры di, si, bp,
sp, bx, dx, cx и ax в соответствующем порядке. Все регистры общего
назначения восстанавливают значения, которые они имели перед
выполнением предыдущей команды pusha. Сегментные регистры не
сохраняются и не восстанавливаются командами pusha и рора.
Обычно
это
необходимо
в
начале
и
конце
процедур
обслуживания прерываний, хотя можно использовать эти команды и в
простых процедурах.
Эти команды не меняют флаги.
Расширение системы команд в процессоре 80286
3. Команды ввода-вывода строк в порты
Синтаксис команд аналогичен описанию примитивов команд
обработки строк.
ins dest, port
Команда вводит данные из порта ввода-вывода, номер
которого загружен в регистр dx, в память по адресу es:[di].
Сегментная составляющая адреса должна быть обязательно в
регистре
es.
Замена
сегментного
регистра
недопустима.
Непосредственное задание порта в команде также недопустимо - для
этого используется регистр dx. Размеры вводимых элементов (байт
или слова) зависят от способа описания приемника в программе на
Ассемблере. Транслятор, обработав команду ins и выяснив тип
операнда, генерирует одну из машинных команд:
Расширение системы команд в процессоре 80286
insb
insw
Как
и
в других командах
обработки
машинного аналога для команды ins нет.
Пример.
; в сегменте данных
str_10
db
10 dup(0)
adr_str
dd
str_10
; в сегменте кода
les
di,adr_str
mov
dx,300h
mov
cx,10
rep
insb
строк
Расширение системы команд в процессоре 80286
outs port, src
Команда выводит данные в порт ввода-вывода, номер
которого загружен в регистр dx, из памяти по адресу ds:[si]. Замена
сегментного регистра допустима. Непосредственное задание порта в
команде недопустимо - для этого используется регистр dx. Размеры
выводимых элементов (байт или слова) зависят от способа описания
источника в программе на Ассемблере. Транслятор, обработав
команду outs и выяснив тип операнда, генерирует одну из машинных
команд:
outsb
outsw
Как и в других командах обработки строк машинного аналога
для команды outs нет.
Расширение системы команд в процессоре 80286
Пример.
; в сегменте данных
str_10
db
10 dup(0)
adr_str
dd
str_10
lds
si,
adr_str
mov
dx,
300h
mov
cx,
10
rep
outsb
Эти команды не меняют флаги.
4. Модификация команд сдвига и циклического сдвига.
Малозаметным улучшением в командах 80286 является
возможность устанавливать величины непосредственного сдвига и
циклического сдвига, большие, чем на 1. Это означает, что команды
8086:
Расширение системы команд в процессоре 80286
mov
shl
cl, 4
ax, cl
могут быть упрощены:
shl
ах,4
Такое же изменение применимо ко всем командам сдвига и
циклического сдвига процессора 8086. При необходимости можно попрежнему указывать значение сдвига в cl.
Расширение системы команд в процессоре 80386
В процессоре 80386 введены новые команды, позволяющие
работать с 32-разрядными данными. Их можно разделить на
следующие группы:
1. Команды битового сканирования и проверки битов
bsf dest, src
(Bit Scan Forward — битовое сканирование вперед)
Используется для установки в 16- или 32-разрядный регистр
приемника номера позиции первого ненулевого бита в байте, слове или
двойном слове источника. Флаг zf при этом равен 0. Источником
может быть регистр или ячейка памяти. Сканирование проходит от
младшего бита к старшему. Если не найдено ни одного единичного
бита, флаг zf устанавливается в 1 и содержимое приемника не
меняется.
Расширение системы команд в процессоре 80386
bsr dest, src
(Bit Scan Reverse — обратное битовое сканирование)
То же самое, что bsf, но только сканирование в обратном
направлении от старшего бита к младшему.
Одним из способов использования этих команд может быть
установка в cl числа битов, необходимых для сдвига единичного бита в
позицию нулевого бита.
Например:
mov dx, 00100000b
bsf сx, dx
jz short AllZero
shr dx, cl
AllZero:
А теперь случай, когда больше, чем один бит, установлен в 1:
Расширение системы команд в процессоре 80386
mov bx, 00010110b
bsf cx, bx
bsr cx, bx
; cx = 1
; cx = 4
bt dest, src
(Bit Test — проверка бита)
Копирует бит приемника, номер которого указан в источнике,
в флаг переноса cf. Каждый из операндов может быть 16- или 32разрядным
регистром;
второй
операнд
может
задаваться
непосредственным значением. Приемник может быть 16- или 32разрядной ячейкой памяти, а источник непосредственным значением.
btс dest, src
(Bit Test and Complement — проверка бита с инверсией)
То же самое, что bt, но только бит приемника после
копирования в флаг переноса cf меняет значение на противоположное.
Расширение системы команд в процессоре 80386
btr dest, src
(Bit Test and Reset — проверка бита с его сбросом в 0)
То же самое, что bt, но только бит приемника после
копирования в флаг переноса cf сбрасывается в 0.
bts dest, src
(Bit Test and Set — проверка бита с его установкой в 1)
То же самое, что bt, но только бит приемника после
копирования в флаг переноса cf устанавливается в 1.
mov
dx,01010011b
bt
dx,4
;проверка состояния бита 4 и установка cf в 1
jc
m1
;перейти на m1, если проверяемый бит равен 1
2. Команды конвертирования данных
В дополнение к cbw и cwd можно использовать:
Расширение системы команд в процессоре 80386
cdq
(Convert Double word to Quad word — преобразование двойного слова в
учетверенное слово),
для того чтобы конвертировать 32-битовое двойное слово со знаком в eax в
64-битовое четверное слово со знаком в паре регистров edx:eax путем
копирования значения старшего бита регистра eax на все биты регистра edx
и
cwde
(Convert Word to Double Word Extended — преобразование слова в
двойное слово)
для конвертации слова со знаком в ax в двойное слово со знаком в расширенный
аккумулятор еах путем копирования значения старшего бита регистра ax на
все биты старшего слова регистра еах.
Эти команды не влияют на флаги.
Расширение системы команд в процессоре 80386
mov
cdq
idiv
eax,delimoe
delitel
;частное в eax, остаток в edx
movsx dest, src
(MOVe and Sign eXtension — пересылка со знаковым расширением)
преобразует
элемент
со
знаком
меньшей
размерности
в
эквивалентный ему элементы со знаком большей размерности путем
распространения значения знакового разряда источника на свободные
старшие разряды приемника.
movzx dest, src
(MOVe and Zero eXtension — пересылка с нулевым расширением)
то же самое, что и movsx, но для чисел без знака. При этом двоичный
нуль распространяется на свободные старшие разряды приемника.
Эти команды также не влияют на флаги.
Расширение системы команд в процессоре 80386
Для обеих команд первый операнд должен быть 16- или 32битовым расширенным регистром. Второй операнд может быть 8либо 16-битовым регистром или указателем на память.
mov
al,
0ffh
movsx
bx,
al
;bx=0ffffh
3. Команды для загрузки сегментных регистров
Позволяют получить логический адрес в виде сегментной
составляющей и смещения.
lfs dest, src
(Load pointer into fs segment register — загрузка сегментного регистра fs
указателем из памяти)
Алгоритм работы команды зависит от действующего режима
адресации (16- или 32-разрядной):
Расширение системы команд в процессоре 80386
• если 16-разрядный, то первые два байта из ячейки памяти
источника загружаются в 16-разрядный регистр, указанный
операндом
приемник.
Следующие
два
байта
источника
загружаются в регистр fs;
• если 32-разрядный, то первые четыре байта из ячейки памяти
источника заргужаются в 32-разрядный регистр, указанный
операндом
приемник.
Следующие
два
байта
источника
загружаются в регистр fs.
lgs dest, src
(Load pointer into gs segment register — загрузка сегментного регистра
gs указателем из памяти)
То же самое, что lfs, только загружается сегментный регистр gs.
Расширение системы команд в процессоре 80386
lss dest, src
(Load pointer into ss segment register — загрузка сегментного
регистра ss указателем из памяти)
То же самое, что lfs, только загружается сегментный
регистр ss.
Все команды не влияют на флаги.
Третья команда — lss позволяет, как частный случай,
инициализировать одновременно ss и sp.
Одним
подхватывание
из
способов
адреса
монстрирует пример.
применения
альтернативного
lss
стека,
является
как
де-
Расширение системы команд в процессоре 80386
mov
mov
lss
.
.
.
mov
mov
oldss, ss
oldsp, sp
sp, newstack
; Сохранение старого стекового сегмента
; и старого указателя стека
; Загрузка ss:sp новыми значениями
sp, oldsp
ss, oldss
; Восстановление sp
; Восстановление ss
4. Команды для работы со стеком
pushad
(PUSH All general Double word registers onto stack — размещение всех
регистров общего назначения в стеке)
Размещает в стеке регистры общего назначения в следующей
последовательности: eax, ecx, edx, ebx, esp, ebp, esi, edi. Величина
сохраненного esp равна величине указателя стека до выполнения
pushad.
Расширение системы команд в процессоре 80386
popad
(POP All general Double word registers from the stack —
извлечение всех регистров общего назначения из стека)
Извлекает из стека регистры общего назначения в
следующей последовательности: edi, esi, ebp, esp, ebx, edx, ecx,
eax. Регистр esp по-прежнему восстанавливается тем же
значением, которое он имел до pushad.
Команды не влияют на флаги.
pushfd
(PUSH eFlags Double word register onto stack — размещение
расширенного регистра флагов в стеке)
Размещает в стеке содержимое регистра флагов eflags.
Расширение системы команд в процессоре 80386
popfd
(POP eFlags Double word register from the stack — извлечение
расширенного регистра флагов из стека)
Извлекает из стека содержимое регистра флагов eflags.
Действие на флаги аналогично командам pushf и popf с
учетом 32-разрядного расширения.
5. Set-команды
Набор команд, общий синтаксис которых, может быть
представлен следующим образом:
setcc dest
(byte SET on condition — установка байта по условию)
Расширение системы команд в процессоре 80386
Установка приемника (байтового регистра или ячейку
памяти) логическим значением (0 или 1) в зависимости от
истинности условия, заданного модификатором кода операции
cc. Окончание cc у set такие же, как и у команд условного
перехода: seta, setae, setb, setbe и т.д.
Пример:
;подсчитать число единичных битов в регистре ax
m1:
mov
cx,16
mov
bh,0
rol
ax,1
setc
bl
add
bh,bl
clc
loop
m1
Расширение системы команд в процессоре 80386
6. Сдвиги двойной точности
shld dest, src, cnt
(SHift Left Double word — cдвиг двойного слова влево)
Первый операнд определяет приемник результата и может
быть регистром слова либо двойного слова или ссылкой на память.
Второй операнд, который должен быть регистром слова или двойного
слова, содержит биты, сдвигаемые в первый операнд. Сам он при
этом не меняется. Третий операнд представляет собой число битов,
которые надо сдвинуть влево. Этот операнд может быть
конкретной величиной от 0 до 31 или же регистром cl.
shrd dest, src, cnt
(SHift Right Double word — cдвиг двойного слова вправо)
То же самое, что shld, только сдвиг вправо.
Расширение системы команд в процессоре 80386
Пример показывает типичное использование shld.
; в сегменте данных
v1 dd 00012345h
v2 dd 6789ABCDh
; в сегменте кода
mov сl, 8
mov eax, v2
shld v1, eax, cl
shl v2, cl
; v1 = 01234567
; v2 = 89ABCD00
Два двойных слова, vl и v2, образуют в памяти 64-битовую переменную.
Только четыре инструкции требуются для сдвига этой переменной влево на
любое число битов — в данном примере на 8. Прежде всего в cl загружается
счетчик сдвига. Затем вторая часть значения загружается в еах.
Инструкция shld сдвигает биты из еах в v1, которое также сдвигается влево
равное число раз. Инструкция shl завершает сдвиг, сдвигая v2 в
соответствии с этим же счетчиком, хранящимся в cl. Эффективным результатом является умножение за очень короткий промежуток времени
полного 64-битового значения двойной точности на 28 (256 десятичное).
Расширение системы команд в процессоре 80386
7. Команды обработки строк
Во все примитивы команд обработки строк процессоров 8086
и 80286 добавлются команды для работы со строками, состоящими из
двойных слов:
movsd – копировать строку двойных слов;
cmpsd – сравнение строк двойных слов;
scasd – сканировать строку двойных слов;
lodsd – загрузить строку двойных слов;
stosd – сохранить строку двойных слов;
insd – ввести строку двойных слов из порта;
outsd - вывести строку двойных слов в порт.
Download