08 семестр / Книги и методические указания / Методы к лабам / методичка8086
.docКраткое описание микропроцессора К181ВМ86
Микропроцессор имеет разрядность шины данных 16 бит, шины адреса 20 бит. Схема процессора представлена на рис.1:
Рис.1
В процессоре имеется восемь 16-разрядных регистров общего назначения: AX – аккумулятор, BX – базовый регистр, CX – счетчик, DX – регистр данных, SP – указатель стека, BP – указатель базы, SI – индекс источника, DI – индекс приемника. Обычно регистры AX, BX, CX и DX используются для хранения данных, регистры SP, BP, SI, DI - для адресной информации. Для регистров AX, BX, CX, DX возможно также раздельное использование младших и старших байтов (AH, AL, BH, BL, CH, CL, DH, DL).
Регистр флагов F:
FH |
FL |
||||||||||||||
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
x |
x |
x |
x |
OF |
DF |
IF |
TF |
SF |
ZF |
x |
AF |
x |
PF |
x |
CF |
Арифметические флаги:
CF – флаг переноса, фиксирует значение переноса из старшего бита результата при сложении, либо заема при вычитании, а также значение выдвигаемого бита при сдвиге операнда
PF – флаг паритета, фиксирует четное число единиц в младшем байте результата
AF – флаг вспомогательного переноса, фиксирует перенос из младшей тетрады (используется при выполнении десятичной коррекции)
ZF – флаг нулевого результата
SF – флаг знака, равен старшему разряду результата при работе со знаковой арифметикой
OF – флаг переполнения
Флаги управления:
DF – флаг направления обработки цепочек команд: DF=0 – в сторону больших адресов, DF=1 – в сторону меньших.
IF – флаг разрешения прерываний: IF=0 прерывания запрещаются, IF=0 – разрешаются.
TF – флаг трассировки: TF=1 – пошаговый режим работы.
Блок сегментных регистров состоит из четырех 16-разрядных регистров CS, SS, DS, ES, которые хранят базовые адреса сегментов памяти: CS – сегмент команд, SS – сегмент стека, DS – сегмент данных, ES – дополнительный сегмент (обычно также используется для хранения данных).
Указатель команд IP хранит смещение следующей команды в текущем кодовом сегменте.
Организация памяти в процессоре
Память представляет собой набор последовательно расположенных байтов, каждый из которых имеет 20-разрядный адрес. Два смежных байта могут рассматриваться как 16-битное слово, адресом слова считается адрес младшего байта (он меньше, чем адрес старшего байта). Адресное пространство имеет емкость 1 Мбайт и разбито на сегменты емкостью 64 Кбайт, которые характеризуются базами. Начальные адреса четырех текущих сегментов записываются в сегментные регистры CS, SS, DS, ES; для перехода к другой области памяти достаточно сменить содержимое сегментного регистра.
Каждая ячейка памяти характеризуется логическим и физическим адресом. Физический адрес представляет собой 20-разрядное число, однозначно определяющее положение ячейки в памяти. Логический адрес ячейки состоит из двух 16-битовых значений: базы сегмента и смещения внутри сегмента относительно базы (определяет расстояние от начала сегмента до этой ячейки). Для пересчета логического адреса в физический база сегмента сдвигается влево на 4 бит и суммируется со смещением. Если при суммировании возникает бит переноса, он игнорируется; таким образом, после ячейки памяти с адресом FFFFF идет ячейка с адресом 00000, то есть возникает кольцевая организация памяти (она также присуща каждому сегменту в отдельности).
Обращение к памяти.
К каждому сегменту памяти обращение осуществляется отдельно. Прямая передача информации между сегментами невозможна, для этого необходимо использовать регистры общего назначения.
Для обращения к памяти используются 4 регистра: BX, SI, DI, BP, а также смещение, задаваемое непосредственной величиной: d8 – 8 бит или d16 – 16 бит. Комбинируя эти регистры и смещения внутри квадратных скобок [ ], можно задействовать любую ячейку памяти.
[BX + SI] [BX + DI] [BP + SI] [BP + DI] |
[SI] [DI] d16 [BX] |
[BX + SI + d8] [BX + DI + d8] [BP + SI + d8] [BP + DI + d8] |
[SI + d8] [DI + d8] [BP + d8] [BX + d8] |
[BX + SI + d16] [BX + DI + d16] [BP + SI + d16] [BP + DI + d16] |
[SI + d16] [DI + d16] [BP + d16] [BX + d16] |
Для примера примем DS=100, BX=30, SI=70. В этом случае адрес [BX+SI]+25 будет преобразован процессором в следующий физический адрес: 100*16+30+70+25=1725.
По умолчанию сегментный регистр DS используется всегда, кроме режимов с регистром BP, в этом случае используется сегментный регистр SS.
Адреса задаются в шестнадцатеричном коде.
Структура команд процессора
Двухоперандные команды:
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Код операции |
d |
s |
md |
reg |
r/m |
||||||||||
disp L |
disp H |
Бит d указывает направление передачи: d=1 – передача операнда или результата операции в регистр, указанный в поле reg, d=0 – передеча из регистра reg. Бит s показывает формат данных: s=1 – слово, s=0 - байт
Поле reg определяет второй операнд, обязательно находящийся в регистре; поле r/m (регистр/память) определяет первый операнд, который может находиться в регистре или памяти.
reg, r/m |
s=0 |
s=1 |
reg, r/m |
s=0 |
s=1 |
000 |
AL |
AX |
100 |
AH |
SP |
001 |
CL |
CX |
101 |
CH |
BP |
010 |
DL |
DX |
110 |
DH |
SI |
011 |
BL |
BX |
111 |
BH |
DI |
Поле md показывает, содержится первый операнд в памяти или в регистре, а в случае расположения операнда в памяти определяет вариант использования смещения disp, которе может находиться в третьем и четвертом байтах команды:
md=00 – операнд содержится в памяти, disp=0 (смещение отсутствует)
md=01 – операнд содержится в памяти, disp=disp L (команда содержит 8-битовое смещение, которое расширяется со знаком до 16 бит)
md=10 – операнд содержится в памяти, disp=disp H, disp L (команда содержит 16-битовое смещение)
md=11 – операнд содержится в регистре
Однооперандные команды:
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Код операции |
s |
md |
Код операции |
r/m |
|||||||||||
disp L |
disp H |
Могут содержать от 2хдо 4х байт в зависимости от s и md
Команды с непосредственной адресацией:
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Код операции |
s |
w |
md |
Код операции |
r/m |
||||||||||
disp L |
disp H |
||||||||||||||
data L |
data H |
Могут содержать до 3х слов. Поля s и w показывают, как используются последние 2 байта команды:
s |
w |
|
x |
0 |
data=data L (8 разрядов) |
0 |
1 |
data=data H, dataL (16 разрядов) |
1 |
1 |
data=data L (расширение до 16-разрядного слова со знаком) |
Описание эмулятора
Для выполнения работы используется эмулятор процессора emu8086. Окно программы имеет следующий вид:
Рис.2
Текст программы набирается в поле редактора построчно. Комментарии записываются после знака «;».
Числа допускается записывать в любой системе счисления, при этом после числа ставится обозначение: h – шестнадцатеричное, b – двоичное, o – восьмеричное, например: 1ah, 101b, 71o. Числа без обозначения считаются десятичными. Если в записи шестнадцатеричного числа старшим разрядом является буква (A..F), то перед ней необходимо поставить «0».
Для создания циклов, условных и безусловных переходов используются команды LOOP, JMP, JA, JC и т.п. и метки вида:
label:
В конце программы рекомендуется ставить команду RET
Полный список и описание всех команд процессора можно найти в меню help: Documentation and tutorials/8086 Instruction Set.
Для запуска набранной программы используется кнопка emulate на панели инструментов. При этом открывается окно эмулятора (рис.3):
Рис.3
В открывшемся окне эмулятора можно управлять режимом работы программы: кнопка single step позволяет использовать пошаговый режим, run – запустить программу на выполнение. В левой части окна выводятся значения всех регистров общего назначения, их можно просматривать и изменять по ходу выполнения программы; кроме того, двойной щелчок мыши по окошку со значением регистра позволяет вывести на экран окно расширенного просмотра значений регистров в различных кодировках. В центральной части окна эмулятора находятся номера и содержимое ячеек памяти (подсвечиваются ячейки, соответствующие следующей строке программы), в правой части – обработанный текст выполняемой программы. Содержимое регистра флагов можно просматривать и изменять с помощью кнопки flags в левом нижнем углу. При помощи регулятора step delay можно устанавливать задержку между выполнением шагов программы.
Порядок выполнения работы
1.Ознакомьтесь с работой эмулятора:
-
запустите программу emu8086.exe
Рис.4
В окне приветствия (рис.4) выберите вариант new, далее (рис.5) выберите empty workspace.
Рис.5
-
для примера напишите программу занесения числа 1234h в регистр AX:
Рис.5
-
запустите ее нажатием клавиши F5 или кнопки emulate на панели инструментов, откроются окна эмулятора (рис.3) и кода программы (рис.7):
Рис.6
-
запустите программу на выполнение в пошаговом режиме и проследите за изменением значения регистров AX и IP (содержимое изменившиеся при выполнении команды регистров выделяется синим цветом), затем перезагрузите программу нажатием кнопки reload и выполните ее с помощью кнопки run
-
просмотрите содержимое регистра флагов, нажав кнопку flags; измените значение флага паритета PF на 1
2. Напишите программы, выполняющие следующие действия:
1. Команда загрузки и пересылки данных (команда MOV)
-
загрузить регистр CX числом ABCDh
-
переслать содержимое CX в регистр AX
-
загрузить ячейку памяти текущего сегмента без смещения (смещение 0) числом FFh
-
задать в качестве базы сегмента DS=200h, предварительно записав это число в регистр DX; загрузить ячейку 02100h числом AAh (смещение 100h)
-
записать в регистр BX смещение 200h и загрузить ячейку 02200h числом BBh (смещение [BX])
-
записать в регистр SI индекс 20 и загрузить ячейку 02220h числом CCh, используя сегмент с базой DS=200h и смещение [BX+SI]
-
загрузить ячейку 02222h числом DDh, используя сегмент с базой DS=200h и смещение [BX+SI+2]
2. Однооперандные команды
-
загрузить регистр DX числом 5
-
увеличить содержимое регистра DX на единицу (команда INC)
-
перенести содержимое регистра DX в ячейку памяти 01100h
-
уменьшить содержимое ячейки 01100h на единицу (команда DEC)
-
инвертировать содержимое регистра DX (команда NOT)
3. Двухоперандные команды
а) Арифметические операции:
-
сложить числа 1Bh и 1Ch, используя регистры BX и CX, результат записать в CX (команда ADD)
-
вычесть из содержимого регистра CX константу 10b, результат записать в AX (команда SUB)
-
содержимое регистра AX разделить на 10h, предварительно записав делитель в регистр BX (команда DIV)
-
остаток от деления (находится в регистре DX) умножить на 2 (команда MUL)
б) Логические операции:
-
записать в ячейку памяти 01100h число 101101b, в регистр AX число 110001b, выполнить для них логическое умножение, результат записать в ячейку 01100h (команда AND)
-
записать в регистр AX число 111010b, выполнить логическое сложение между содержимым AX и ячейки памяти 01100h, результат записать в регистр AX (команда OR)
-
выполнить операцию сумма по модулю 2 для содержимого регистра AX и числа 001001b (команда XOR)
4. Команды сдвига
-
занести в регистр BX число 25h, умножить его на 2, используя операцию арифметического сдвига (команда SAL)
-
занести в ячейку памяти 01200h число 40h, разделить его на 4, используя операцию арифметического сдвига (команда SAR)
5. Команды управления программой
а) Цикл (команда LOOP)
-
занести в регистр CX число 10 (количество повторений цикла)
-
установить в качестве базы сегмента DS=0100h, занести в регистр BX смещение 0101h
-
установить метку начала выполнения цикла вида label:
-
тело цикла: занести число AAh в ячейку, смещение которой относительно базы DS указано в регистре BX, и увеличить содержимое BX на 1
-
после записи тела цикла перейти по метке label
После выполнения программы число AAh должно быть записано в ячейки с 01101h по 0110Ah
б) Условный переход (команда JC)
-
занести число FFh в регистр AL
-
увеличить содержимое регистра AL на AAh
-
если бит переноса не равен единице, записать в регистр BX число ABCDh, иначе завершить программу (переход по метке к концу программы)
в) Безусловный переход (команда JMP)
-
занести в ячейку 01100h число С3h (код команды RET)
-
написать программу сложения чисел Ah и Bh, используя регистры DL и DH
-
для окончания выполнения программы перейти по адресу 01100h
Команда |
Операнды |
Описание |
Пример |
Регистр флагов |
||||||||||||
ADD |
REG, memory memory, REG REG, REG memory, immediate REG, immediate |
Сложение
Алгоритм: операнд 1=операнд1+операнд2 |
Сложение 5 и -3:
MOV AL, 5 ; AL = 5 ADD AL, -3 ; AL = 2 RET |
|
||||||||||||
AND |
REG, memory memory, REG REG, REG memory, immediate REG, immediate |
Логическое И, результат сохраняется в операнд1
Применяются правила: 1 AND 1 = 1 1 AND 0 = 0 0 AND 1 = 0 0 AND 0 = 0 |
Сложение по И чисел 1100001b и 11011111b:
MOV AL, 'a' ; AL = 01100001b AND AL, ; AL = 01000001b ('A') RET |
|
||||||||||||
DEC |
REG memory |
Декрементация
Алгоритм операнд=операнд-1 |
Уменьшение 255 на1:
MOV AL, 255 ; AL = 0FFh (255 or -1) DEC AL ; AL = 0FEh (254 or -2) RET |
|
||||||||||||
DIV |
REG memory |
Деление (без знака)
Алгоритм: 1)операнд - байт: AL=AX/операнд, AH = остаток 2)операнд – слово: AX=(DX AX)/операнд, DX =остаток |
Деление 203 на 4:
MOV AX, 203 ; AX = 00CBh MOV BL, 4 DIV BL ; AL = 50 (32h), AH = 3 RET |
|
||||||||||||
HLT |
- |
Прекращение выполнения программы |
MOV AX, 5 HLT |
|
||||||||||||
INC |
REG memory |
Инкрементация
Алгоритм: операнд=операнд+1 |
Увеличение 4 на 1:
MOV AL, 4 INC AL ; AL = 5 RET |
|
||||||||||||
JC |
Метка |
Короткий переход, если бит переноса равен 1.
Алгоритм: если CF = 1 то переход
|
Проверка наличия бита переноса:
include 'emu8086.inc' ORG 100h MOV AL, 255 ADD AL, 1 JC label1 PRINT 'no carry.' JMP exit label1: PRINT 'has carry.' exit: RET |
|
||||||||||||
JMP |
Метка 4-хбайтный адрес |
Безусловный переход (перемещение к другой части программы). 4-х байтный адрес может вводиться в виде: 1234h:5678h, первое значение – база сегмента, второе – смещение.
Алгоритм: переход по метке (всегда) |
Выполнить прыжок через 2 строки, напечатать “Got Here!”, если прыжок выполнен:
include 'emu8086.inc' ORG 100h MOV AL, 5 JMP label1 PRINT 'Not Jumped!' MOV AL, 0 label1: PRINT 'Got Here!' RET |
|
||||||||||||
LOOP |
метка |
Декрементация CX, переход к метке, если CX не равен нулю
Алгоритм: CX=CX -1 если CX <> 0 то переход иначе продолжить |
Напечатать “loop” 5 раз:
include 'emu8086.inc' ORG 100h MOV CX, 5 label1: PRINTN 'loop!' LOOP label1 RET |
|
||||||||||||
MOV |
REG, memory memory, REG REG, REG memory, immediate REG, immediate
SREG, memory memory, SREG REG, SREG SREG, REG |
Копирование операнда2 в операнд1
Команда MOV не может: 1.устанавливать значение регистров CS и IP. 2.копировать значение одного сегментного регистра в другой сегментный регистр (необходимо сначала скопировать в регистр общего назначения). 3.копировать непосредственное значение в сегментный регистр
Алгоритм: операнд1=операнд2 |
Занесение числа ABh в регистр AL, пересылка его в ячейку памяти с адресом 01101h:
MOV AL, 0ABh MOV BX, 0100h MOV DS, BX MOV [BX+1], AX RET |
|
||||||||||||
MUL |
REG memory |
Умножение (без знака)
Алгоритм: 1)операнд - байт: AX = AL * операнд 2)операнд - слово: (DX AX) = AX*операнд |
Умножение 200 на 4:
MOV AL, 200 MOV BL, 4 MUL BL ; AX = 0320h (800) RET |
CF=OF=0, если старший бит результата равен нулю |
||||||||||||
NOP |
- |
Нет операции |
Ничего не делать 2 раза:
NOP NOP RET |
|
||||||||||||
NOT |
REG memory |
Инвертирует все биты операнда
Алгоритм: 1.если бит равен 1, то приравнять бит 0 2.если бит равен 0, то приравнять бит 1 |
Инвертировать число 11011b:
MOV AL, 00011011b NOT AL ; AL = 11100100b RET |
|
||||||||||||
OR |
REG, memory memory, REG REG, REG memory, immediate REG, immediate |
Логическое ИЛИ между всеми битами двух операндов. Результат сохраняется в первом операнде.
Применяются правила: 1 OR 1 = 1 1 OR 0 = 1 0 OR 1 = 1 0 OR 0 = 0 |
Сложение по ИЛИ 1000001b и 100000b:
MOV AL, 'A' ; AL = 01000001b OR AL, 00100000b ; AL = 01100001b ('a') RET |
|
||||||||||||
RET |
- immediate |
Возврат из процедуры
Алгоритм: 1.вытолкнуть из стека: IP 2.если операнд – константа: SP=SP+operand |
Вызов процедуры занесения числа 1234h в регистр AX, увеличение его на 1
ORG 100h ; for com file CALL p1 ADD AX, 1 RET p1 PROC MOV AX, 1234h RET p1 ENDP |
|
||||||||||||
SAL |
memory, immediate REG, immediate memory, CL REG, CL |
Арифметический сдвиг операнда 1 влево. Число сдвигов устанавливается операндом 2 (константа либо значение регистра CL)
Алгоритм: 1.Сдвиг всех бит влево, старший бит записывается в CF. 2.В качестве младшего бита записывается 0. |
Сдвиг числа E0 влево 1 раз:
MOV AL, 0E0h ; AL = 11100000b MOV CL, 1 SAL AL, CL ; AL = 11000000b, CF=1. RET |
OF=0 если знак операнда1 сохраняется. |
||||||||||||
SAR |
memory, immediate REG, immediate memory, CL REG, CL |
Арифметический сдвиг операнда1 вправо. Число сдвигов устанавливается операндом2 (константа либо значение регистра CL)
Алгоритм: 1.Сдвиг всех бит вправо, младший бит заносится в CF. 2.Старший бит (бит знака) устанавливается в то же значение, что было раньше. |
Сдвиг числа E0 вправо 2 раза (бит знака равен 1):
MOV AL, 0E0h ; AL = 11100000b SAR AL, 2 ; AL = 11111000b, CF=0. RET
Сдвиг числа 4C вправо 1 раз (бит знака равен 0):
MOV BL, 4Ch ; BL = 01001100b SAR BL, 1 ; BL = 00100110b, CF=0 RET |
OF=0 если знак операнда1 сохраняется. |
||||||||||||
SUB |
REG, memory memory, REG REG, REG memory, immediate REG, immediate |
Вычитание
Алгоритм: операнд1=операнд1-операнд2 |
Вычитание 2 из 5:
MOV AL, 5 SUB AL, 2 ; AL = 3 RET
|
|
||||||||||||
XOR |
REG, memory memory, REG REG, REG memory, immediate REG, immediate |
Сумма по модулю 2 (исключающее ИЛИ) между всеми битами двух операндов. Результат сохраняется в первом операнде.
Применяются правила: 1 XOR 1 = 0 1 XOR 0 = 1 0 XOR 1 = 1 0 XOR 0 = 0 |
Сумма по модулю два чисел 111b и 10b:
MOV AL, 00000111b XOR AL, 00000010b ; AL = 00000101b RET
|
|