Все про Assembler українською мовою на сайті net.kr.ua

 

:: Меню ::

Головна
Введення
Архітектура реального режиму
Основи програмування
Команди і алгоритми
Розширені можливості сучасних мікропроцесорів
Система команд процесорів Intel
Книга для гостей
Контакти
Добавити у вибране

:: Друзі ::

  С хорошей скидкой обслуживание пожарной сигнализации москва без дополнительной оплаты.
 

:: Лічильники ::

=

 

 

 

 

fff00e50

Програмування апаратних засобів

Програмування апаратури - як штатних периферійних пристроїв комп'ютера, таких, як відеосистема, клавіатура, послідовний або паралельний інтерфейс і ін., так і нестандартних вимірювальних або таких, що управляють пристроїв, що підключаються до комп'ютера, якщо він використовується для автоматизації наукових досліджень або управління технологічним процесом - є одним з найважливіших і найбільш виправданих застосування мови асемблера. По-перше, від програм управління апаратурою часто потрібна максимальна швидкодія. По-друге, ці програми, покликані управляти апаратурою на низькому рівні, шляхом звернення до регістрів і їх окремими бітам, часто нічого не виграють від використання мов високого рівня, в яких ті ж операції реалізуються за допомогою процедур мови, менш наочних і ефективних, чим "чисті" команди процесора. По-третє, при програмуванні апаратури, особливо, експериментальною, важливо жорстко дотримувати тимчасову і подієву послідовність команд і сигналів, що сприймаються програмованим пристроєм, що природним чином досягається при використанні мови асемблера, в якому кожна пропозиція мови реалізується цілком певною командою процесора.
Залежно від призначення і способу функціонування апаратури, вона може вимагати різних режимів програмного управління. В основному існують три режими, або способи взаємодії програми і апаратури: режим вільного доступу, режим очікування готовності і режим переривань.
Режим вільного доступу використовується в тих випадках, коли момент звернення до пристрою цілком визначається програмою. Наприклад, регістри, керівники роботою апаратури, зазвичай доступні у будь-який момент часу. Програма може у будь-який момент прочитати вміст цих регістрів і визначити по ньому поточний режим роботи пристрою, або, навпаки, послати в керівники регістри необхідну послідовність команд з метою зміни робочого режиму.
Режим очікування готовності необхідно використовувати в тих випадках, коли після прийому деякої команди пристрою вимагається певний час для її виконання. Наприклад, в послідовний порт, через який комп'ютер зв'язується з іншими комп'ютерами або телефон ний мережею, не можна посилати наступну порцію інформації (байт), поки пристроями послідовного інтерфейсу не буде відправлена до каната зв'язку попередня порція. Режимом очікування готовності часто користуються для прийому інформації з вимірювальної апаратури, якщо потрібно забезпечити максимальну швидкість її отримання.
Режим переривань є найважливішим способом зв'язку з відносно повільним периферійним устаткуванням. В цьому випадку пристрій підключається не тільки до ліній адрес, даних і управління системної магістралі комп'ютера, але і до однієї із спеціально виділених ліній переривань. У режимі переривання пристрій само вирішує, коли йому потрібне обслуговування, і посилкою в комп'ютер сигналу переривання оповіщає про це процесор. Типовим прикладом є клавіатура, що посилає сигнал переривання кожного разу, коли користувач натискає на ту або іншу клавішу. Велика частина штатних пристроїв комп'ютера - миша, диски, таймер і ін. - використовують режим переривань. Типовий цей режим також і для зв'язку з вимірювальною апаратурою в тих випадках, коли апаратура реєструє відносно рідкісні події, або вимірювальні дані накопичуються в апаратурі протягом помітного часу і потім пересилаються в комп'ютер відразу цілою пачкою.
Як вже наголошувалося в гл. 1, зв'язок з апаратними засобами самого комп'ютера, а також з пристроями, що підключаються до нього, здійснюється головним чином через адресний простір введення-виводу. Це означає, що за кожним пристроєм закріплюється один або, частіше, декілька портів, і програмування пристрою здійснюється виключно за допомогою команд in і out (а також ins і cuts, якщо програмований пристрій може посилати дані потоком).
У простому випадку програмування пристрою зводиться до виконання єдиної команди in у разі читання з пристрою, або out у разі запису в нього. Розглянемо, наприклад, процедури маскування і размаськированія апаратних переривань. У кожному з двох контроллерів переривань, що включаються до складу комп'ютера, є регістр маски (мал. 3.10). Значення 0 в біті маски вирішує проходження сигналу переривання, значення 1 забороняє. Пройшовши через маску і через подальші вузли контроллера переривань (не показані на мал. 3.10), сигнал переривань поступає на вхід INT мікропроцесора. Програмування регістрів маски здійснюється через порт 21h для провідного контроллера і A1h для веденого.
Початкове значення маски встановлюється програмами початкового завантаження комп'ютера залежно від конфігурації обчислювальної системи. Типовим є значення A8h, показане на мал. 3.10. При цьому значенні маски размаськированнимі виявляються системний таймер, клавіатура, миша, підключена до першого послідовного порту

Мал. 3.10. Регістр маски провідного контроллера переривань.

Сом1, гнучкий диск, а також вихід від веденого контроллера, що підключається до входу Irq2 ведучого. Замасковано обидва паралельні порти (принтер, що підключається до порту Lpt1, зазвичай не використовує переривань, а другий паралельний порт часто просто відсутній) і другий послідовний порт, до якого нічого не підключено. Іншими словами, размаськировано все потрібне, і замасковане все непотрібне.
У раді випадків виникає необхідність замаскувати переривання від системного таймера, який є єдиним постійно активним джерелом переривань. Така ситуація типова, зокрема, для автоматизованих вимірювальних систем, в яких неприпустимо переривати потік даних, що поступають від вимірювальної установки в комп'ютер. Будь-яке переривання процесу прийому даних може привісить до втрати частині інформації, що приймається, і порушенню роботи установки. Для заборони переривань від таймера треба виконати таку послідовність команд:

in Al,21h ;Чтение регістра маски


or Al,1 ;Установка 1 в біті 0


out 21h,al ;Запись нового значення маски

Відновлення початкового стану обчислювальної системи з дозволеними перериваннями від таймера здійснюється таким чином:

in Al,21h ;Чтение регістра маски


and AL, 0feh ;Установка 0 в біті 0


out 21h,al ;Запись нового значення маски

Іншим прикладом використання режиму вільного доступу до пристрою є програмування незалежної КМОП-мікросхеми, що включає годинник реального часу, про який вже мовилося в розділі 5 цього розділу, а також інформацію об конфігурації комп'ютера і в деяких випадках пароль. Загальний об'єм КМОП-пам'яті складає 64 байт (від 00h до 3fh); доступ до байтів КМОП-пам'яті здійснюється через порти 70h і 71h.
У КМОП-мікросхемі реалізований спосіб звернення до її окремих осередків, широко використовуваний в мікропроцесорній техніці. Якщо програмувати КМОП-пам'ять прямим чином, для звернення до її 64 осередкам в адресному просторі введення-виводу довелося б виділити 64 адреси. Для скорочення числа використовуваних адрес до складу мікросхеми введено два службові регістри - адресний і даних. У адресний регістр (порт 70h) заноситься номер того осередку КМОП-пам'яті, до якого потрібне звернення. Після цього читання регістра даних (порт 7 Hi) дозволяє прочитати вміст вибраного осередку, а запис в регістр даних виконує передачу даного в цей осередок. Приведемо повний текст програми, яка читає вміст осередку з номером 0dh. У ній зберігається стан батареї, що живить КМОП-мікросхему. Якщо битий 7 цього осередку встановлений, батарея справна; якщо цей біт скинутий, напруга батареї впала нижче за допустиму межу, і її треба міняти.

Приклад 3-10. Читання осередку КМОП-мікросхеми


code segment

assume cs:code

main proc

mov Al,odh ;Будем читати осередок Odh

out 70h,al ;Задание номери осередку

in Al,71h ;чтение з осередку

test Al,80h ;Проверка бита 7

jnz ok ;Бит 7 = 1, перейти на OK

mov Ah,02h ;Бит 7=0, живлення немає

mov Dl,'-' ; Виведемо на знак цього

int 21h ; Символ мінус

jmp exit ;Переход на завершення

ok: mov Ан,02h ;Батарея у порядку

mov Dl,'+' ;выведем на знак цього

int 21h ;символ плюс

;Завершимо програму

exit: mov Ax,4cooh

int 21h

main endp

code ends

end main

Розглянемо тепер програмування периферійного устаткування в режимі очікування готовності на прикладі паралельного інтерфейсу. У стандартній конфігурації комп'ютера до паралельного інтерфейсу зазвичай підключається принтер, проте його можна використовувати і для зв'язку з нестандартним (вимірником або управляє) устаткуванням.
У комп'ютерах використовується різновид паралельного інтерфейсу під назвою Centronics, що відрізняється щодо високою швидкістю передачі даних (до 150 Кбайт/с) і простотою програмування. Правда, Centronics дозволяє передавати дані тільки в одному напрямі - з комп'ютера в пристрій, проте цю проблему можна частково вирішити, якщо скористатися для прийому даних лініями стану інтерфейсу.
Зрозуміло, в установці, що підключається до комп'ютера через паралельний інтерфейс, має бути передбачене пристрій сполучення, що сприймає і виробляє сигнали обміну з інтерфейсом.
Інтерфейс Centronics підключається до периферійного пристрою (принтеру) за допомогою кабелю, що містить 17 сигнальних ліній і декілька ліній нуля. Управління інтерфейсом здійснюється через три закріплених за ним порту: порту даних з адресою 378h, порту стану принтера з адресою 379h і порту управління принтером з адресою 37аh. Порти фактично є 8-розрядними регістрами, биті яких відповідають сигналам інтерфейсу. Деякі з цих сигналів, конкретно, сигнали портів даних і управління, є для інтерфейсу вихідними; їх повинна встановлювати програма, що управляє передачею інформації. Інші сигнали, навпаки, поступають з периферійного пристрою і відображаються в стані закріплених за ними бітів порту стану; програма повинна читати і аналізувати ці біти. На мал. 3.11 показані порти інтерфейсу Centronics з вказівкою сигналів, відповідним конкретним бітам.

Мал. 3.11. Порти інтерфейсу Centronics

Програмування паралельного інтерфейсу вимагає деяких відомостей про його протокол, тобто послідовності і взаємодії сигналів, якими інтерфейс обмінюється з підключеним до нього пристроєм. Деякі з цих сигналів мають вузько спеціалізоване призначення і виникають лише в особливих випадках (наприклад, сигнал РЕ - кінець паперу), інші ж беруть обов'язкову участь в процедурі передачі даних. До останніх відносяться 8 битий даних і три керівників сигналу STROBE', BUSY і АСЬК' (мал. 3.12).


Мал. 3.12. Протокол передачі даних для інтерфейсу Centronics.

Сигнал BUSY вважається за активний, коли він має високе значення. В протилежність цьому активний стан сигналів STROBE' і АСЬК' низький, чому вони і позначаються з тим або іншим додатковим значком (з межею вгорі, із знаком мінус або з апострофом, як у нас). Простежуючи відповідність сигналів інтерфейсу стану бітів його портів, необхідно мати на увазі, що для деяких сигналів (SLCT, РЕ, STROBE) в порти записуються їх прямі значення, а для інших (ERROR, АСЬК, BUSY) - інверсні.
Вивід на принтер кожного байта даних складається з трьох етапів. Перш за все програма повинна дочекатися неактивного стану сигналів BUSY і АСЬК (це і є очікування готовності пристрою). Переконавшись, що биті 6 і 7 порту стану 379h встановлені в 1 (див. мал. 3.11), програма посилає в порт даних 378h байт даних, що приводить до установки коди даних на лініях інтерфейсу D7...D0. Нарешті, програма повинна встановити на короткий час сигнал STROBE, що реалізується шляхом установки і потім скидання бита 0 порту управління 37all. Наступні байти посилаються таким самим чином.
Виконуючи всі ці операції, необхідно враховувати тимчасові характеристики інтерфейсу. Сигнал STROBE можна посилати в порт управління не раніше, чим через 0,5 мкс після установки даних, що може зажадати введенню в програму невеликої програмної затримки (однієї або декількох команд jmp, див. приведений нижче текст програми). То ж відноситься і до тривалості сигналу STROBE, яка не має бути менше тієї ж величини 0,5 мкс. Практично програмні затримки часто виявляються не потрібні.
Звернемося ще раз до мал. 3.12. Принтер, знявши з ліній даних байт даних, і почавши його обробку (вивід на друк або збереження у внутрішній пам'яті), встановлює у відповідь сигнал BUSY, що діє весь час, поки принтер зайнятий обробкою байта даних. Закінчивши обробку байта, принтер на деякий час встановлює сигнал АСЬК і скидає сигнал BUSY. Закінчення сигналу АСЬК (при скинутому стані сигналу BUSY) говорить інтерфейсу про закінчення даної операції обміну і про можливість посилки наступного байта даних. Зважаючи на стислість сигналу АСЬК часто виявляється, що чекати його зняття немає необхідності; досить дочекатися неактивного стану сигналу BUSY (тобто 1 в біті 7 порту стану). Взагалі слід відмітити, що різні принтери можуть декілька по разному виконувати свою частину протоколу обміну. Розглянутий нижче приклад відладжувався на принтері Epson Lq100.
Приведемо текст програми, в якій принтер програмується, як то кажуть, на фізичному рівні, тобто шляхом звернення до його портів. Зрозуміло, в більшості випадків для виводу на принтер тексту з виконуваної програми простіше скористатися функціями DOS. Проте в деяких спеціальних випадках доводиться вдаватися і до програмування через порти, наприклад, якщо принтер використовується в нестандартному режимі, або паралельний інтерфейс служить для зв'язку з нестандартним пристроєм.
У приведеному прикладі передбачається, що принтер вибраний і встановлений в початковий робочий стан, що зазвичай виконується автоматично при його включенні. Свідоцтвом цього будуть встановлені біти 2 і 3 (SLCT IN і INIT) в порту управління, а також битий 4 (SLCT) в порту стану. У програмі не виконується аналіз байта стану на наявність помилки або кінця паперу, що при роботі з принтером, взагалі кажучи, слід передбачати.
Третій метод програмування периферійного пристрою - режим переривань - розглянемо на прикладі обробки переривання від миші. Як відомо, миша зазвичай підключається до першого послідовного порту Сом1 і працює в режимі переривань. Натиснення або відпуск будь-якої клавіші, так само, як навіть мінімальне переміщення по столу, виробляє сигнали переривань, що супроводжуються певними кодами, які поступають в порт даних інтерфейсу. Написавши власний обробник переривань для послідовного порту, ми дістанемо можливість виконувати задані дії, наприклад, при натисненні лівої і правої клавіш миші. Слід підкреслити, що ці дії почнуть виконуватися практично в той же момент, коли ми натиснули на клавішу. У приведеній нижче програмі при натисненні лівої клавіші в центр екрану виводиться кольоровий напис "Лівий!", а при натисненні правої клавіші - напис "Правий" іншого кольору.
Для того, щоб приведена програма працювала, слід завантажити драйвер миші, який ініціалізував послідовний інтерфейс і саму мишу. До складу цього драйвера входить свій обробник переривань. Ми заміщаємо його адресу у векторі 0ch адресою нашого обробника, і оскільки в програмі не передбачено зчеплення обробників, на час дії програми стандартна обробка переривань від миші відключається. Перед завершенням програми вміст вектора 0сh відновлюється, і миша знову починає працювати, як завжди.
Кожне натиснення (або відпуск) клавіші миші, так само, як і її переміщення, насправді виробляють не поодинці, а по три послідовні переривання з різними кодами в порту даних інтерфейсу. Так, натиснення лівої клавіші миші дає послідовність код 60h, 0, 0, натиснення правої клавіші - послідовність 50h, 0, 0, відпуск будь-якої клавіші - 40h, 0, 0, переміщення вгору - 4ch, 0, 3fh, переміщення вниз - 40h, 0, 1 і так далі Таким чином, по-справжньому треба було зберігати в обробнику переривань всі три коди і потім аналізувати всю послідовність. Ми для простоти обмежилися аналізом тільки першої коди. Як видно з приведеного вище переліку, аналіз однієї коди не дає можливість відрізнити, наприклад, відпуск клавіші від переміщення вниз.
Коди, що генеруються мишею, можуть залежати від її типу, що треба враховувати при підготовці цього прикладу. Для набуття значень код, що генеруються, можна передбачити в обробнику переривань вивід їх на екран за допомогою функції переривання 10h BIOS, як це було зроблено, наприклад, в прикладі 3-5, або прямим виводом у відеобуфер. Слід тільки мати на увазі, що перехоплення будь-якого переривання від послідовного інтерфейсу повинне обов'язково супроводитися читанням з його порту даних, оскільки інтерфейс може прийняти черговий байт даних тільки після читання попереднього і звільнення свого регістра даних.

Приклад 3-12. Програмування миші в режимі переривань


.586 ;Будут команди нових процесорів
code segment use16 ;16-разрядное додаток
assume CS : code,ds:code ;Данные у сегменті команд
main proc
push CS ;Настроим DS
pop DS ;на сегмент команд
;Збережемо обробник переривань послідовного порту
mov Ax,350ch ;Функция 35h, вектор 0сh
int 21h
mov word ptr old_oc,bx ;Сохраним зсув
mov word ptr old_oc+2,es ;Сохраним сегмент
;Встановимо наш обробник переривань послідовного порту
mov Ax,25ось ;Функция 25h, вектор 0сh
mov Dx,offset new_0c ;Адрес нашого обробника
int 21h
;Остановим програму функцією введення з клавіатури
mov Ah,01h
int 21h
;Восстановим початковий обробник драйвера миші
mov Ax,250ch ;Функция 25h, вектор 0сh
Ids Dx,old_0c ;Сохраненный адреса
int 21h
mov Ax,4c00h ;Завершим програму
int 21h
main endp
new_0c proc
pusha ;Сохраним всі регістри
push DS ;Сегментные регістри не
push ES ;сохраняются командою pusha
mov Dx,3f8h ;Порт даних
in Al,dx ;Прочитаем
cmp AL, 60h ;Левая клавіша — код 60h
je Ibtn ;Переход на відробіток
cmp AL, 5oh ;Правая клавіша — код 5oh
je rbtn ;Переход на відробіток
;Завершення обробника переривань
outret:pop ES ;Восстановим сегментні
pop DS ;регистры
mov Al,20h ;Команда EOI
out 20h,al ;в контроллер переривань
рора ;Восстановим всі регістри
iret ;Выход з переривання
;Якщо натиснута ліва клавіша миші
Ibtn: mov АН, 1eh ;Атрибут символів жовтий по
; синьому
mov Si,offset msgdn ;Адрес рядка, що виводиться
jmp commn ;Ha загальну частину виводу
;Якщо натиснута права клавіша миші
rbtn: mov Ah,2eh ;Атрибут символів жовтий по
;зеленому
mov Si,offset msgdn ;Адрес рядка, що виводиться
;Загальна частина виводу на екран діагностичного рядка
commn: mov Bx,ob800h ;Настроим ES
mov Es,bx ;на відеобуфер
push CS ;Настроим DS
pop DS ;на наш сегмент
mov Cx,6 ;Число символів, що виводяться
mov Di,2000 ;Смещение на екрані
cld ;Движение вперед
scr: lodsb ;АL=очередной символ
stosw ;Из АХ на екран
loop scr ;Цикл
jmp outret ;После виводу завершити
;обробку переривання
new_0c endp
old_0c dd 0 ;Ячейка для початкового
;вектора
msgdn db "Ліва!" ;Выводимые повідомлення
msgup db "Права"
code ends
stk segment stack
dw 128 dup(O)
stk ends
end main

Приведений приклад з погляду його структури побудований звичайним способом. Початковий вміст вектора 0ch зберігається в осередку old_0c і використовується перед завершенням програми для відновлення вектора. Для спрощення установки обробника переривань програма написана без сегменту даних; її небагато даних розміщено в сегменті команд. Оскільки на початку програми регістр DS настроюється на сегмент команд, адресація до даних (у основній програмі) можлива через DS. Для того, щоб можна було спостерігати обробку переривань від миші, основна програма після виконання дій, що ініціалізували, зупиняється за допомогою функції 01h DOS очікування введення символу з клавіатури. Після натиснення будь-якої клавіші програма завершується, відновивши заздалегідь початковий стан вектора послідовного порту.
Дії, які повинні ініціюватися натисненням лівої або правої клавіш миші (наприклад, включення або виключення деякого устаткування), в програмі замінені виводом на екран коротких діагностичних повідомлень. Вивід здійснюється прямим записом у відеобуфер, оскільки, як вже мовилося раніше, в обробнику апаратних переривань не можна використовувати функції DOS і ризиковано - функції BIOS. Вивід на екран за допомогою команд обробки рядків lodsb і stosw вимагає налаштування великої кількості регістрів - в Ds:si повинна знаходитися адреса рядка-джерела, в Es:di адреса позиції у відеобуфері, в СХ число символів, що виводяться. Окрім цього, в обробнику переривань використовуються регістри АХ, ВХ і DX. Для збереження всіх регістрів загального призначення використовується команда pusha, а для їх відновлення команда рора. Проте ці команди не враховують сегментні регістри, і їх доводиться зберігати і відновлювати від діловими командами.
З відновленням регістрів може виникнути деяка складність. Обробник переривання повинен завершуватися посилкою в контроллер переривань команди EOI, а для цього необхідний регістр AL. Тому відновлення регістрів, в усякому разі, регістра АХ, необхідно виконувати після команди EOI. З іншого боку, команда EOI розблоковує рівні переривань, що пролягають нижче, в контроллері переривань (див. гл. 3), що може привести до проходження через контроллер чергового (вкладеного в наше) переривання, яке перерве наш обробник в крапці, де ще не відновлені регістри. Це неминуче приведе до краху системи. Проте в процесорі передбачені заходи усунення цього неприємного явища. Зупинимося на них детальніше.
Процесор, прийнявши будь-який сигнал переривання, скидає прапор IF в своєму регістрі прапорів, забороняючи тим самим всі апаратні переривання. Тому вхід в обробник переривань завжди здійснюється при заборонених перериваннях. Блокування рівнів, що пролягають нижче, в контроллері переривань просто накладається на цю загальну заборону і нових обмежень не вносить.
Якщо в тексті обробнику переривань немає команди дозволу переривань sti, то переривання будуть заборонені до самого його кінця, до завершуючої команди iret. Ця команда витягує із стека і відновлює початковий вміст регістрів Cs:ip, а також регістра прапорів. У момент переривання в регістрі прапорів був безумовно встановлений прапор IF, інакше переривання не могло б виникнути. Відновлення регістра прапорів приводить до установки цього прапора і дозволу всіх апаратних переривань, але вже після завершення обробника переривань. Таким чином, зняття апаратного блокування переривань командою EOI насправді не приводить до дозволу переривань, і будь-які рядки, що стоять після цієї команди, виконуються при заборонених перериваннях. В результаті жодних проблем з відновленням регістрів після команди EOI не виникає.
Зазвичай, проте, використовується інший варіант побудови обробника переривань. У цьому варіанті на початку програми обробника виконується команда sti, що встановлює прапор IF і що вирішує всі апаратні переривання, окрім тих, які заблоковані в контроллері переривань. В результаті програма обробника може бути перервана будь-яким перериванням більш високого рівня IRQ (тобто рівня з меншим номером), але не уривається сигналами переривань цього ж і нижчих рівнів. Така побудова обробників переривань зручна тим, що "важливіші" переривання, наприклад, від таймера або клавіатури, можуть бути оброблені без затримки. Для того, щоб виключити можливі неприємності з відновленням регістра АХ після команди EOI, перед нею переривання забороняються командою cli і структура обробника переривань набуває приблизно такого вигляду:

sti

pusha ;Сохранение регістрів

... ;Тіло обробника

cli ;Запрещение всіх переривань

mov Al,20h ;Команда EOI

out 20h,al ;контроллеру переривань

рора ;Восстановление регістрів

iret ;Возврат з обробника


Команди рора і iret виконуються в цьому випадку при заборонених перериваннях, але після відробітку команди iret в регістрі прапорів відновлюється його початковий вміст (у якому IF = 1), і переривання, таким чином, знову вирішуються.

-

:: Наша кнопка ::

Отримати код:

Підтримайте наш сайт і розмістіть нашу кнопку на своєму ресурсі.


:: Популярне ::

-


:: Посилання ::

-


 

 

 


Copyright © net.kr.ua, 2019-2025 (assem.us)