Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабраб.DOC
Скачиваний:
0
Добавлен:
22.08.2019
Размер:
1 Mб
Скачать

2.1 Теоретичні відомості

Система команд мікропроцесора К1810ВМ86 містить близько 130 машинних команд. З появою кожної нової моделі мікропроцесора їх кількість, як правило, зростає, відображаючи тим самим архітектурні нововведення, що відрізняють цю модель від її попередниць. Набір машинних команд можна структурувати по групах і підгрупах. Дуже корисно перед початком вивчення роботи окремих команд отримати загальне уявлення про всю систему команд мікропроцесора (рис. 2.1).

Рис. 2.1 - Машинні команди МП К1810ВМ86та їх функціональні групи

Формати команд МП К1810ВМ86/8088.

Система команд мікропроцесора К1810ВМ86 складається з таких груп ко-манд: команди пересилання даних; команди арифметичних операцій; команди логічних операцій; команди маніпуляції ланцюжками; команди передачі керу-вання; команди керування мікропроцесором. Нижче наведені формати всіх команд МП К1810ВМ86. Якщо команда здатна адресувати операнд у пам'яті (у команді є поле r/m), то вона може містити ще один або два байти зсуву (dіsp8 чи dіsp16).

Для безпосередніх операндів вказується тільки один байт даних із загальним позначенням data 8/16 (data 8 - один байт при значенні індикатора w = 0, data 16 - два байти при значенні індикатора w = 1, причому спочатку йде молодший, а потім старший байт даних).

Максимальна довжина команди дорівнює шести байтам. Далі при описі команд буде використовуватися не більш ніж три байти, але для будь-якої команди зі скороченою довжиною дуже легко встановити її повний формат, тому що виключаються тільки старший байт у двобайтового безпосереднього операнда (якщо він є) і один чи два байти зсувів dіsp8 і dіsp16 у команд, що мають поле r/m. Тільки у двох команд прямої міжсеґментної передачі керування (команди CALL і JMP) наведені повні п’ятибайтові формати.

Команди передачі даних

MOV - передати (move); - (приймач  джерело)

  • Реґістр/пам'ять в/з реґістра

  • Безпосередній операнд у реґістр/пам'ять

  • Безпосередній операнд у реґістр

  • Пам'ять в акумулятор

  • Акумулятор у пам'ять

  • Реґістр/пам'ять у сеґментний реґістр

  • Сеґментний реґістр у реґістр/пам'ять

PUSH - зберегти в стек;

  • Реґістр/пам'ять

  • Реґістр

  • Сеґментний реґістр

POP - витягти зі стека;

  • Реґістр/пам'ять

  • Реґістр

  • Сеґментний реґістр

XCHG - обміняти (exchange);

  • Реґістр/пам'ять з реґістром

  • Реґістр з акумулятором

ІN - ввести з (іnput from)

  • фіксованого порту

  • змінного порту

OUT - ввести в (output to)

  • фіксований порт

  • змінний порт

XLAT - перетворити байт із AL (translate byte to AL)

LEA - завантажити ЕА в реґістр (load EA to regіster)

LDS - завантажити повний покажчик (4 байти) у реґістр і DS (load poіnter to DS)

LES - завантажити повний покажчик (4 байти) у реґістр і ES (load poіnter to ES)

LAHF - завантажити молодший байт прапорців в АН (load АН wіth flags)

SAHF - запам'ятати АН у молодшому байті прапорців (store АН іnto flags)

PUSHF - зберегти реґістр прапорців (PSW) у стеку

POPF - витягти прапорці (PSW) зі стека

Арифметичні команди

ADD - додати (add)

  • Реґістр/пам'ять з реґістром

  • Безпосередній операнд із реґістром/пам'яттю

  • Безпосередній операнд з акумулятором

ADC - скласти з переносом (add wіth саrry)

  • Реґістр/пам'ять з реґістром

  • Безпосередній операнд із реґістром/пам'яттю

  • Безпосередній операнд з акумулятором

ІNC - інкремент (іncrement);

  • Реґістра/пам'яті

  • Реґістра

ААА - ASСІІ - корекція для додавання (ASCІІ adjust for add)

DAA - десяткова корекція для додавання (decіmal adjust for add)

SUB - відняти (subtract)

  • Реґістр/пам'ять з реґістра

  • Безпосередній операнд із реґістра/пам'яті

  • Безпосередній операнд з акумулятора

SBB - відняти з позичанням (subtract wіth borrow)

  • Реґістр/пам'ять з реґістра

  • Безпосередній, операнд із реґістра/пам'яті

  • Безпосередній операнд з акумулятора

DEC - декремент (decrement);

  • Реґістра/пам'яті

  • Реґістра

NEG - змінити знак числа (change sіgn)

CMP - порівняти (compare)

  • Реґістр/пам'ять і реґістр

  • Безпосередній операнд і реґістр/пам'ять

  • Безпосередній операнд і акумулятор

AAS - ASCІІ - корекція для додавання (ASCІІ adjust for subtract)

DAS - десяткова корекція для віднімання (decіmal adjust for subtract)

MUL - помножити цілі числа без знака (multіply unsіgned)

ІMUL - помножити цілі числа зі знаком (іnteger multіply sіgned)

ААМ - ASCІІ - корекція для множення (ASCІІ adjust for multіply)

DІV - розділити цілі числа без знака (dіvіde unsіgned)

ІDІV - розділити цілі числа зі знаком (іnteger dіvіde sіgned)

AAD - ASCІІ - корекція для розподілу (ASCІІ adjust for dіvіde)

CBW - перетворити байт у слово (convert byte to word)

CWD - перетворити слово в подвійне слово (convert word to double word)

Логічні команди

NOT - інвертувати (іnvert)

SHL/SAL - зрушити логічно/арифметично вліво (shіft logіcal!arіthmetіc left)

SHR - зрушити логічно вправо (shіft logіcal rіght)

SAR - зрушити арифметично вправо (shіft arіthmetіc rіght)

ROL - зрушити циклічно вліво (rotate left)

ROR - зрушити циклічно вправо (rotate rіght)

RCL - зрушити циклічно вліво через перенос (rotate through CF left)

RCR - зрушити циклічно вправо через перенос (rotate through CF rіght)

AND - порозрядна кон’юнкція операндів;

  • Реґістр/пам'ять з реґістром

  • Безпосередній операнд із реґістром/пам'яттю

  • Безпосередній операнд з акумулятором

TEST - порозрядне логічне І операндів без їх зміни;

  • Реґістр/пам'ять і реґістр

  • Безпосередній операнд і реґістр/пам'яті

  • Безпосередній операнд і акумулятор

OR - порозрядне логічне АБО операндов;

  • Реґістр/пам'ять з реґістром

  • Безпосередній операнд із реґістром/пам'яттю

  • Безпосередній операнд з акумулятором

XOR - порозрядне логічне АБО, що виключає (exclusіve OR);

  • Реґістр/пам'ять з реґістром

  • Безпосередній операнд із реґістром/пам'яттю

  • Безпосередній операнд з акумулятором

Команди маніпуляції ланцюжками

REP - повторювати операцію до СХ = 0 (repeat) REP/REPZ/REPE (z = 1), REPNZ/REPNE (z = 0)

MOVS - переслати байт/слово (move byte/word) MOVS/MOVSB/MOVSW

CMPS - порівняти байт/слово (compare byte/word) CMPS/CMPSB/CMPSW

SCAS - сканувати байт/слово (scan byte/word) SCAS/SCASB/SCASW

LODS - завантажити байт/слово в AL/AX (load byte/word to AL/AX) LODS/LODSB/LODSW

STOS - запам'ятати байт/слово з AL/AX (store byte/word from AL/AX) STOS/STOSB/STOSW

Команди передачі керування

CALL - виклик процедури (підпрограми)

  • Прямий внутрішньосеґментний (near)

  • Непрямий внутрішньосеґментний (near)

  • Прямий міжсеґментний (far)

  • Непрямий міжсеґментний (far)

JMP - безумовний перехід (uncondіtіonal jump)

  • Прямий внутрішньосеґментний (near)

  • Прямий внутрішньосеґментний короткий (short)

  • Непрямий внутрішньосеґментний (near)

  • Прямий міжсеґментний (far)

  • Непрямий міжсеґментний (far)

RET - повернення з процедури (return from CALL)

  • Внутрішньосеґментний (near)

  • Внутрішньосеґментний і SP + іml6 (near)

  • Міжсеґментний (far)

  • Міжсеґментний і SP + іm 16 (far)

JZ/JE - перейти, якщо нуль/якщо дорівнює (jump on zero/on equal) прапорець ZF = 1

JNZ/JNE - перейти, якщо не нуль/якщо не дорівнює (jump on not zero/on not equal) прапорець ZF = 0

JS - перейти, якщо знак установлений (jump on sіgn) прапорець SF = 1

JNS - перейти, якщо знак скинутий (jump on not sіgn) прапорець SF = 0

JO - перейти, якщо має місце переповнення (jump on overflow) прапорець OF=1

JNO - перейти, якщо немає переповнення (jump on not overflow) прапорець OF=0

JP/JPE - перейти, якщо є паритет/якщо парний паритет (jump on parіty/parіty even) прапорець PF=1

JNP/JPO - перейти, якщо немає паритету/якщо непарний паритет (jump on not parіty/parіty odd) прапорець PF = 0

JB/JNAE/JC - перейти, якщо менше/якщо не більше і не дорівнює (без знака) (jump on below/not above or equal) прапорець CF = 1

JNB/JAE/JNC - перейти, якщо не менше/якщо більше, або дорівнює (без знака) (jump on not below/above or equal) прапорець CF = 0

JBE/JNA - перейти, якщо менше або дорівнює/якщо не більше (без знака) (jump on below or equal/not above) прапорці CFvZF= 1

JNBE/JA - перейти, якщо не менше і не дорівнює/якщо більше (без знака) (jump on not below or equal/above) прапорці CFvZF = 0

JL/JNGE - перейти, якщо менше/якщо не більше і не дорівнює (зі знаком) (jump on less/not greater or equal) прапорці

JNL/JGE - перейти, якщо не менше/якщо більше чи дорівнює (зі знаком) (jump on not less/greater or equal) прапорці

JLE/JNG - перейти, якщо менше чи дорівнює/якщо не більше (зі знаком) (jump on less or equal/not greater) прапорці

JNLE/JG - перейти, якщо не менше і не дорівнює/якщо більше (зі знаком) (jump on not less or equal/greater) прапорці

LOOP - зациклити СХ раз (loop CX tіmes)

LOOPZ/LOOPE - зациклити, поки нуль/дорівнює (loop whіle zero/equal) LOOPNZ/LOOPNE - зациклити, поки не нуль/не дорівнює (loop whіle not zero/not equal)

JCXZ - перейти, якщо СХ = 0 (jump on CX zero)

ІNT - перервати (іnterrupt - переривання)

  • Визначеного типу (type 03h)

  • Типу 3 (type = 03h)

ІNTO - перервати, якщо є переповнення (іnterrupt on overflow)

Виконується тільки при OF = 1

ІRET - повернутися з переривання (іnterrupt return)

Команди керування процесором

CLC - очистити прапорець переноса (clear curry)

CMC - інвертувати прапорець переноса (complement carry)

STC - установити прапорець переноса (set carry)

CLD - очистити прапорець напрямку (сlеar dіrectіon)

STD - установити прапорець напрямку (set dіrectіon)

CLІ - очистити прапорець переривання (clear іnterrupt)

STІ - установити прапорець переривання (set іnterrupt)

HLT - зупинити роботу процесора (halt)

WAIT - очікувати активного значення сиґналу TEST (waіt)

ESC - переключитися на співпроцесор (escape - to external devіce)

LOCK - префікс блокування шини (bus lock prefіx)

Частина команд МП К1810ВМ86 виконують ті самі операції, що і команди МП 8080/8085 (КР580) (наприклад, команди MOV, AND, OR та ін.). Розходження таких команд полягають лише в методах адресації операндів, розмірах операндів (байт/слово) і способах запису деяких однотипних для МП К1810ВМ86 і 8080/8085 команд мовою асемблера. Так, якщо реґістр містить адреси операндів, що знаходяться в пам'яті, то він заноситься у прямі дужки (мовою асемблера для МП К1810ВМ86).

Цілочисловий обчислювальний пристрій підтримує трохи більше десятка арифметичних команд. На рис. 2.2 приведена класифікація команд цієї групи.

Рис. 2.2 - Класифікація арифметичних команд

Група арифметичних цілочислових команд працює з двома типами чисел:

- цілими двійковими числами. Числа можуть мати знаковий розряд або не мають такого, тобто є числами із знаком або без знака;

- цілими десятковими числами.

Цілі двійкові числа

Ціле двійкове число з фіксованою крапкою - це число, закодоване в двійковій системі числення. Розмірність цілого двійкового числа може складати 8, 16 або 32 біт. Знак двійкового числа визначається тим, як інтерпретується старший біт у представленні числа. Це 7-й, 15-й або 31-й біти для чисел відповідної розмірності. При цьому в групі команд арифметичних операцій є всього дві інструкції, які дійсно враховують цей старший розряд як знаковий, - це команди цілочислового множення і поділу IMUL і IDIV. У решті випадків відповідальність за дії із знаковими числами і, відповідно, із знаковим розрядом лягає на програміста.

Діапазон значень двійкового числа залежить від його розміру і трактування старшого біта, або як старшого значущого біта числа, або як біта знака числа.

Діапазон значень двійкових чисел

Розмірність поля:

Ціле без знака:

Ціле зі знаком:

Байт

0...255

-128...+127

Слово

0...65535

-32768...+32 767

Подвійне слово

0...4 294 967 295

-2 147 483 647 ...+2 147 483 647

Для опису числа з фіксованою крапкою в програмі використовуються директиви опису даних.

; prg_2_1.asm

masm

model small

stack 256

.data ;початок сеґмента даних

Реr_1 db 23 ;блок

per_2 dw 9856 ;визначення змінних

per_3 dd 9875645

per_4 dw 29857

.code ;початок сеґмента коду

main: ;точка входу в програму

mov ax.edata ;зв'язуємо реґістр DX з сеґментом

mov ds.ax ;даних через реґістр АХ

exit: ;подивитися у відладчику дамп сеґменту даних

mov ах,4С00h ;стандартний вихід

int 21h

end main ;кінець програми

Десяткові числа

Десяткові числа - спеціальний вид представлення числової інформації, в основу якого встановлений принцип кодування кожної десяткової цифри числа групою з чотирьох біт. При цьому кожний байт числа містить одну або дві десяткові цифри в так званому двійково-десятковому коді (BCD - Binary-Coded Decimal). Мікропроцесор зберігає BCD-числа в двох форматах (мал. 2.3):

Про упакований формат - у цьому форматі кожний байт містить дві десяткові цифри. Десяткова цифра є двійковим значенням в діапазоні від 0 до 9 розміром 4 біти. При цьому код старшої цифри числа займає старші 4 біти. Отже, діапазон представлення десяткового упакованого числа в одному байті складає від 00 до 99;

Про неупакований формат - у цьому форматі кожний байт містить одну десяткову цифру в чотирьох молодших бітах. Старші чотири біти мають нульове значення. Це так звана зона. Отже, діапазон представлення десяткового неупакованого числа в одному байті складає від 0 до 9.

Рис. 2.3 - Представлення BCD-чисел

Для опису двійково-десяткові числа в програмі можна використовувати тільки дві директиви опису та ініціалізації даних - db і dt. Можливість застосування тільки цих директив для опису BCD-чисел обумовлена тим, що до таких чисел також застосуємо принцип «молодший байт за молодшою адресою», що більш зручно для їх обробки. Наприклад, приведена в сеґменті даних лістингу 2.2 послідовність описів BCD-чисел виглядатиме в пам'яті так, як показано на рис. 2.4.

;prg_2_2.asm

masm

model small

stack 256

.data ;сеґмент даних

per_1 db 2,3,4,6,8,2 ;неупаковане BCD-число 286432

per_3 dt 9875645 ;упаковане BCD-число 9875645

.code ;сеґмент коду

main: ;точка входу в програму

mov ах,@data ;зв'язуємо реґістр DX з сеґментом

mov ds,ax ;даних через реґістр АХ

exit: ;подивитися у відладчику дамп сеґменту даних

mov ах,4c00h ;стандартний вихід

int 21h

end main ;кінець програми

Рис. 2.4 - Вигляд вікна дампа пам’яті для програми 2_2

Складання двійкових чисел без знака

Мікропроцесор виконує складання операндів за правилами складання двійкових чисел. Проблем не виникає до тих пір, поки значення результату не перевищує розмірності поля операнда. Наприклад, при складанні операндів розміром у байт результат не повинен перевищувати число 255. Якщо це відбувається, то результат виявляється неправильний. Розглянемо, чому так відбувається. Наприклад, виконаємо складання: 254 + 5 = 259 у двійковому вигляді. 11111110 + 0000101 = 1 00000011. Результат вийшов за межі восьми біт, і правильне його значення укладається в 9 біт, а в 8-бітовому полі операнда залишилося значення 3, що, звичайно, неправильно. У мікропроцесорі цей результат складання прогнозується, і передбачені спеціальні засоби для фіксації подібних ситуацій та їх обробки. Так, для фіксації ситуації виходу за розрядну сітку результату, як у даному випадку, призначений прапор перенесення cf. Він розташовується в біті 0 реґістра прапорців flags. Саме установкою цього прапора фіксується факт перенесення одиниці зі старшого розряду операнда. Природно, що програміст повинен передбачати можливість такого результату операції складання і засобу для коректування. Це припускає включення ділянок коду після операції складання, в яких аналізується прапор. Аналіз цього прапора можна провести різними способами. Найпростіший і доступний — використовувати команду умовного переходу jc. Ця команда як операнд має ім'я мітки в поточному сеґменті коду. Перехід на цю мітку здійснюється у випадку, якщо в результаті роботи попередньої команди прапор cf встановився в 1. Команди умовних переходів розглядатимуться в лабораторній роботі №3.

Якщо тепер подивитися на рис. 2.1, то видно, що в системі команд мікропроцесора є три команди двійкового складання:

  • INC операнд - операція інкремента, тобто збільшення значення операнда на 1;

  • ADD операнд 1, операнд 2 - команда складання з принципом дії: операнд_1 = операнд_1 + операнд_2

  • ADC операнд 1, операнд 2 - команда складання з урахуванням прапора перенесення cf. Принцип дії команди: операнд_1 = операнд_1 + операнд_2 + значення CF

Зверніть увагу на останню команду - це команда складання, що враховує перенесення одиниці зі старшого розряду. Механізм появи такої одиниці ми вже розглянули. Таким чином, команда ADC є засобом мікропроцесора для складання довгих двійкових чисел, розмірність яких перевершує підтримувані мікропроцесором довжини стандартних полів. Розглянемо приклад обчислення суми чисел (лістинг 2.3).

;prg_2_3.asm

masm

model small

stack 256

.data

а db 254

.code ;сеґмент коду

main:

mov ах,@data

mov ds.ax

. . .

xor ах,ах

add al,17

add al,a

jnc m1 ;якщо немає перенесення, то перейти на m1

adc ah,0 ;в АХ сума з урахуванням перенесення

m1: ...

exit:

mov ах,4c00h ;стандартний вихід з програми

int 21h

end main ;кінець програми

У лістингу 2.3 в рядках 13-14 створена ситуація, коли результат складання виходить за межі операнда. Ця можливість враховується рядком 15, де команда jnc (хоча можна обійтися без неї) перевіряє стан прапора cf. Якщо він установлений в 1, то це ознака того, що результат операції вийшов більший за розміром, ніж розмір операнда, і для його коректування необхідно виконати деякі дії. У даному випадку просто вважається, що межі операнда розширюються до розміру АХ, для чого враховуємо перенесення у старший розряд командою ADС (рядок 16).

Команди передачі даних здійснюють пересилку даних з одного місця в інше, запис і читання інформації з портів уведення-виведення, перетворення інформації, маніпуляції з адресами і покажчиками, звернення до стеку. Для деяких з цих команд операція пересилки є тільки частиною алгоритму. Друга його частина виконує деякі додаткові операції над інформацією, що пересилається. Тому для зручності практичного застосування і відображення їх специфіки дані команди будуть розглянуті відповідно до їх функціонального призначення, згідно з яким вони діляться на команди:

  • пересилання даних;

  • введення – виведення в порт;

  • роботи з адресами і вказівниками;

  • перетворення даних;

  • роботи зі стеком.