УМЕНИЯ ПРОЦЕССОРОВ i8086 И i8088
Процессор Intel 8086 может производить разнообразные операций над
шестнадцатибитными числами в разных представлениях, производить операций над
строками. Здесь представлено как это делать и что умеют эти процессоры.
Содержание:
- Введение
- Как вычислять на процессоре
- Регистры общего назначения
- Сегментные регистры
- Регистр состояния (флагов)
- MOD, REG и R/M - адресация операндов
- Доступные форматы записи чисел
- Стак
- Вычисляем на процессоре - в ожиданий
- Окончание
Этот документ обозревает умения и возможности процессоров Intel 8086 и 8088,
которые представлены в одну семью INTEL 8086 FAMILY. Этот документ
предраспологает, что тебе доступна информация о конкретном ассемблере который
ты имеешь, и об его дополнительных синтаксических элементах как и о элементах
синтаксиса во всех платформах (Например, ORG).
Различия между 8086 и 8088 заключаются лишь в работе шины данных: процессор
8086 передаёт шестнадцатибитные данные на чётные адреса за один раз, на
нечётных адресах он их передаёт по одному байту, и процесс становится на 4
такта больше; 8088 всегда передаёт данные по одному байту, и его можно
использовать с распространёнными 8-битными чипами памяти.
Также, шестнадцатебитные данные, которыми оперирует процессор, здесь называются
машинными СЛОВАМИ.
Процессор может брать один операнд из памяти, а другой операнд брать внутри
себя. Внутри процессора операнды хранятся в регистрах. Восемь из них
предназначены для хранения операндов и называются РЕГИСТРАМИ ОБЩЕГО
НАЗНАЧЕНИЯ, а другие шесть нужны при выполнений программы. Из этих шести
операндов, четыре хранят смещения сегментов и называются СЕГМЕНТНЫМИ
РЕГИСТРАМИ, один держит курс выполнения программы и называется УКАЗАТЕЛЕМ
ИНСТРУКЦИЙ (IP), ещё один запоминает характер результата команды и по нему
делают решения, называется РЕГИСТР СОСТОЯНИЯ (или регистр флагов).
Регистры общего назначения есть следующие:
- A - Accumulator, Аккумулятор
- D - Data, данные
- C - Count, счётчик
- B - Base, основа
- SP - Stack Pointer, указатель верхушки стека, не совсем предназначен
для хранения операндов
- BP - Base Pointer, указатель основы стека
- SI - Source Index, указатель места источника
- DI - Destination Index, указатель места назначения
Важно: некоторые инструкций (помимо PUSH и
POP) при исполнений производят операций со стеком, поэтому лучше
не использовать регистр SP для хранения операндов, в частности в системах со
внешними прерываниями, и если программа будет включать процедуры.
К первым четырём регистрам, можно обращаться тремя способами, которые следует
указывать всегда, как суффикс: X - ко всему регистру, H - к его верхней части,
и L - к его нижней части.
Например: AX - весь регистр A, CL - нижняя часть регистра C, наконец DH -
верхняя часть регистра D.
Одним из нововедений процессора 8086 является сегментная модель памяти,
созданная с целью расширить объём адресуемой памяти. Они хранят смещение
соответствующего сегмента, который может быть задан с шагом в 16 байт.
Сегментные регистры есть следующие:
- CS - Code Segment, хранит смещение сегмента с программой
- SS - Stack Segment, хранит место расположения стека
- DS - Data Segment, хранит место сегмента данных
- ES - Extra Segment, хранит место дополнительного сегмента данных
Благодаря сегментной модели памяти программы можно сделать независимыми
от их расположения в памяти, что может быть использовано при созданий
многозадачных операционных систем.
Сегментные регистры работают следующим образом:
(Пример) Содержимое сегментного регистра вставляется
на четыре бита левее
DS │0111 0100 0000 0000|<─── - Содержимое сегментного регистра
OFFSET + │0001 1000 0110 0100│ - Высчитаное смещение операнда
ADDRES =│0111 0101 1000 0110 0100│ - Физический адрес, то есть адрес
ячейки памяти, значение которого будет
запрошено
Регистр состояния используется для отражения результата какой-либо операций, а
также определения поведения некоторых команд и процессора. Флагов всего девять.
Все арифметические и логические операций (и не только) отражают результат
обновлением флагов состояний, которых всего шесть.
ФЛАГИ СОСТОЯНИЯ
╔═══╦════════════════╤═══════════════════════════╗
║ИМЯ║ НАЗВАНИЕ │ ЗНАЧЕНИЕ ║
╠═══╩════════════════╧═══════════════════════════╣
║ Результат выполнения ║
╟───╥────────────────┬───────────────────────────╢
║CF ║Carry │Перенос ║
║PF ║Parity │Чётность ║
║AF ║Auxiliary carry │Десятичный перенос ║
║ZF ║Zero │Ноль/нуль ║
║SF ║Sign │Знак ║
║OF ║Overflow │Переполнение ║
╟───╨────────────────┴───────────────────────────╢
║ Работа и управление ║
╟───╥────────────────┬───────────────────────────╢
║IF ║Interrupt enable│Обработка прерываний ║
║DF ║Direction │Направление обработки строк║
║TF ║Trap │Пошаговое выполнение ║
╚═══╩════════════════╧═══════════════════════════╝
Эти флаги имеют следующие значения:
- CF
- Флаг переноса хранит значение переноса при сложений или вычитаний
длинных чисел (длинее чем слово). Также он может хранить значение
крайнего бита при смещениях на 1.
- PF
- Флаг чётности установлен, когда количество установленных (не
сброшенных, равных 1) битов в результате чётное. Если их количество не
чётное, то флаг сброшен.
- AF
- Дополнительный флаг переноса хранит значение пятого бита при сложений,
или четввёртого бита при вычитаний. Используется командами
корректировки под двоично кодированный десятичный формат.
- ZF
- Этот флаг устанавливается когда результат равен нулю.
- SF
- Этот флаг устанавливается в соответствие со старшим битом результата.
- OF
- Если он будет установлен, то произошло арифметическое переполнение:
результат оказался слишком большим чтобы записать его на место.
На основе их состояний можно выполнять условные переходы. Последние три
определяют работу процессора и режим работы со строками.
- IF
- Установка этого флага сообщает процессору обрабатывать внешние
маскируемые прерывания.
- DF
- Этот флаг определяет направление обработки строк. Когда он сброшен,
строки обрабатываются с нижних адресов до верхних; а когда он сброшен,
то обрабатываются с верхних до нижних.
- TF
- Этот флаг заставляет процессор генерировать прерывание ?1 после
выполнения каждой операций. Этот флаг предназначен для отладок.
Часто в командах операнды указываются в этой структуре:
│ Байт 1 │ Байт 2 │ Байт 3 │
│0│1│2│3│4│5│6│7│0│1│2│3│4│5│6│7│0│1│2│3│4│5│6│7│
│MOD│ REG │ R/M │ DISP-LOW │ DISP-HIGH │
Поле MOD определяет режим поля R/M как содержащий адрес к регистру или к
памяти, и в последнем случае также определяет размер поля постоянного смещения
(DISP).
╔═══╦══════════════════════════════╗
║MOD║ R/M и DISP ║
╠═══╬══════════════════════════════╣
║00 ║DISP = 0 ║
║01 ║DISP размером в 8 бит ║
║10 ║DISP размером в 16 бит ║
║11 ║R/M адресует регистр (см. REG)║
╚═══╩══════════════════════════════╝
В этом поле записывается номер регистра, с содержимым которого надо
будет работать. Так как не во всех операциях нужны два операнда, он может
содержать продолжение кода операций.
ПОЛЕ REG,
УКАЗАНИЕ РЕГИСТРА
╔═══╦═════╤═════╗
║REG║W = 0│W = 1║
╠═══╬═════╪═════╣
║000║ AL │ AX ║
║001║ CL │ CX ║
║010║ DL │ DX ║
║011║ BL │ BX ║
║100║ AH │ SP ║
║101║ CH │ BP ║
║110║ DH │ SI ║
║111║ BH │ DI ║
╚═══╩═════╧═════╝
Бит W, записываемый в первом байте команды, определяет разрядность операндов,
поэтому влияет на адресацию регистров.
В этом поле задают метод, по которому должно быть высчитано смещение в памяти
для одного из операндов.
РАСЧЁТ АДРЕСА ОПЕРАНДА R/M
╔═══╦═══════╤══════════════╤═══════════════╤═══════════╗
║R/M║ MOD=00│ MOD=01 │ MOD=10 │ MOD=11 ║
╠═══╬═══════╪══════════════╪═══════════════╪═══════════╣
║ ║ │ │ │W = 0│W = 1║
║000║[BX+SI]│[BX+SI]+DISP 8│[BX+SI]+DISP 16│ AL │ AX ║
║001║[BX+DI]│[BX+DI]+DISP 8│[BX+DI]+DISP 16│ CL │ CX ║
║010║[BP+SI]│[BP+SI]+DISP 8│[BP+SI]+DISP 16│ DL │ DX ║
║011║[BP+DI]│[BP+DI]+DISP 8│[BP+DI]+DISP 16│ BL │ BX ║
║100║[SI] │[SI] +DISP 8│[SI] +DISP 16│ AH │ SP ║
║101║[DI] │[DI] +DISP 8│[DI] +DISP 16│ CH │ BP ║
║110║DISP 16│[BP] +DISP 8│[BP] +DISP 16│ DH │ SI ║
║111║[BX] │[BX] +DISP 8│[BX] +DISP 16│ BH │ DI ║
╚═══╩═══════╧══════════════╧═══════════════╧═══════════╝
Операнды для обработки могут быть записаны разными способами: без знака, со
знаком, и двоично кодированые десятичные числа (BCD, ДКД).
Последние разделяют на запакованные, по две цифры на байт, и не запакованые, по
одной цифре за байт (такие числа можно легко перевести в текстовый ASCII
формат).
ИНТЕРПРЕТАЦИЯ ЧИСЕЛ В РАЗНЫЙ ФОРМАТАХ
╔════════╦═══════════╤════════╤═══════════╤════════╗
║ БАЙТ ║БЕЗЗНАКОВОЕ│ЗНАКОВОЕ│НЕ ЗАП. ДКД│ЗАП. ДКД║
╠════════╬═══════════╪════════╪═══════════╪════════╣
║01101001║ 105 │ 105 │ Неверно │Неверно ║
║11010101║ 149 │ -107 │ Неверно │Неверно ║
║00000111║ 7 │ 7 │ 7 │ 07 ║
║10010110║ 150 │ -106 │ Неверно │ 96 ║
╚════════╩═══════════╧════════╧═══════════╧════════╝
Двоично кодированые десятичные числа записывается в четырёхбитном поле, где
верны значения от 0000B (0) до 1001B (9). Запакованный формат определяет два
таких поля в байте, а не запакованный формат определяет только одно поле,
расположенное к нижнему краю байта.
Стак - это специальная структура в памяти, куда последовательно записывается
информация и потом берётся в обратном порядке. Стак используется для сохранения
данных для возврата с обработчика прерываний или с подпрограммы-процедуры, а
также её можно использовать в самой программе. Стак идёт с верхних адресов к
нижним и состоит из шестнадцатибитных данных. Когда данные помещаются в стак,
указатель стека SP уменьшается на два, и по его новому адресу он туда
записывается. Когда данные берутся из стека, оно копируется по адресу в
указателе стека на место назначения и указатель уменьшается на два.
Адрес основы стека хранит сегментный регистр стака SS. Аддрес её верхушки
хранится в регистре SP. Также, вы можете использовать регистр BP для хранения
адреса своего рода основы стена, но на его работу он не влияет.
Когда будете определять размер стака, оставьте лишние несколько байт для
системного прерывания.
РАБОТА СТАКА
Аддрес ? Элемента
FFFEh ║Элемент ?+2║
FFFCh ║Элемент ?+1║
FFFAh ║Элемент ? 0║<─ SP
FFF8h ║Элемент ?-1║
FFF6h ║Элемент ?-2║
FFF4h ║Элемент ?-3║
Информация о том, как вычислять на процессоре, была взята из этих
источников:
- The 8086 Family User's Manual
Chapter 2: The 8086 And 8088 Central Processing Units