Програмування контролера пріоритетних переривань

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати

Міністерство освіти Російської Федерації
Волзький університет ім. Татіщева
Факультет «Інформатика і телекомунікації»
Кафедра «Інформатика та системи управління»
ЗАТВЕРДЖУЮ
Проректор з навчальної роботи
_____________Е.В. Філатова
«_____»____________ 200 г .
МЕТОДИЧНЕ ВКАЗІВКА
для проведення лабораторної роботи з теми
''Програмування контролера пріоритетних переривань''
по курсу''Організація ЕОМ''
для студентів спеціальностей 220100, 071900
Тольятті

Створення та компіляція програм на асемблері
Процес розробки програми на асемблері складається з п'яти етапів:
1. Створення файлу з вихідним текстом програми в будь-якому текстовому редакторі. Розширення файлу з вихідним текстом може бути. Asm, або. Txt, або. Doc.
2. Створення об'єктного модуля. У середовищі DOS або NORTON або FAR в командному рядку набираєте наступну команду:
tasm name.asm
або
tasm.exe name.asm name.obj
name.asm файл із вихідним текстом програми. При цьому файли tasm.exe і name.asm повинні знаходиться в одному каталозі. Після запуску цієї команди ми отримуємо об'єктний файл з розширенням. Obj. Якщо об'єктний файл не з'явився, то в програмі містяться помилки. Перелік помилок можна подивитися, відключивши панелі (ctrl + o або Ctrl + f1 і ctrl + f2).
3. Створення виконавчого файлу. У командному рядку набираємо наступну команду:
tlink name.obj
або
tlink.exe name.obj name exe
При цьому файли tlink.exe і name.obj повинні знаходиться в одному каталозі. Після запуску цієї команди ми отримуємо запускную файл з розширенням. Exe. Якщо запускную файл не з'явився в цьому каталозі, то в даному каталозі не вистачає деяких бібліотек. Перелік файлів можна подивитися, відключивши панелі (ctrl + o або Ctrl + f1 і ctrl + f2).
4. Тестування програми. Запустіть виконавчий файл.
5. Покрокова налагодження. У командному рядку набираємо наступну команду:
td name. exe

Структура програми на асемблері
Model small; модель програми, або ж кількість пам'яті на сегмент
. Data           ; Сегмент даних
; Опис змінних
. Stack 100 h           ; Сегмент стека
. Code; сегмент даних
; Процедури, макрокоманди
main:
mov ax, @ data
   mov      ds, ax    
; Основна програма
mov      ax, 4 c 00 h
   int 21 h       ; Вихід з програми
end main
Директиви резервування пам'яті
Для опису простих типів даних у програмі використовуються спеціальні директиви резервування та ініціалізації даних, які, по суті, є вказівками транслятору на виділення певного обсягу пам'яті. Якщо проводити аналогію з мовами високого рівня, то директиви резервування та ініціалізації даних є визначеннями змінних.
Машинного еквівалента цих директив немає; просто транслятор, обробляючи кожну таку директиву, виділяє необхідну кількість байт пам'яті і при необхідності ініціалізує цю область деяким значенням.

Директиви резервування та ініціалізації даних простих типів мають формат:

Рис. 1. Директиви опису даних простих типів
На рис. 1 використані наступні позначення:
·? Показує, що вміст поля не визначено, тобто при завданні директиви з таким значенням вираження вміст виділеної ділянки фізичної пам'яті змінюватися не буде. Фактично, створюється неініціалізованих мінлива;
· Значення ініціалізації - значення елементу даних, яке буде занесено в пам'ять після завантаження програми. Фактично, створюється ініціалізований змінна, в якості якої можуть виступати константи, рядки символів, константні та адресні вираження в залежності від типу даних. Детальна інформація наведена у додатку 1;
· Вираз - ітеративна конструкція з синтаксисом, описаним на рис. 5.17. Ця конструкція дозволяє повторити послідовне занесення в фізичну пам'ять вирази в дужках n разів.
· Ім'я - деяке символічне ім'я мітки або комірки пам'яті в сегменті даних, що використовується в програмі.
· Db - резервування пам'яті для даних розміром 1 байт. Директивою db можна задавати такі значення:
o вираз або константу, приймаючу значення з діапазону:
для чисел зі знаком -128 ... +127; для чисел без знака 0 ... 255;
o символьну рядок з одного або більше символів. Рядок полягає в лапки. У цьому випадку визначається стільки байт, скільки символів в рядку.
· Dw - резервування пам'яті для даних розміром 2 байти.
o вираз або константу, приймаючу значення з діапазону:
для чисел зі знаком -32 768 ... 32 767; для чисел без знака 0 ... 65 535;
o вираз, що займає 16 або менше біт, в якості якого може виступати зміщення в 16-бітовому сегменті або адреса сегмента;
o 1 - або 2-байтове рядок, укладена в лапки.
· Dd - резервування пам'яті для даних розміром 4 байти.
o вираз або константу, приймаючу значення з діапазону:
для чисел зі знаком -2147483648 ... +2 147 483 647;
для чисел без знака 0 ... 4294967295;
o відносне або адресне вираз, що складається з 16-бітового адреси сегмента і 16-бітового зсуву;
o рядок довжиною до 4 символів, укладену в лапки.
· Df - резервування пам'яті для даних розміром 6 байт;
· Dp - резервування пам'яті для даних розміром 6 байт. Директивами df і dp можна задавати такі значення:
o вираз або константу, приймаючу значення з діапазону:
для чисел зі знаком -2147483648 ... +2 147 483 647;
для чисел без знака 0 ... 4294967295;
o відносне або адресне вираз, що складається з 32 або менше біт (для i80386) або 16-менш біт (для молодших моделей мікропроцесорів Intel);
o адресне вираз, що складається з 16-бітового сегмента і 32-бітового зсуву;
o рядок довжиною до 6 байт, укладену в лапки.
· Dq - резервування пам'яті для даних розміром 8 байт.
відносне або адресне вираз, що складається з 32 або менше біт
o константу зі знаком з діапазону -2 63 ... 2 63-1;
o константу без знака з діапазону 0 ... 2 64-1;
o рядок довжиною до 8 байт, укладену в лапки.
· Dt - резервування пам'яті для даних розміром 10 байт.
відносне або адресне вираз, що складається з 32 або менше біт
o адресне вираз, що складається з 16-бітового сегмента і 32-бітового зсуву;
o константу зі знаком з діапазону -2 79 ... 2 79-1;
o константу без знака з діапазону 0 ... 2 80-1;
o рядок довжиною до 10 байт, укладену в лапки;
o упаковану десяткову константу в діапазоні 0 ... 99 999 999 999 999 999 999.
Дуже важливо усвідомити собі порядок розміщення даних у пам'яті. Він безпосередньо пов'язаний з логікою роботи мікропроцесора з даними. Мікропроцесори Intel вимагають проходження даних в пам'яті за принципом: молодший байт по молодшому адресою.
Для ілюстрації цього принципу розглянемо приклад 1, в якому визначимо сегмент даних. У цьому сегменті даних наведено кілька директив опису простих типів даних.
Приклад SEQ Приклад \ * ARABIC 1. Приклад використання директив резервування та ініціалізації даних. Результатом роботи даної програми буде рядок 'Привіт, все працює'
model      small
. Stack 100 h
. Data
mes db 'Привіт, все працює','$'; визначення рядка
perem_1 db 0ffh; визначення контстанти
perem_2 dw 3a7fh; визначення контстанти
perem_3 dd 0f54d567ah; визначення контстанти
mas db 10 dup (''); визначення порожнього масиву з 10 байт
adr dw perem_3; мінлива adr містить адресу
; Всередині сегмента змінної perem_3
a_full dd perem_3; мінлива a_full містить повний
; Адресу змінної perem_3
fin db 'Кінець сегмента даних програми $'
. Code
start:
; Занесення в сегментний регістр адреси сегмента даних
mov ax, @ data
mov         ds, ax    
mov ah, 09h
mov dx, offset mes
int 21h; висновок на екран рядки mes
mov         ax, 4 c 00 h
int 21 h       ; Вихід з програми
end    start
Закінчення роботи програми супроводжується повним вивантаженням програми з оперативної пам'яті, це здійснюється функцією 4с00h переривання int 21h.
Все що в даній програмі виділено жирним шрифтом обов'язково при написанні будь-якої програми.
При написанні програм на асемблері регістр букв не важливий.

Організація вводу-виводу на асемблері

Введення-виведення даних в комп'ютер здійснюється за допомогою різних периферійних пристроїв. Завантаження процесора з різними периферійними відбувається через систему переривань. Для введення-виведення даних служить переривання int 21h.
Основна послідовність дій при використанні переривань 2lh (DOS):
1. Помістити номер функції в регістр ah.
2. Помістити передаються функції параметри в певні регістри (вони наведені при описі кожної функції).
3. Викликати переривання 2lh (DOS) командою int 21h
4. Витягти результати роботи функцій з певних регістрів. Які саме регістри і що вони містять після повернення управління з функції програмі користувача, вказується при описі кожної функції.
Переривання DOS 2lh призначене для надання програмісту різних послуг з боку операційної системи. Цими послугами є набір функцій. Яка саме функція повинна бути викликана, вказується числом в регістрі ah.
Деякі функції DOS (int 21 h)
Призначення
Номер функції
Вхід
Вихід
Введення символу з очікуванням і ехосопровожденіем
ah-0lh
аl-ASCII-код символу
Висновок символу
ah-02h
dl-ASCII-код символу
Висновок символу на принтер
ah-05h
dl-ASCII-код символу
Введення символу з очікуванням і без ехосопровожденія
ah-07h
ah-08h
al-ASCII-код символу (функція 08h при введенні перевіряє, чи не натиснуто чи CTRL-BREAK)
Висновок рядка на екран
ah-09h
ds: dx = адреса рядка з символом <$> на кінці
Введена рядок у буфері
Введення рядка з клавіатури
ah-0ah
ds: dx-anpec буфера з форматом:
1 байт - розмір буфера для введення (формує користувач);
2 байт - число фактично введених символів (заповнює система по закінченню введення - натискання клавіші Enter (Odh)). Символ 0dh не враховується у другому байті буфера;
3 байт і далі - введена рядок з символом 0dh на кінці
Перевірка стану буферу клавіатури
ah - 0bh
al = 0 - буфер порожній
al = 0ffh - в буфері є символи
Приклад SEQ Приклад \ * ARABIC 2. Програма введення символу з клавіатури
model small
. Stack 100h
. Data
. Code
start:; занесення в сегментний регістр адреси сегмента даних
mov ax, @ data
mov ds, ax
; Поміщаємо в регістр ah номер функції, яка вводить символ
mov ah, 01h
int 21h; вводимо символ з клавіатури
; Символ введений з клавіатури знаходиться в регістрі al
mov         ax, 4 c 00 h
int 21 h       ; Вихід з програми
end    start
Приклад SEQ Приклад \ * ARABIC 3. Програма виведення символу на екран
model      small
. Stack 100 h
. Data
f db 'ф'; поміщаємо в змінну f виведений символ
. Code
start:; занесення в сегментний регістр адреси сегмента даних
mov ax, @ data
mov ds, ax
; Поміщаємо в регістр ah номер функції, яка виводить символ
mov ah, 02h
mov dl, f; поміщаємо в dl символ
int 21h; виводимо символ на екран
mov         ax, 4 c 00 h
int 21 h       ; Вихід з програми
end    start
Приклад SEQ Приклад \ * ARABIC 4. Висновок рядка на екран
model small
. Stack 100h
. Data
f db 'рядок виводу $'
; F - строкова змінна, яка обов'язково закінчується знаком $
. Code
start:; занесення в сегментний регістр адреси сегмента даних
mov ax, @ data
mov ds, ax
; Поміщаємо в регістр ah номер функції, яка виводить рядок на екран
mov ah, 09h
mov dx, offset f; поміщаємо в dx адреса рядка, яку виводимо
int 21h; виводимо рядок
mov         ax, 4 c 00 h
int 21 h       ; Вихід з програми
end    start
Організація обчислень

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

Система команд мікропроцесора містить п'ять логічних команд. Ці команди виконують логічні операції над бітами операндів. Розмірність операндів повинна бути однакова. Як операнди можуть використовуватися, регістри, комірки пам'яті (змінні) та безпосередні операнди (числа). Будь-яка логічна команда змінює значення наступних прапорів of, sf, zf, pf, cf (переповнення, знак, нуля, паритет, перенесення)
and операнд_1, операнд_2 - операція логічного множення (І - сполучення).
and ah, 0a1h; ah: = ah70ah
and bx, cx; bx: = bx7cx
and dx, x1; dx: = dx7x1
Команда and може застосовуватися для скидання певних бітів в 0 або для визначення значення деяких бітів.
Наприклад, необхідно 5й біт числа знаходиться в bl встановити в 0, інші біти не чіпати.
and bl, 11011111b або and bl, 0cfh
Якщо необхідно визначити чому дорівнює 5й біт, то
and bl, 00100000b або and bl, 20h
У результаті якщо в регістрі bl в 5м бите був 0, то після виконання цієї команди ми отримаємо нульовий результат, обнулив весь регістр. Якщо ж у регістрі bl в 5м бите була 1, то ми отримаємо не нульовий результат.
or операнд_1, операнд_2 - операція логічного додавання (АБО - диз'юнкцію)
or al, x1; al: = al & x1
or eax, edx; eax: = eax & edx
or dx, 0fa11h; dx: = dx & 0fa11h
Команда or може застосовуватися для установки певних біт в 1. Наприклад, необхідно встановити в одиницю 4й і 7й біти регістра ah.
or ah, 10010000b або or ah, 90h
xor операнд_1, операнд_2 - Операція логічного виключає складання (виключає АБО АБО-НЕ). Команда може застосовується для з'ясування того, які біти в операндах розрізняються мул для інвертування стану заданих біт в операнде_1. Наприклад, необхідно визначити чи збігається вміст регістрів ax і dx
xor ax, dx; якщо вміст збігається то в регістрі ах ми отримаємо
; Нульовий результат, інакше не нульовий результат.
xor bh, 10b; інвертувати 1й біт в регістрі bh
test операнд_1, операнд_2 - операція "перевірити" (способом логічного множення). Команда виконує поразрядно логічну операцію І над бітами операндів операнд_1 і операнд_2. Стан операндів залишається тим самим, змінюються лише прапори zf, sf, і pf, що дає можливість аналізувати стан окремих бітів операнда без зміни їх стану.
not операнд - операція логічного заперечення. Команда виконує поразрядное інвертування (заміну значення на протилежне) кожного біта операнда. Результат записується на місце операнда.
not ax; ax: =
Приклад SEQ Приклад \ * ARABIC 5. Логічне складання двох однобайтовим чисел.
model small
. Stack 100h
. Data
x1 db 0c2h; перший доданок
x2 db 022h; другий доданок
y db? ; Мінлива результату
. Code
start:
mov         ax, @ data
mov         ds, ax
mov al, x1; в al поміщаємо перший доданок
or al, x2; здійснюємо логічне додавання, результат у al
mov y, al; поміщаємо результат на місце
mov ax, 4c00h
int 21h
end start
Наступні дві команди дозволяють здійснити пошук першого встановленого в 1 біта операнда. Вони з'явилися у 486 процесорі.
bsf операнд_1, операнд_2 - сканування біт операнда_2 від молодшого до старшого в пошуках першого біта встановленого в 1. Якщо такий знайдеться, то в операнд_1 заноситися номер цього біта в целочисленном форматі.

Приклад:
mov al, 02 h
bsf     bx, al; bx: = 1, тому що 1й біт регістра al = 1
bsr операнд_1, операнд_2 - сканування біт операнда_2 від старшого до молодшого у пошуках першого біта встановленого в 1. Якщо такий знайдеться, то в операнд_1 заноситися номер цього біта в целочисленном форматі.
Приклад:
mov al, 82 h
bsr     bx, al; bx: = 6, тому що 6й біт регістра al = 1
Якщо операнд_2 дорівнює 0 то вищеописані дві команди встановлюють прапор нуля zf в 1, інакше в 0.

Арифметичні операції над цілими двійковими числами

Додавання двійкових чисел
inc операнд - операція інкремента, тобто збільшення значення операнда на 1;
inc ax; ax: = ax +1
inc x1; х1: = х1 +1
add ОП1, ОП2 - команда складання з принципом дії: ОП1 = ОП1 + ОП2 (addition)
add al, bl
add ax, 0fe2h
add ebx, x1 +2
add x1, 0fh
add x2, ax
adc ОП1, ОП2 - команда складання з урахуванням прапора перенесення cf. ОП1 = ОП1 + ОП2 + знач_cf

Віднімання двійкових чисел
dec операнд - операція декремента, тобто зменшення значення операнда на 1;
dec cx; cx: = cx-1
dec x
sub операнд_1, операнд_2 - команда вирахування; її принцип дії:
операнд_1 = операнд_1 - операнд_2
sub al, bl; al: = al-bl
sub ax, x1
sub x2, dx
sub eax, 0f35h
sub x2, 22h
sbb операнд_1, операнд_2 - команда вирахування з урахуванням позички (прапора cf):
операнд_1 = операнд_1 - операнд_2 - значеніе_cf
Приклад SEQ Приклад \ * ARABIC 6. Складання двох однобайтовим чисел.
model      small
. Stack 100 h
. Data
x1 db 0c2h; перший доданок
x2 db 022h; другий доданок
y db? ; Результат
. Code
start:
mov         ax, @ data
mov         ds, ax
mov al, x1; поміщаємо в al перший доданок
add al, x2; складаємо х1 і х2
mov y, al; поміщаємо результат на місце
mov ax, 4c00h
int 21h
end start

Множення двійкових чисел

mul множітель_1 - операція множення двох цілих чисел без урахування знака
Алгоритм роботи:
Команда виконує множення двох операндів без урахування знаків. Алгоритм залежить від формату операнда команди і вимагає явного вказівки місцеположення тільки одного співмножники, який може бути розташований в пам'яті або в регістрі. Розташування друге сомножителя фіксоване і залежить від розміру першого співмножники. Розташування результату також залежить від розміру першого співмножники.
mul dl; ax: = al * dl, dl-множітель_1, al-множітель_2
mul x1; dx: ax = ax * 0ad91h, x1 word-множітель_1, ax-множітель_2
mul ecx; edx: eax = eax * ecx, ecx-множітель_1, eax-множітель_2
в результаті множення може виникнути ситуація коли результат за розміром перевищить 16 або 32 біта, тоді старша частина результату множення заноситися в dx або edx відповідно.
imul множітель_1 - операція множення двох цілочисельних двійкових значень зі знаком

Розподіл двійкових чисел

div дільник - виконання операції ділення двох двійкових беззнакових значень
Алгоритм роботи:
Для команди необхідно завдання двох операндів - діленого і дільника. Ділене задається неявно, і розмір його залежить від розміру дільника, який вказується в команді. Розташування результату залежить від розміру дільника.
div dl; ah: al = ax / dl, ax-ділене, dl-дільник, ah-приватне, al-залишок
div x1; ax: dx = dx: ax/0ad91h, dx: ax-ділене, x1 word-дільник,
; Ax-приватне, dx-залишок
div ecx; eax: edx = edx: eax / ecx, edx: eax-ділене, ecx-дільник,
; Eax-приватне, edx-залишок
idiv дільник - операція ділення двох двійкових значень зі знаком
Приклад SEQ Приклад \ * ARABIC 7. Множення двох однобайтовим чисел.
model small
. Stack 100h
. Data
x1 db 78; перший множник
yl db? ; Перший байт результату
yh db? ; Другий байт результату
. Code
start:
mov         ax, @ data
mov         ds, ax
xor ax, ax; очищаємо регістр ax
mov al, 25; поміщаємо в al другий множене
mul x1
jnc m1; якщо немає переповнювання, переходимо на мітку m1
mov yh, ah; інакше старший байт результату поміщаємо в yh
m1:
mov yl, al; результат поміщаємо на місце
mov ax, 4c00h
int 21h
end start
Приклад SEQ Приклад \ * ARABIC 8. Поділ двох однобайтовим чисел.
model small
. Stack 100h
. Data
x1 db 6; дільник
yl db? ; Залишок
yh db? ; Приватне
. Code
start:
mov         ax, @ data
mov         ds, ax
xor ax, ax; очищаємо регістр ax
mov ax, 25; поміщаємо в al ділене
div x1
mov yh, ah; поміщаємо приватне на місце
mov yl, al; поміщаємо залишок на місце
mov ax, 4c00h
int 21h
end start
ASCII коди і їх інтепрітація
Введення інформації з клавіатури та виведення її на екран здійснюється в символьному вигляді, тобто будь-який символ надається в ASCII кодах. Причому на один символ йде один ASCII код. На два символи - два ASCII коду, і т.д. Будь-яке число, що вводиться з клавіатури і виводиться на екран, представляється послідовністю ASCII кодів.
Табл.1. ASCII коди цифр
Символ шістнадцятковій цифри
Двійкова тетрада
ASCII код
(Двійкове подання)
Різниця
0
0000
30h (0011 0000)
30h
1
0001
31h (0011 0001)
30h
2
0010
32h (0011 0010)
30h
3
0011
33h (0011 0011)
30h
4
0100
34h (0011 0100)
30h
5
0101
35h (0011 0101)
30h
6
0110
36h (0011 0110)
30h
7
0111
37h (0011 0111)
30h
8
1000
38h (0011 1000)
30h
9
1001
39h (0011 1001)
30h
A a
1010
41h (0100 0001) 61h (0110 0001)
37h 57h
B b
1011
42h (0100 0010) 62h (0110 0010)
37h 57h
C c
1100
43h (0100 0011) 63h (0110 0011)
37h 57h
D d
1101
44h (0100 0100) 64h (0110 0100)
37h 57h
E e
1110
45h (0100 0101) 65h (0110 0101)
37h 57h
F f
1111
46h (0100 0110) 66h (0110 0110)
37 h 57 h
Розглянемо послідовність дій для перетворення чисел у їх ASCII код і навпаки.
Введення інформації з клавіатури:
1. Введення символу з клавіатури, один ASCII код знаходиться в dl. Заздалегідь не відомо, що це за число від 0 до 9 або від а до f.
Cmp dl, 040 h
Jb       m 1; якщо ASCII код менше 40 h значить ввели цифру від 0 до 9,
; Переходимо на мітку m 1
Cmp dl, 047 h; інакше ввели букву, заголовну чи маленьку?
Jb      m 2; якщо ввели заголовну, переходимо на m 2, інакше виконуємо
; Далі за програмою
sub    dl, 057 h; в dl отримуємо із символів число a .. f h
jmp   m 3; переходимо на m 3 щоб не виконувати зайвих обчислень
m 2: sub    dl, 037 h; в dl отримуємо із символів число a .. f h
jmp    m 3
m 1: sub    dl, 030 h; в dl отримуємо із символів число 0 .. 9 h
m 3:
Далі наведено оптимізований код перетворення числа з ASCII кодів. Подумайте в чому різниця.
Cmp dl, 040 h
Jb m 1
Cmp dl, 047 h
Jb m2
Sub dl, 020h
m2: sub dl, 07h
m1: sub dl, 030h
2. Введення рядка, відрізняється тільки тим, що таке порівняння треба проводити з кожним елементом, тобто треба організувати цикл і звернення до кожного елементу. Розглянемо пізніше.
Виведення інформації на екран
0
1. Припустимо що, число, яке ми хочемо вивести, знаходиться в регістрі bl. Висновок символу здійснюється з регістра dl, 02 функція INT 21 H. Число може бути одне або двозначне, наприклад 7 h або 5 Fh. Для універсальності програми будемо вважати, що треба вивести двозначне число. А для цього треба отримати окремо десятки і одиниці, і отримати для них два ASCII коду.
; Двозначне число яке хочемо вивести знаходиться в bl
mov dl, bl; поміщаємо число в регістр dl
; Зрушуємо вміст dl на 4 біта вправо, щоб отримати окремо десятки
shr    dl, 4
and    bl, 0 fh; отримуємо окремо одиниці
cmp   dl, 0 ah; порівнюємо dl з ah
jb      m 1; якщо менше переходимо на m 1
add dl, 07h
m1: add dl, 30h
mov ah, 02h
int 21h
mov dl, bl
cmp   dl, 0 ah; порівнюємо dl з ah
jb m2
add dl, 07h
m2: add dl, 30h
int 21 h
Спробуйте самі розібратися в наведеному шматочку коду.
SHAPE \ * MERGEFORMAT
5
F
7

5

F
3
5
6
6
ASCII код 5Fh
Підпис: ASCII код 5Fh

Команди передачі управління
За принципом дії, команди мікропроцесора, що забезпечують організацію переходів у програмі, можна розділити на три групи:
1. Команди безумовної передачі керування:
- Команда безумовного переходу; jmp
- Виклику процедури і повернення з процедури; call, ret
- Виклику програмних переривань та повернення з програмних переривань. Int, iret
2. Команди умовної передачі управління:
- Команди переходу по результату команди порівняння cmp;
- Команди переходу за станом певного прапора;
- Команди переходу по вмісту регістру ecx / cx.
3. Команди управління циклом:
- Команда організації циклу з лічильником ecx / cx;
- Команда організації циклу з лічильником ecx / cx з можливістю дострокового виходу з циклу по додатковому умові.
jmp адрес_перехода - безумовний перехід без збереження інформації про точку повернення. Аналог goto.

Умовні переходи

Команди умовного переходу мають однаковий синтаксис:
jcc метка_перехода
Мнемокод всіх команд починається з "j" - від слова jump (стрибок), cc - визначає конкретна умова, аналізоване командою. Що стосується операнда метка_перехода, то ця мітка може знаходиться лише в межах поточного сегмента коду, міжсегментний передача управління в умовних переходах не допускається.
Для того щоб прийняти рішення про те, куди буде передано керування командою умовного переходу, попередньо має бути сформовано умова, на підставі якого і буде прийматися рішення про передачу управління. Джерелами такої умови можуть бути:
- Будь-яка команда, що змінює стан арифметичних прапорів;
- Команда порівняння cmp, що порівнює значення двох операндів;
- Стан регістра ecx / cx.
jcxz метка_перехода (Jump if cx is Zero) - перехід, якщо cx нуль;
jecxz метка_перехода (Jump Equal ecx Zero) - перехід, якщо ecx нуль.

Умовні переходи по вмісту прапорів

Назва прапора
Номер біта в eflags / flag
Команда умовного переходу
Значення прапора для здійснення переходу
Прапор переносу cf
1
jc
cf = 1
Прапор парності pf
2
jp
pf = 1
Прапор нуля zf
6
jz
zf = 1
Прапор знака sf
7
js
sf = 1
Прапор переповнення of
11
jo
of = 1
Прапор переносу cf
1
jnc
cf = 0
Прапор парності pf
2
jnp
pf = 0
Прапор нуля zf
6
jnz
zf = 0
Прапор знака sf
7
jns
sf = 0
Прапор переповнення of
11
jno
of = 0
Приклад SEQ Приклад \ * ARABIC 9. Визначте, чи рівні два числа вводяться користувачем з клавіатури. Визначити рівність чисел можна використовуючи віднімання, якщо різниця досліджуваних чисел дорівнює 0, то вони рівні.
model small
. Stack 100h
. Data
s1 db 'числа рівні $'
s2 db 'числа не рівні $'
. Code
start:
mov ax, @ data
mov ds, ax
mov ah, 01h
int 21h; ввели перше число
mov dl, al; посилаємо в dl перше число
int 21h; ввели друге число
sub al, dl; порівняли числа
jnz m1; якщо отримали не 0 результат, то на мітку m1
mov dx, offset s1; інакше виводимо рядок s1, про те що числа рівні.
jmp m2
m1: mov dx, offset s2; числа не рівні, виводимо рядок s2
m2: mov ah, 09h
int 21h; висновок інформаційну рядок
mov ax, 4c00h
int 21h
end start
Команда порівняння cmp
cmp операнд_1, операнд_2 - порівнює два операнда і за результатами порівняння встановлює прапори. Команда порівняння cmp має цікавий принцип роботи. Він абсолютно такий же, як і у команди віднімання sub. Єдине, чого вона не робить - це запис результату віднімання на місце першого операнда.
Алгоритм роботи:
-Виконати віднімання (операнд1-операнд2);
-В залежності від результату встановити прапори, операнд1 і операнд2 не змінювати (тобто результат не запам'ятовувати).
Умовні переходи після команд порівняння
Типи операндів
Мнемокод команди умовного переходу
Критерій умовного переходу
Значення прапорів для осществленія переходу
Будь-які
je
операнд_1 = операнд_2
zf = 1
Будь-які
jne
операнд_1 <> операнд_2
zf = 0
Зі знаком
jl / jnge
операнд_1 <операнд_2
sf <> of
Зі знаком
jle / jng
операнд_1 <= операнд_2
sf <> of or zf = 1
Зі знаком
jg / jnle
операнд_1> операнд_2
sf = of and zf = 0
Зі знаком
jge / jnl
операнд_1 => операнд_2
sf = of
Без знака
jb / jnae
операнд_1 <операнд_2
cf = 1
Без знака
jbe / jna
операнд_1 <= операнд_2
cf = 1 or zf = 1
Без знака
ja / jnbe
операнд_1> операнд_2
cf = 0 and zf = 0
Без знака
jae / jnb
операнд_1 => операнд_2
cf = 0
Приклад SEQ Приклад \ * ARABIC 10. Визначте, чи рівні два числа вводяться користувачем з клавіатури.
model small
. Stack 100h
. Data
s1 db 'числа рівні $'
s2 db 'числа не рівні $'
. Code
start:
mov ax, @ data
mov ds, ax
mov ah, 01h
int 21h; ввели перше число
mov dl, al
mov ah, 01h
int 21h; ввели друге число
cmp al, dl; порівняли числа
jne m1
mov dx, offset s1
jmp m2
m1: mov dx, offset s2
m2: mov ah, 09h
int 21h; висновок інформаційну рядок
mov ax, 4c00h
int 21h
end start
Приклад SEQ Приклад \ * ARABIC 11. Дани три числа, знайти серед них максимальне.
model small
. Stack 100h
. Data
s1 db 'Максимальна кількість', 10,13, '$'
x1 db 34
x2 db 56
x3 db 45
. Code
start:
mov ax, @ data
mov ds, ax
mov dx, offset s1
mov ah, 09h
int 21h; висновок інформаційну рядок
; Знаходимо максимальне число
mov dl, x1; dl: = x1
cmp dl, x2; порівнюємо х1 і х2
ja m1; якщо х1> х2, то на m1
mov dl, x2; інакше dl: ​​= x2
m1: cmp dl, x3; порівнюємо dl і х2
ja m2; якщо dl> х3 то на m2
mov dl, x3
; В dl знаходиться найбільший максимальний елемент
m2: mov ah, 02h
int 21h; виводимо максимальний елемент
mov ax, 4c00h
int 21h
end start
 
Організація циклів
loop метка_перехода (Loop) - повторити цикл
Робота команди полягає у виконанні наступних дій:
- Декремента регістру ecx / cx;
- Порівняння регістру ecx / cx з нулем:
- Якщо (ecx / cx)> 0, то управління передається на мітку переходу;
- Якщо (ecx / cx) = 0, то управління передається на наступну після loop команду
Організація циклу:
mov cx, кількість циклів
м1: тіло циклу
  loop m 1
loope / loopz метка_перехода (Loop till cx <> 0 or Zero Flag = 0) - повторити цикл, поки cx <> 0 або zf = 0.
loopne / loopnz метка_перехода (Loop till cx <> 0 or Not Zero flag = 0) - повторити цикл поки cx <> 0 або zf = 1
Недолік команд організації циклу loop, loope / loopz і loopne / loopnz в тому, що вони реалізують тільки короткі переходи (від -128 до +127 байт).
Організація вкладених циклів:
mov c х, n; в сх заносимо кількість ітерацій зовнішнього циклу
m 1:
Зовнішній цикл
Підпис: Зовнішній цикл push cx
...
mov cx, n 1, у сх заносимо кількість ітерацій внутрішнього циклу
                            m 2:
тіло внутрішнього циклу
                            loop m 2
...
                            pop cx
                            loop m 1
Приклад SEQ Приклад \ * ARABIC 12. Напишіть програму підрахунку у = 1 +2 +3 + ... + n, n не більше 10000.
model small
. Stack 100h
. Data
yb dd?
ym dw?
s1 db 'введіть n', 10,13, '$'
. Code
start:
mov ax, @ data
mov ds, ax
mov dx, offset s1
mov ah, 09h
int 21h
mov cx, 3
m: shl bx, 4
mov ah, 01h
int 21h вводимо n в регістр bx
sub ax, 130h
add bx, ax
loop m

mov cx, bx
xor dx, dx
xor al, al
m1: add dx, cx вважаємо у
jnc m2
mov al, 1
m2: loop m1
cmp al, 1
je m3
mov ym, dx
m3: mov yb, edx
mov ax, 4c00h
int 21h

end start

Команди обробки рядків

Ланцюжок - це послідовність елементів, розмір яких може бути байт, слово, подвійне слово. Вміст цих елементів може бути будь-яке - символи, числа. У системі команд мікропроцесора є сім операцій-примітивів обробки ланцюжків. Кожна з них реалізується в мікропроцесорі трьома командами, в свою чергу, кожна з цих команд працює з відповідним розміром елемента - байтом, словом або подвійним словом.
Типовий набір дій для виконання будь-якої цепочечной команди:
à Встановити значення прапора df залежно від того, в якому напрямку будуть оброблятися елементи ланцюжка - в напрямку зростання або зменшення адрес.
à Завантажити покажчики на адреси ланцюжків у пам'яті в пари регістрів ds: (e) si і es: (e) di.
à Завантажити в регістр ecx / cx кількість елементів, що підлягають обробці.
à Видати цепочечную команду з префіксом повторень.
Пересилання ланцюжків
movs адрес_пріем, адрес_істочніка (MOVe String) - переслати ланцюжок;
movsb MOVe String Byte) - переслати ланцюжок байт;
movsw (MOVe String Word) - переслати ланцюжок слів;
movsd (MOVe String Double word) - переслати ланцюжок подвійних слів.
Команда копіює байт, слово або подвійне слово з ланцюжка джерела, в ланцюжок приймача. Розмір пересилаються елементів асемблер визначає, виходячи з атрибутів ідентифікаторів. Приміром, якщо ці ідентифікатори були визначені директивою db, то пересилатися будуть байти, якщо ідентифікатори були визначені за допомогою директиви dd, то пересилання підлягають подвійні слова.
Для ланцюгових команд з операндами типу movs адрес_пріемніка, адрес_істочніка, не існує машинного аналога. При трансляції в залежності від типу операндів транслятор перетворює її в одну з трьох машинних команд: movsb, movsw або movsd.
Сама по собі команда movs пересилає тільки один елемент, виходячи з його типу, і модифікує значення регістрів esi / si і edi / di. Якщо перед командою написати префікс rep, то однією командою можна переслати до 64 Кбайт даних. Число пересилаються елементів має бути додано в лічильник - регістр cx (use16) або ecx (use32).
Приклад SEQ Приклад \ * ARABIC 13. Пересилання рядків командою movs
MODEL small
. STACK 256
. Data
source db 'Тестована рядок','$'; рядок-джерело
dest db 19 DUP (''); рядок-приймач
. Code
main:
mov ax, @ data; завантаження сегментних регістрів
mov ds, ax; налаштування регістрів DS і ES на адресу сегменту даних
mov es, ax
cld; скидання прапора DF - обробка рядка від початку до кінця
lea si, source; завантаження в si зсуву рядка-джерела
lea di, dest; завантаження в DS зсуву рядка-приймача
mov cx, 20; для префікса rep - лічильник повторень (довжина рядка)
rep movs dest, source; пересилання рядки
lea dx, dest
mov ah, 09h; висновок на екран рядка-приймача
int 21h
mov ax, 4c00h
int 21h
end main
Операція порівняння ланцюжків
cmps адрес_пріемніка, адрес_істочніка (CoMPare String) - порівняти рядки;
cmpsb (CoMPare String Byte) - порівняти рядок байт;
cmpsw (CoMPare String Word) - порівняти рядок слів;
cmpsd (CoMPare String Double word) - порівняти рядок подвійних слів.
Алгоритм роботи команди cmps полягає в послідовному виконанні віднімання (елемент ланцюжка-джерела - елемент ланцюжка-одержувача) над черговими елементами обох ланцюжків. Принцип виконання вирахування командою cmps аналогічний команді порівняння cmp. Вона, так само, як і cmp, виробляє віднімання елементів, не записуючи при цьому результату, і встановлює прапори zf, sf та of.
Після виконання вирахування чергових елементів ланцюжків командою cmps, індексні регістри esi / si і edi / di автоматично змінюються відповідно до значення прапора df на значення, рівне розміром елемента порівнюваних ланцюжків.
Операція сканування ланцюжків
scas адрес_пріемніка (SCAning String) - сканувати ланцюжок;
scasb (SCAning String Byte) - сканувати ланцюжок байт;
scasw (SCAning String Word) - сканувати ланцюжок слів;
scasd (SCAning String Double Word) - сканувати ланцюжок подвійних слів
Ці команди здійснюють пошук шуканого значення, яке знаходиться в регістрі al / ax / eax. Принцип пошуку той же, що і в команді порівняння cmps, тобто послідовне виконання віднімання
(Вміст регістра_аккумулятора - вміст очередного_элемента_цепочки).
У залежності від результатів віднімання проводиться установка прапорів, при цьому самі операнди не змінюються.
Завантаження елемента ланцюжка в акумулятор
lods адрес_істочніка (LOaD String) - завантажити елемент з ланцюжка в регістр-акумулятор al / ax / eax;
lodsb (LOaD String Byte) - завантажити байт з ланцюжка в регістр al;
lodsw (LOaD String Word) - завантажити слово з ланцюжка в регістр ax;
lodsd (LOaD String Double Word) - завантажити подвійне слово з ланцюжка в регістр eax.
Ця операція-примітив дозволяє витягти елемент ланцюжка і помістити його в регістр-акумулятор al, ax або eax. Цю операцію зручно використовувати разом з пошуком (скануванням) з тим, щоб, знайшовши потрібний елемент, витягти його (наприклад, для зміни).
Перенесення елемента з акумулятора в ланцюжок
stos адрес_пріемніка (STOre String) - зберегти елемент з регістра-акумулятора al / ax / eax в ланцюжку;
stosb (STOre String Byte) - зберегти байт з регістра al в ланцюжку;
stosw (STOre String Word) - зберегти слово з регістра ax в ланцюжку;
stosd (STOre String Double Word) - зберегти подвійне слово з регістра eax в ланцюжку.
Ця операція-примітив дозволяє провести дію, зворотне команді lods, тобто зберегти значення з регістра-акумулятора в елементі ланцюжка. Цю операцію зручно використовувати разом з операцією пошуку (сканування) scans і завантаження lods, з тим, щоб, знайшовши потрібний елемент, витягнути його в регістр і записати на його місце нове значення.

Приклад SEQ Приклад \ * ARABIC 14 . Підрахуйте кількість незбіжних елементів в заданій і введеної рядках.
Model small
. Stack 100h
. Data
s0 db 'Задана рядок $'
s1 db 16; задаємо кількість символів у введеної рядку + знак Enters
s2 db?, 16 dup (?);? - під кількість введених символів, масив під рядок
s3 db 10,13, 'Кількість незбіжних елементів - $'; інформац. рядок
. Code
mov ax, @ data
mov ds, ax; задаємо адресу сегменту даних
mov es, ax; налаштовуємо адресу сегменту даних, де зберігається рядок приймач
; Вводимо порівнювану рядок
mov ah, 0ah
mov dx, offset s1
int 21h
; Виводимо інформаційну рядок
mov ah, 09h
mov dx, offset s3
int 21h
; Порівнюємо рядки, один елемент із заданої рядка порівнюємо з усіма; елементами введеного рядка
mov dl, '0 ', у dl ascii-код 0
mov cx, 16; в сх кількість елементів в заданій рядку
mov si, offset s0; в si адресу вказаного рядка-джерела
z_str: push cx; зберігаємо лічильник зовнішніх циклів у стеку
lodsb; завантажуємо елемент із заданої рядки в акумулятор, al
mov di, offset s2; в di адресу введеного рядка-приймача
mov cl, s2 [di]; в cl кількість введених елементів
xor ch, ch; Обнуляємо ch, тому що в циклі лічильником є ​​сх
inc di; на перший елемент строки-приймача
repe scacb
; Скануємо рядок-приймач до тих пір поки елемент не = вмісту al,
; Або поки не скінчиться рядок
jz m1; zf = 1, якщо в рядку зустрівся елемент = вмісту al
inc dl; вважаємо кількість не збігаються елементів
m1:; внутрішній цикл по введеної рядку закінчився
pop cx; відновлюємо вміст сх
loop z_str
; Після виходу з циклу в dl кількість не збігаються елементів
mov ah, 02h
int 21h; виводимо dl
mov ax, 4c00h
int 21h
end
Масиви
Організація одновимірних масивів
Всі елементи масиву розташовуються в пам'яті послідовно
Опис елементів масиву
mas db 1,2,3,4,5
mas dw 5 dup (0)

Доступ до елементів масиву

mov ax, mas [si]; в si номер елемента в масиві
mov mas [si], ax; в di номер елемента в масиві
Приклад SEQ Приклад \ * ARABIC 15. Знайти в рядку хоча б один нульовий елемент
model          small
. Stack 100 h
. Data
bufer dw 25; формую розмір буфера для введення рядка
mas db 25 dup (''); формую буфер
subj 1 db 'у рядку знайдений нульовий елемент', '$'
subj 2 db 'у рядку не знайдено нульовий елемент', '$'
. Code
main:
mov ax, @ data
mov   ds, ax
; Введення рядка з клавіатури
mov ah, 0ah
mov dx, offset bufer
int 21h
; Пошук нульового елемента
xor    si, si
mov cl, mas [si]; завантажуємо в сх кількість елементів у рядку
mov al, 030 h; в ax завантажуємо ASCII код нуля
m1: inc si
cmp al, mas [si]
je m2
; Якщо в рядку знайдемо нульовий елемент, то виходимо з циклу на висновок subj 1
loop m 1
; Нормальний вихід з циклу означає що в рядку немає нульових елементів
lea dx, subj2
jmp m3
m2: lea dx, subj1
m3: mov ah, 09h
int 21h
mov ax, 4c00h
int 21h
end main
Організація двовимірних масивів
! Спеціальних засобів для опису двовимірних масивів в асемблері немає!
Двовимірний масив описується також як і одновимірний масив, відмінність полягає у трактуванні розташування елементів. Нехай послідовність елементів трактується як двовимірний масив, розташований по рядках, тоді адресу елемента [i, j] обчислюється так
База + коліч_елем_строке * размер_елем * I + j
Приклад SEQ Приклад \ * ARABIC 16. Знайти максимальний елементи в кожному рядку масиву 5 * 7
model small
. Stack 100h
. Data
mas dw 5 dup (7 dup (0))
max dw 0
subj db 'введіть рядок ', 13,10,' $ '
. Code
main:
mov ax, @ data
mov ds, ax
; Заповнення масиву
xor si, si
mov cx, 05h
incykl: push cx
mov ah, 09h
lea dx, subj
int 21 h; висновок інформаційного рядка
mov   cx, 07 h
mov ah, 01h
outcykl: int 21 h; введення елементів масиву
mov   mas [si], ax; розміщення елементів на місці
inc si
inc si
loop outcykl
pop    cx
loop   incykl
; Пошук максимального / мінімального в рядках
xor si, si
mov cx, 05h
s1t: push cx
mov cx, 06h
mov dx, mas [si]
maxi: add si, 2
cmp dx, mas [si]
ja min1; якщо менше то переходимо
mov dx, mas [si]
min1: loop maxi
; Висновок максимального
mov ah, 02h
int 21h
pop cx
loop s1t
mov ax, 04c00h
int 21h
end main
Процедури. Дії
Процедура, часто звана підпрограмою, - це правильним чином оформлена сукупність команд, яка будучи одноразово описана, при необхідності може бути викликана в будь-якому місці програми. Процедура представляє собою групу команд для вирішення конкретної підзадачі і володіє засобами отримання управління з точки виклику завдання більш високого рівня і повернення управління в цю точку. У найпростішому випадку програма може складатися з однієї процедури.
Опис процедури може розміщується в будь-якому місці програми, але таким чином щоб на неї випадковим чином не потрапило управління:
- На початку програми, до першої виконуваної команди;
- В кінці, після команди повертає керування операційній системі;
- Проміжний варіант, тіло процедури розташовується всередині іншої процедури або основної програми. У цьому випадку необхідно передбачити обхід процедури командою jmp;
- В іншому модулі.
Синтаксис опису процедури:
Імя_процедури PROC заголовок
Команди, директиви тіло процедури
[Ret] повернення з процедури
[Імя_процедури] ENDP кінець процедури
Виклик процедури здійснюється командою
CALL [модифікатор] імя_процедури
Команда call передає управління за адресою із символічною адресою імя_процедури, із збереженням в стеку адреси повернення, команди наступного після команди call.
Повернення з процедури здійснюється по команді
RET [число]
Команда ret зчитує адреса повернення з стека і завантажує його в регістри cs і ip / eip, повертаючи таким чином управління команді, наступної за командою call. Число - необов'язковий параметр, що позначає кількість елементів, що видаляються з стека при поверненні з процедури. Розмір елемента залежить від використовуваної моделі сегментації 32 або 16 розрядної.
Передача аргументів з / в процедуру може здійснюватися через регістри, змінні або стік.
Приклад.
Model small
. Stack 100h
. Data
w db 25 dup (?)
. Code
vvod proc
mov ah, 0ah
lea dx, w
int 21h
ret
vvod endp
main:
...
Call schet
Call vvod
...
exit:
mov ax, 4c00h
int 21h
schet proc
..
ret
schet endp
end main
Макрокоманда є одним з багатьох механізмів заміни тексту програми. За допомогою дії в текст програми можна вставляти послідовності рядків і прив'язувати їх до місця вставки. Макрокоманда представляє собою рядок, що містить деякий ім'я - ім'я дії, призначений для того, щоб бути заміщених однією або декількома іншими рядками при трансляції.
Для роботи з макрокоманди спочатку необхідно задати її шаблон-опис, так зване макроозначень.
Імя_макрокоманди MACRO [список_формальных_аргументов]
<Тіло макровизначеннями>
ENDM
Існує три варіанти розташування макроозначень:
- На початку вихідного тексту програми до сегмента коду та даних з тим, щоб не погіршувати читабельність програми. У даному випадку дії будуть актуальні тільки в межах цієї програми;
- В окремому файлі. Для того, щоб використовувати ці макровизначеннями в інших програмах, необхідно на початку вихідного тексту цих програм записати директиву
  include ім'я_файлу
- У макробібліотеке. Макробібліотека створюється в тому випадку, коли написані макроси використовуються практично у всіх програмах. Підключається бібліотека директивою include. Недолік цього і попереднього методів в тому, що у вихідний текст програми включаються абсолютно всі макровизначеннями. Для виправлення ситуації можна використовувати директиву purge, в якості операндів якій перераховуються дії, які не повинні включатися до тексту програми.
Include macrobibl. inc; у вихідний текст програми будуть вставлені рядки з macrobibl. inc
Purge outstr, exit; за винятком макроозначень outstr, exit
Активізація макросу здійснюється наступним чином:
Імя_макрокоманди спісок_ фактіческіх_ аргументів
Model small
Vivod macro rg
Mov dl, rg
Mov ah, 02h
Int 21h
endm
. Data
..
. Code
..
vivod al
..
Model small
sravnenie macro rg, met
cmp rg, 'a'
ja met
add rg, 07h
met: add rg, 30h
endm
. Data
..
. Code
..
sravnenie al, m1 ..
Функціонально макровизначеннями схожі на процедури. Подібність їх у тому, що і ті, і інші достатньо один раз десь описати, а потім викликати їх спеціальним чином. На цьому їх схожість закінчується, і починаються відмінності, які залежно від цільової установки можна розглядати і як достоїнства і як недоліки:
- На відміну від процедури, текст якої незмінний, макроозначень в процесі макрогенераціі може змінюватися у відповідності з набором фактичних параметрів. При цьому корекції можуть піддаватися як операнди команд, так і самі команди. Процедури в цьому відношенні об'єкти менш гнучкі;
- При кожному виклику дії її текст у вигляді макрорасшіренія вставляється в програму. При виклику процедури мікропроцесор здійснює передачу управління на початок процедури, що знаходиться в деякій області пам'яті в одному екземплярі. Код в цьому випадку виходить більш компактним, хоча швидкодія дещо знижується за рахунок необхідності здійснення переходів.

Приклад SEQ Приклад \ * ARABIC 17. Знайти максимальний елементи в кожному рядку масиву 5 * 7, з використанням процедур
model small
. Stack 100h
. Data
mas dw 5 dup (7 dup (0))
max dw 0
subj db 'введіть рядок ', 13,10,' $ '
. Code
; Процедура введення рядка
vvod _ str               proc
mov ah, 09h
lea dx, subj
int 21h
mov cx, 07h
mov ah, 01h
outcykl: int 21h
mov mas [si], ax
inc si
inc si
loop outcykl
ret
vvod _ str               endp
; Процедура пошуку максимального в рядку
poick_maxi proc
mov cx, 06h
mov dx, mas [si]
maxi: add si, 2
cmp dx, mas [si]
ja min1; якщо менше то переходимо
mov dx, mas [si]
min1: loop maxi
ret
poick_maxi endp
main proc
mov ax, @ data
mov ds, ax
xor     si, si; заповнення масиву
mov cx, 05 h
incykl: push   cx
call    vvod _ str     ; Виклик процедури щодо введення рядка
pop    cx
loop   incykl
; Пошук максимального / мінімального в рядках
xor si, si
mov cx, 05h
s 1 t: push   cx
call     poick _ maxi; виклик процедури пошуку максимального елемента
mov   ah, 02 h; висновок максимального
int 21 h
pop cx
loop s1t
mov ax, 04c00h
int 21 h
end р main

Програмування контролера пріоритетних переривань

Для організації обробки апаратних переривань в обчислювальних системах застосовується програмований контролер переривань, виконаний у вигляді спеціальної мікросхеми i8259А, вітчизняний аналог мікросхема КР580ВМ59. Ця мікросхема може обробляти запити від восьми джерел зовнішніх переривань. У стандартній конфігурації обчислювальних систем використовують дві послідовно з'єднані мікросхеми i8259А.
Функції мікросхеми PKP:
- Фіксування запитів на обробку переривання від восьми джерел, формування єдиного запиту на переривання і подача його на вхід INTR мікропроцесора;
- Формування номера вектора переривання і видача його на шину даних;
- Організація пріоритетною обробки переривань;
- Заборона (маскування) переривань з певними номерами.
На рис.1 представлена ​​структурна схема контролера.
Irq1
Irq2
Irq3
Irq4
Irq5
Irq7
Irq6
Irq0
INTA
INT
Блок управління читанням / записом
Буфер даних
Схема каскадування
d7 ... d0
Регістр стану (ISR)
Арбітр пріоритетів
Регістр маскування переривань (IMR)
Регістр переривань (IRR)
Програмований контролер переривань (ПКП)
Схема управління ПКП

Рис.1. Структурна схема ПКПП.

Програмування контролера пріоритетних переривань

Мета роботи:
Дослідження принципу програмного управління мікросхеми контролера переривань (ПКП) i8259А за допомогою ПК, дослідження різних режимів роботи ПКП
Мікросхема i8259A має два стани:
- Стан налаштування параметрів обслуговування переривань, під час якого шляхом посилки в певному порядку так званих керуючих слів проводиться ініціалізація контролера;
- Стан роботи - це звичайний стан контролера, в якому проводиться фіксація запитів на переривання і формування керуючої інформації для мікропроцесора відповідно до параметрів настройки.
Можливість програмування контролера дозволяє досить гнучко змінювати алгоритми обробки апаратних переривань.
У процесі завантаження комп'ютера і в подальшому під час роботи контролер переривань налаштовується на роботу в одному з шести режимів:
1. Режим фіксованих пріоритетів (Fixed Priority, Fully Nested Mode).
У цьому режимі контролер знаходиться відразу після ініціалізації. Запити переривань мають жорсткі пріоритети від 0 до 7 (0 - вищий) і обробляються відповідно до пріоритетів. Переривання з меншим пріоритетом ніколи не буде оброблено, якщо в процесі обробки переривань з більш високими пріоритетами постійно виникають запити на ці переривання.
2. Автоматичний зсув пріоритетів (Automatic Rotation). Режим циклічної обробки переривань.
У цьому режимі дається можливість обробити переривання всіх рівнів без їхньої дискримінації. Наприклад, після обробки переривання рівня 4 йому автоматично присвоюється нижчий пріоритет, при цьому пріоритети для всіх інших рівнів циклічно зсуваються і переривання рівня 5 будуть мати в даній ситуації вищий пріоритет і, отже, можливість бути обробленими.
3. Програмно-керований зсув пріоритетів (Specific Rotation).
Програміст може сам передати команду циклічного зсуву пріоритетів ПКП, задавши відповідне керуюче слово. У команді задається номер рівня, якому потрібно присвоїти максимальний пріоритет. Після виконання такої команди пристрій працює так само, як і в режимі фіксованих пріоритетів, з урахуванням їх зсуву. Пріоритети зсуваються циклічно, таким чином якщо максимальний пріоритет був призначений рівню 3, то рівень 2 отримає мінімальний і буде оброблятися останнім.
4 Автоматичне завершення обробки переривання (Automatic End Of Interrupt, AEOI).
У звичайному режимі роботи процедура обробки апаратного переривання повинна перед своїм завершенням очистити свій біт в ISR спеціальною командою, інакше нові переривання не будуть оброблятися ПКП. У режимі AEOI потрібний біт в ISR автоматично скидається в той момент, коли починається обробка переривання потрібної процедурою обробки і від неї не потрібно видавати команду завершення обробки переривання (EOI). Складність роботи в даному режимі обумовлюється тим, що всі процедури обробки апаратних переривань повинні бути повторно входимость, оскільки за час їхньої роботи можуть повторно виникнути переривання того ж рівня.
5. Режим спеціальної маски (Special Mask Mode).
Даний режим дозволяє скасувати пріоритетне впорядкування обробки запитів і обробляти їх у міру надходження. Після скасування режиму спеціальної маски попередній порядок пріоритетів рівнів сохранается.
6. Режим опитування (Polling Mode).
У цьому режимі апаратні переривання не відбуваються автоматично. Поява запитів на переривання має визначатися зчитуванням IRR. Даний режим дозволяє так само одержати від ПКП інформацію про наявність запитів на переривання і, якщо запити є, номер рівня з максимальним пріоритетом, за яким є запит
Програмування контролера переривань i 8259 A
Для виведення інформації в ПКП використовуються 2 порти введення-виведення. Порт з парних адресою (зазвичай це порт 20h) і порт з непарним адресою (зазвичай 21h). Через ці порти можуть бути передані 4 слова ініціалізації (Initialization Control Word, ICW1 - ICW4), що задають режим роботи ПКП, і 3 операційних керуючих слова (слова робочих наказів, Operation Control Words, OCW1 - OCW3).
У порт з парних адресою виводяться ICW1, OCW2 і OCW3.
Порт з непарним адресою використовується для виведення ICW2, ICW3, ICW4 і OCW1. Неоднозначності інтерпретації даних в цьому випадку так само не виникає, тому що слова ініціалізації ICW2 - ICW4 повинні безпосередньо слідувати за ICW1, виведеним в порт з парних адресою і виводити в проміжку між ними OCW1 не слід, воно не буде упізнано контролером.
Висновком в порт з парних адресою керуючого слова ініціалізації ICW1 починається ініціалізація ПКП. У процесі ініціалізації контролер послідовно вживає керуючі слова ICW1 - ICW4. При наявності в системі одного контролера ICW3 не виводиться. Наявність ICW4 визначається змістом ICW1. При наявності каскаду з декількох ПКП кожен з них ініціалізується окремо.
Для ініціалізації та управління роботою відомого контролера використовуються адреси A0h, A1h. У порт з адресою A0h виводяться ICW1, OCW2 і OCW3. Порт з адресою A1h використовується для виведення ICW2, ICW3, ICW4 і OCW1.
При наявності в системі відомого контролера слово ICW3 для контролерів ПКП обов'язково.
Формат ICW1 наступний:
Біти ICW1
Призначення і зміст
0
1 - керуюче слово ICW4 буде присутній в даній послідовності наказів
1
0 - каскадне підключення ПКП (ICW3 буде в послідовності)
1 - одиночне підключення ПКП (ICW3 не буде)
2
0 - не використовується
3
0 - переривання по перепаду сигналу
4
1 - ознака ICW1
5 .. 7
0 - не використовується
ICW2 - визначення базового адреси:
Біти ICW2
Призначення і зміст
0 .. 2
0 - не використовується
3 .. 7
Біт для створення номера базового вектора
Керуюче слово ICW2 задає номер вектора переривання, процедури обробки переривань, для апаратного переривання irq0. Вектора обробки апаратних переривань розташовуються послідовно з адреси 08h, що завантажується на початку роботи процесора. Некоректна зміна номера вектора призведе до збою всієї системи.
Формат ICW3 для головного контролера наступний:
Біти ICW3
Призначення і зміст
0 .. 7
1 - якщо до входу irqN підключений ведений
0 - якщо до входу irqN підключено зовнішній пристрій

Формат ICW3 для відомого контролера наступний:
Біти ICW3
Призначення і зміст
0 .. 3
Задає номер рівня, на якому працює ведений контролер
4 .. 7
0 - не використовується
Формат ICW4:
Біти ICW4
Призначення і зміст
0
Тип процесора: 0 - i8080; 1 - i80x86, Pentium
1
1 - режим автоматичного завершення обробки переривання, описаний вище
0 - діє звичайне угоду: процедура обробки апаратного переривання повинна сама скидати свій біт в ISR.
2
1 - даний контролер ведучий,
0 - даний контролер ведений
3
1 - системна шина буферизованная
0 - системна шина не буферизованная
4
0 - встановлює спеціальний вкладений режим, який застосовується при каскадування для визначення пріоритетів запитів від різних контролерів (Special Fully Nested Mode)
5 .. 7
0
У процесі роботи з ПКП ви можете без переініціалізаціі:
- Маскувати і размаскіровать апаратні переривання;
- Змінювати пріоритети рівнів;
- Видавати команду завершення обробки апаратного переривання;
- Встановлювати / скидати режим спеціальної маски;
- Переводити контролер у режим опитування і зчитувати стан регістрів ISR і IRR.
Для цього Вам потрібно вивести в порти ПКП одне з трьох слів робочих наказів OCW1 - OCW3.

Формат OCW1 - управління регістром масок IMR:
Біти ОCW1
Призначення і зміст
0 .. 7
0 - дозволити переривання рівня N
1 - заборонити переривання рівня N
Формат OCW2 - управління пріоритетом:
Біти ОCW2
Призначення і зміст
0 .. 2
000-nnn - код рівня запиту irq для дій, що визначаються розрядами 5-7
3 .. 4
00 - ознака OCW2
5
0 - режим автоматичного EOI
1 - режим неавтоматичного EOI
6 .. 7
Задають операцію в поєднанні з 5-м бітом:
000 - автоматичний режим пріоритетів з автоматичним EOI
001 - скидання біта з максимальним пріоритетом в ISR
011 - скидання біта в ISR для рівня з кодом nnn
100 - установка режиму циклічної зміни пріоритету при автоматичному EOI
101 - установка режиму циклічної зміни пріоритету при неавтоматическом EOI
111 - установка режиму циклічної зміни пріоритету але відносно біта nnn
Формат OCW3 - загальне управління контролером:
Біти ОCW3
Призначення і зміст
0 .. 1
10 - прочитати вміст IRR (наступній командою з порту 020h);
11 - прочитати вміст ISR (наступною командою з порту 020h);
Вміст IМR є постійно як вміст порту 021h.
2
1 - переводить контролер у режим опитування
3 .. 4
Ознака OCW3
5 .. 6
11 - встановити режим спеціального маскування
10 - скинути режим спеціального маскування
00 або 01 - нічого не міняти
7
0

Розподіл і пріоритети апаратних переривань в архітектурі АТ
Рівень
Контролер
Джерело переривань
Пріоритет рівня
Irq0
Ведучий
Таймер
2
Irq1
Ведучий
Клавіатура
3
Irq2
Ведучий
Вихід INT веденого
Irq8
Ведений
Годинник реального часу
4
Irq9
Ведений
Вхід для влаштування розширення
5
Irq10
Ведений
Вхід для влаштування розширення
6
Irq11
Ведений
Вхід для влаштування розширення
7
Irq12
Ведений
Вхід для влаштування розширення
8
Irq13
Ведений
Помилка співпроцесора
9
Irq14
Ведений
Контролер жорсткого диска
10
Irq15
Ведений
Вхід для влаштування розширення
11
Irq3
Ведучий
Вхід для влаштування розширення (послідовний порт СОМ2)
12
Irq4
Ведучий
Вхід для влаштування розширення (послідовний порт СОМ1)
13
Irq5
Ведучий
Вхід для влаштування розширення (паралельний порт LPT2)
14
Irq6
Ведучий
Контролер гнучкого диска
15
Irq7
Ведучий
Вхід для влаштування розширення (паралельний порт LPT1)
16
Програмування контролера прямого доступу пам'яті

Програмування контролера ПДП

Мета роботи:
Дослідження принципу програмного управління мікросхеми, контролера прямого доступу пам'яті (ПДП) i8237А за допомогою ПК, дослідження різних режимів роботи ПДП.
Прямий доступ до пам'яті - DMA (Direct Memory Access) метод обміну даними периферійного пристрою з пам'яттю без участі процесора. У режимі прямого доступу до пам'яті процесор ініціалізує контролер прямого доступу до пам'яті - задає початкову адресу, лічильник і режим обміну, після чого звільняється. Сам обмін виробляє контролером ПДП, що забезпечує високошвидкісний обмін даними між пристроями введення-виведення і памяттю без використання центрального процесора, це дозволяє звільнити процесор для виконання обчислень паралельно з обміном і незалежно від нього. Найбільш часто можливості ПДП використовуються при роботі з дисковими накопичувачами, проте реалізовано використання ПДП низкою інших пристроїв. Відчутні переваги дає використання ПДП в процесі обміну з пристроями, що приймають або передають дані досить великими порціями з високою швидкістю.
Чотирьохканальний контролер ПДП i8237А має 16-розрядні регістри адреси і лічильники, що забезпечує можливість програмування передачі блоку даних розміром до 64 Кбайт. Для забезпечення доступності адресного простору пам'яті розміром в 1 Мбайт застосували зовнішні 4-розрядні регістри сторінок DMA, окремі для кожного каналу. У цих регістрах зберігаються біти адреси А [19:16], а бітами А [15:0] управляє контролер.
Мікросхема i8237А допускає каскадування при досить гнучкому конфігуруванні.
Принципи роботи контролера ПДП
У роботі ПДП розрізняються 2 головних циклу: цикл очікування (Idle cycle) і активний цикл (Active cycle). Кожен цикл поділяється на ряд станів, які займають по часу один період часу (тик). З циклу очікування контролер може бути переведений в стан програмування (Program Condition) шляхом подачі на вхід RESET сигналу високого рівня, тривалістю не менше 300 нс і такий його подачі сигналу низького рівня (рівня 0) на висновок CS (Chip Select). У стані програмування контролер перебуватиме до тих пір, поки на виведенні CS збережеться сигнал низького рівня. У процесі програмування контролеру задаються:
- Початковий адресу пам'яті для обміну;
- Зменшене на одиницю число переданих байтів;
- Напрямок обміну;
- Необхідні режими роботи (дозволити або заборонити циклічну зміну пріоритетів, автоініціалізацію, задати напрямок зміни адреси при обміні і т. д.).
Завантаження 16-розрядних регістрів контролера здійснюється через 8-розрядні порти введення-виведення. Перед завантаженням першого (молодшого) байта може бути скинуто (очищений) тригер-клямка (тригер перший / останній, First / Last flip-flop), який змінює свій стан після виводу в порт першого байта і таким чином дає можливість наступної командою виводу в той же порт завантажити старший байт відповідного регістру.
Запрограмований канал повинен бути демасковані (біт маски каналу встановлюється при цьому в 0), після чого він може приймати сигнали «Запит на ПДП», що генеруються тим зовнішнім пристроєм, який обслуговується через цей канал. Сигнал «Запит на ПДП» може бути також ініційований установкою в 1 біта запиту даного каналу в регістрі запитів контролера. Після появи сигналу запиту контролер входить в активний цикл, в якому виконується обмін даними. Обмін може здійснюється в одному з чотирьох режимів:
1. Режим одиночної передачі (Signle Transfer Mode).
Після кожного циклу передачі контролер звільняє шину процесору, але відразу ж починає перевірку сигналів запиту і, як тільки виявляє активний сигнал запиту, ініціює наступний цикл передачі.
2. Режим блокової передачі (Block Transfer Mode).
У цьому режимі наявність сигналу запиту слід тільки до моменту видачі контролером сигналу «Підтвердження запиту на ПДП» (DACK), після чого шина не звільняється аж до завершення передачі всього блоку.
3. Режим передачі на вимогу (Demand Transfer Mode).
Даний режим є проміжним між двома першими: передача йде безперервно до тих пір, поки активний сигнал запиту, стан якого перевіряється після кожного циклу передачі. Як тільки пристрій не може продовжити передачу, сигнал запиту скидається їм і контролер призупиняє роботу. Цей режим застосовується для обміну з повільними пристроями, що не дозволяють за своїми часовими характеристиками працювати з ПДП в режимі блокової передачі.
4. Каскадний режим (Cascade Mode).
Режим дозволяє включити в підсистему ПДП більше одного контролера в тих випадках, коли недостатньо чотирьох каналів ПДП. У цьому режимі один з каналів головного контролера використовується для каскадування з контролером другого рівня. Для роботи в каскаді сигнал HRQ («Запит на захоплення») відомого контролера подається на вхід DREG («Запит на канал ПДП») ведучого, а сигнал DACK («Підтвердження запиту») провідного подається на вхід HDLA («Підтвердження захоплення») відомого .
Така схема підключення аналогічна підключенню ведучого (першого) контролера до мікропроцесора, з яким він обмінюється сигналами HRQ і HDLA.
Типи можливих режимів передач
1. Передача пам'ять-пам'ять (Memory - to - memory DMA)
Використовується для передачі блоку даних з одного місця пам'яті в інше. Вихідна адреса визначається в регістрах нульового каналу, вихідний - в регістрах першого каналу. Число циклів обміну (число байт мінус 1) задається в регістрі числа циклів каналу 1. Передача відбувається з використанням робочого регістра контролера в якості проміжної ланки для зберігання інформації. При передачe пам'ять-пам'ять може бути заданий спеціальний режим фіксації адреси (Address hold), при якому значення поточного адреси в регістрі нульового каналу не змінюється, при цьому весь вихідний блок пам'яті заповнюється одним і тим же елементом даних, що знаходяться за заданою адресою.
2. Автоініціалізація (автозавантаження, Autoinitialization)
Після завершення звичайної передачі використаний канал ПДП маскується і повинен бути перепрограмований для подальшої роботи з ним. При автоініціалізаціі маскування каналу після закінчення передачі не відбувається, а регістри поточного адреси і лічильник циклів автоматично завантажуються з відповідних регістрів з початковими значеннями. Таким чином для продовження (повторення) обміну досить виставити сигнал запиту на ПДП по даному каналі.
3. Режим фіксованих пріоритетів
У цьому режимі канал 0 завжди має максимальний пріоритет, а канал 3 - мінімальний. Це означає, що будь-яка передача по каналу з більш високим пріоритетом буде виконуватися раніше, ніж по каналу з більш низьким пріоритетом.
4. Циклічний зсув пріоритетів
Дозволяє уникнути «забивання» шини одним каналом при одночасній передачі по декількох каналах. Кожному каналу, по якому пройшла передача, автоматично присвоюється нижчий пріоритет, після чого право на передачу отримує канал з найвищим пріоритетом, для якого передача в даний момент можлива. Таким чином, якщо на початку роботи розподіл пріоритетів було звичайним (канал 0 - найвищий), і прийшли сигнали запиту на ПДП по 1-му і 2-му каналах, то спочатку буде виконуватися передача по першому каналу, потім він отримає найнижчий пріоритет (а канал 2, відповідно, вищий, тому що зсув пріоритетів циклічний) і передача виконається по 2-му каналу, який потім отримає найнижчий пріоритет, а вищий пріоритет отримає, відповідно, канал 3, який і буде мати переважне право на передачу.
5. Стиснення часу передачі (Comdivssed transfer timing).
У випадку, якщо тимчасові характеристики швидкодії обмінюються пристроїв збігаються, ПДП може скоротити час виконання кожного такту передачі на 2 цикли годин за рахунок тактів очікування, що входять в кожен цикл передачі.

Розподіл каналів прямого доступу

Прямий доступ до пам'яті був використаний ще в PC / XT, де для цього застосовувалася мікросхема чотириканального контролера 8237А.
З чотирьох каналів DMA XT на шині ISA доступні тільки три (1, 2 і 3). Канал 0 використовується для регенерації динамічної пам'яті, і від нього на шину ISA виводиться тільки сигнал підтвердження DACKO #, він же REFRESH #. Цей сигнал може використовуватися для регенерації динамічної пам'яті, якщо така використовується на платах адаптера. Адреса регенерованої рядка береться з ліній адреси шини ISA. Канали 1, 2 і 3 забезпечують побайтного передачу даних і називаються 8-бітними каналами DMA.
В архітектурі AT підсистему DMA розширили, додавши другий контролер 8237А. Його підключили до шини адреси зі зміщенням на 1 біт, і його 16-бітові регістри адреси здатні управляти лініями адреси А [1б: 1], молодший біт адреси АТ завжди нульовий. Таким чином, другий контролер може забезпечувати передачу даних тільки послівно (по два байти), за що його канали і названі 16-бітними. За один сеанс другий контролер здатний передати масив до 64К 16-розрядних слів. Регістри сторінок для всіх каналів DMA у AT розширені до 8 біт, що робить доступною для будь-якого каналу область пам'яті розміром 16 Мбайт (0-FFFFFFh). Стандартне призначення каналів наведено в табл. 1.
Крім збільшення числа каналів в AT ввели додаткову можливість керування шиною ISA - Bus - Mastering - З боку адаптера. Це зовнішнє управління шиною спирається на контролер DMA, що виконує в даному випадку функції арбітра шини. Для одержання керування шиною зовнішній Bus-Master надсилає запит по лінії DRQx (тільки для каналів 5-7) і, отримавши підтвердження DACKx, встановлює сигнал MASTERS. Тепер шиною ISA управляє він, але формально він не має права займати шину більше ніж на 15 мкс за сеанс. В іншому випадку порушиться регенерація пам'яті (пізніше зіб'ється системний час, але при порушенні регенерації ці «дрібниці» вже не важливі). Інтелектуальний контролер може виконувати більш ефективні процедури обміну, ніж стандартний DMA, наприклад:
Scatter Write - «розкидана» запис в кілька блоків пам'яті.
Gather Read - читання зі збором даних з декількох блоків пам'яті.
Обмін непарною кількістю байт і (або) з непарного адреси по 16-бітному каналу.
Управління шиною використовують високопродуктивні адаптери SCSI і локальних мереж, а також інтелектуальні графічні адаптери. Однак архітектурою шини доступне їм простір пам'яті обмежена областю 16 Мбайт, що за нинішніми мірками замало. «Дбайливі» операційні системи (наприклад, Novell NetWare) для таких адаптерів дозволяють під буфери резервувати область в межах молодших 16 Мбайт.
На шині EISA DMA-канали можуть працювати в 8 -, 16 - і 32-бітному режимі, вони можуть використовувати всі 32 розряду шини адреси - мати доступ до всієї пам'яті комп'ютера. Кожен канал може програмуватися на 1 з 4 типів циклу передачі:
Compatible - повністю сумісний з ISA.
Type A - скорочений на 25% цикл: час одиночного циклу 875 нс, в блоковому режимі час циклу 750 нс. Працює майже з усіма ISA-адаптерами з більшою швидкістю.
Type В - скорочений на 50% цикл (750/500 нс на цикл), працює з більшістю EISA-адаптерів і деякими ISA. Цей тип циклу можливий тільки з пам'яттю, безпосередньо доступною контролера шини EISA (пам'яттю на адаптерах EISA, а також системної у разі, якщо EISA є основною шиною системної плати). Якщо декодований адресу пам'яті відноситься до 8/16-бітной пам'яті ISA, то контролер DMA EISA автоматично переводиться в режим Compatible.
Type С (Burst Timing) - скорочений на 87,5% цикл, орієнтований на пакетний режим передач. Працює з швидкісними EISA-адаптерами і при обміні 32-бітових пристроїв з 32-бітної пам'яттю дозволяє розвивати швидкість обміну до 33 Мбайт / с.
У PCI-системах для обміну з пристроями системної плати (Fast ATA-2 або E-IDE-порти) можливе використання DMA Type F, при якому між сусідніми циклами інтервал може не перевищувати 3 тактів шини (360 нс). Для розвантаження системної шини використовується додатковий 4-байтний буфер. Режим F може працювати тільки в режимі одиночної передачі або за запитом і тільки з инкрементом (збільшенням) адреси. На самій шині PCI адаптери можуть використовувати режим прямого управління шиною, для чого є спеціальний протокол арбітражу, який до контролерів DMA відносини вже не має.
Таблиця 1. Стандартні канали прямого доступу до пам'яті.
Номер каналу DMA #
0
1
2
3
4
5
6
7
Стандартне призначення
XT
MRFR *
-
FDD
HDD
Відсутні
AT
-
SDLC *
FDD
HDD *
Каскад
-
-
-
Розрядність, байт
1
2 з парного адреси
Макс. розмір блоку
64 Кбайта
128 Кбайт, парний
Кордон блоків
Кратна 1000h
Кратна 2000h
Регістр сторінок
4 біт А16-А19
7 біт А17-А23
Адреси регістрів:
сторінок
087
083
081
082
08F
08В
089
087
поч. адреси (W)
текущ. адреси (R)
000
002
004
006
0С0
0С4
0С8
0СЕ
поч. лічильника (W)
текущ. лічильника (R)
001
003
005
007
0С2
0С6
0СА
0СЕ
* SDLC-адаптер встановлюється рідко.
HDD-контролер в AT DMA зазвичай не використовує.
Канал 0 в XT використовується для регенерації пам'яті (MRFR).
Канал 4 доступний тільки в PS / 2 МСА.

Програмне управління контролером ПДП

Програмне управління контролером ПДП здійснюється через порти введення-виведення. Доступ до кожного регістру контролера може бути здійснений через свої порти введення-виведення. Розподіл адрес і опис внутрішніх регістрів першого і другого контролера ПДП наведено в таблиці 2.
Таблиця 2. Регістри контролера ПДП 8237А.
8237 # 1
8237 # 2
R / W
Призначення регістрів
008h
0D0h
W
Регістр команд (Command Register)
Біти: 7 = 1 - активний рівень DACK - високий
6 = 1 - активний рівень DRQ - високий
5 = 1 - режим розширеної запису
4 = 1 - циклічний пріоритет
3 = 1 - укорочений цикл обміну
2 = 1 - заборона роботи контролера
1 = 1 - фіксація адреси 0 каналу
0 = 1 - передача пам'ять-пам'ять (в PC не використовується)
008h
0D0h
R
Регістр стану каналів (Status Register)
Біти 7 .. 4 запити каналів 0-3
Біти 3 .. 0 завершення циклу каналів 0-3
009h
0D2h
W
Регістр запитів (Request Register)
Біти 7 .. 3 - не використовуються
2 = 1 - встановлення / = 0 - скидання біта запиту
1 .. 0 - вибір каналу (00 = 0, 01 = 1, 10 = 2, 11 = 3)
00Ah
0D4h
W
Регістр маски - Single Mask Bit Register
Біти 7 .. 3 - не використовуються
2 = 1 - встановлення / = 0 - скидання біта маски
1 .. 0 - вибір каналу (00 = 0, 01 = 1, 10 = 2, 11 = 3)
00Bh
0D6h
W
Регістр режиму роботи каналу (Mode Register)
Біти 7 .. 6 - режим передачі (00 - за запитом, 01 - одиночний, 10 - блоковий, 11 - каскадування)
5 = 1 - інкремент / = 0 - декремент адреси
4 = 1 - дозвіл автоініціалізаціі
3 .. 2 - тип передачі (00 - холостий, 01-запис, 01 - читання, 11 - не ісп.)
1 .. 0 - вибір каналу (00 = 0, 01 = 1, 10 = 2, 11 = 3)
00Ch
0D8h
W
Скидання тригера молодшого / старшого байта - Clear Byte Pointer Flip / Flop
00Dh
0DAh
W
Загальний скид 8237А - Master Clear (висновок будь-якого байта в регістр викликає скидання)
00Eh
0DCh
W
Загальний скид масок всіх каналів - Clear Mask Register (висновок будь-якого байта в регістр викликає скидання)
00Fh
0DEh
W
Регістр масок всіх каналів - All Mask Register Bits
Біти 7 .. 4 - не використовуються
3 .. 0 - маски каналів 0-3 (0-канал дозволений, 1 - приховані)
Регістри управління каналами другого контролера
-
0C0h, 0C4h, 0C8h, 0CCh
W
Запис початкової адреси в регістр початкової адреси (Base Address Register) і регістр поточного адреси каналу (Current Address Register) 4,5,6,7
-
0C0h, 0C4h, 0C8h, 0CCh
R
Читання початкової адреси з регістра початкової адреси каналу (Current Address Register) 4,5,6,7
-
0C2h, 0C6h, 0CAh, 0CEh
W
Запис в регістр початкового лічильника циклів (Base Word Count Register) і в регістр поточного лічильника циклів каналу (Current Word Count Register) 4,5,6,7
-
0C2h, 0C6h, 0CAh, 0CEh
R
Читання поточного значення з регістра поточного лічильника циклів каналу (Current Word Count Register) 4, 5, 6, 7
-
089h, 08Bh, 08Ah, 08Fh
W
Завдання номер сторінки для каналу 6,5,7,4

Канали 4 - 7 призначені для обміну 16-розрядними словами. У зв'язку з цим виникає ряд відмінностей у роботі з цими каналами:
- Біт 0 в даних, що заносяться до регістрів початкового і поточного адреси, завжди мається на увазі рівним 0, тому через ці регістри передаються біти 1 - 16 повного 23-розрядної адреси (а не біти 0 - 15 повного 20-розрядної адреси, як це реалізовано на ХТ - подібних ПЕОМ). З цієї ж причини в сторінкові регістри каналів 4 - 7 заносяться біти 17 - 23 повної адреси, а не биті 16 - 23, як це треба зробити при роботі з каналами 0 - 3;
- Оскільки передача здійснюється 16-розрядними словами, в регістри поточного та початкової лічильника циклів заноситься не число байт, а кількість слів, зменшеної на одиницю;
- Розміри сторінок пам'яті, в межах яких можливий обмін протягом однієї передачі, складають 2000h байтів.
Опис регістрів
Регістр початкової адреси (Base Address Register). У цьому регістрі задається стартова адреса ОЗП, з якого починається передача. Реєстр містить 16 розрядів і визначає адресу всередині заданої сторінки пам'яті розміром 64К. Завдання номера сторінки пам'яті здійснюється через спеціальні сторінкові регістри (Page Registers), підтримувані зовнішньою логікою.
Кожен канал ПДП має свій регістр початкової адреси і сторінковий регістр. Такий поділ пам'яті на сторінки не дозволяє здійснити обмін з блоком пам'яті, що знаходиться на перетині двох сторінок. Кожна сторінка починається з сегментної адреси, кратного 1000h (0, 1000h, 2000h, ..., 9000h).

Регістр початкового лічильника циклів (Base Word Count Register)
У цьому регістрі задається початкове число циклів передачі для програмованого каналу. Фактичне число переданих під час роботи ПДП елементів даних на одиницю перевищує задане число циклів, тобто якщо Ви задаєте 100 циклів передачі, а розмір елемента буде дорівнює 1 байту, то за сеанс обміну буде переданий 101 байт інформації.
Регістр поточного адреси (Current Address Register)
Початкове значення заноситься в цей регістр одночасно з регістром початкової адреси. Надалі в ході передачі значення поточного адреси автоматично збільшується або зменшується (конкретний напрям зміни задається при програмуванні в регістрі режиму). Якщо дозволена автоініціалізація, то після закінчення передачі в регістр автоматично встановлюється значення з регістра початкової адреси.
Регістр поточного лічильника циклів (Current Word Count Register)
Реєстр містить поточне значення лічильника циклів (число залишилися циклів передачі). Коротке в ньому число циклів завжди на одиницю менше числа ще не переданих елементів даних, так як зміна значення в цьому регістрі проводиться в кінці циклу передачі, вже після фактичної передачі елемента даних, а кінець передачі фіксується в момент переповнення лічильника (зміна його значення з 0 на 0FFFFh).
Кожен з чотирьох каналів ПДП має свій набір регістрів, описаних вище. Крім того, є наступний набір регістрів, загальних для всіх каналів.
Регістр режиму (Mode Register)
Даний регістр задає режими роботи свого каналу контролера.
Регістр команд (Command Register).
Цей 8-бітний регістр керує роботою контролера. Він програмується, коли контролер знаходиться в стані програмування і очищається командами скидання «Reset» і «Master Clear».
Регістр стану (Status Register)
Регістр відображає поточний стан запитів і передач по всіх чотирьох каналах. Біти 0 - 3 встановлюються в одиницю після завершення передачі по каналам 0 - 3 (біт 0 - канал 0, біт 1 - канал 1 і т.д.), якщо не заданий режим автоініціалізаціі. Ці біти очищаються після команди скидання контролера і після кожної операції зчитування стану з регістра стану. Біти 4 - 7 вказують яким із каналів 0 - 3 активний поточний момент сигнал запиту на ПДП.
Регістр масок (Mask Register)
Кожен біт 4-бітового регістра маскує / демаскує свій канал ПДП, при цьому значення 1 маскує канал, значення 0 демаскує канал і дозволяє прийом сигналу запиту з цього каналу.
Регістр запитів (Request Register)
Сигнал запиту на ПДП (DREQ) може бути виданий як обслуговуються пристроєм, так і програмно. Для програмного видання сигналу запиту по одному з 4-х каналів ПДП необхідно встановити відповідний біт у 4-розрядному регістрі запитів. Запит на ПДП може бути скасований записом нульового значення у відповідний біт регістра. Біт запиту очищається автоматично при закінченні передачі по даному каналі. Всі біти запитів очищаються при скиданні контролера. Для того, щоб сприймати програмні запити на ПДП, канал повинен знаходиться в режимі блокової передачі.

Література

1. Уокерлі Дж. Архітектура та програмування мікроЕОМ: у 2-х кн. / Пров. з англ. - М.: Світ, 1984.
2. Асемблер. Юров. В. - СПб.: Питер, 2001. - 624 с.: Іл.
3. Асемблер: практикум. Юров. В. - СПб.: Питер, 2001. - 400 с.: Іл.
Додати в блог або на сайт

Цей текст може містити помилки.

Програмування, комп'ютери, інформатика і кібернетика | Методичка
304.9кб. | скачати


Схожі роботи:
Схема контролера
Розрахунок собівартості і вартості програмного продукту з обліку переривань на мові Асемблер
Кластерний аналіз як ефективний інструмент визначення пріоритетних напрямків розвитку регіонів
Організація переривань і прямого доступу до пам`яті в обчислювальних системах розподіл ресурсів
Розробка HDL-моделі та компютерне моделювання паралельного логічного контролера циклічної дії
Правозахисна робота профспілок один із пріоритетних напрямів діяльності профспілок
Основні поняття математичного програмування Побудова моделі задачі лінійного програмування
Програмування мовою С з використанням обєктно-орієнтованого програмування
Програмування мовою С з використанням об єктно орієнтованого програмування
© Усі права захищені
написати до нас