Вы находитесь на странице: 1из 608

Серия «Для программистов»

А$$етЫег
для ОО,
У т4о\$
и омх
Издание второе,
исправленное и дополненное

Зубков
Сергей Владимирович

т Мнь
излательство

Москва, 2000
ББК 32.973.26-018.1
391
Зубков С. В.
391 АззетЫет для О$, УЯо4о\з и ОМХ. - М.: ДМК Пресс, 2000. - 608 с.: ил.
(Серия «Для программистов»).
15ВМ 5-94074-003-0
В книге освещаются все аспекты современного программирования на ассембле-
ре для 2О$, УЙпдо\$ 95/МТ и ОМХ (Зоапз, Гацах и ЕгееВЗЬ), включая созда-
ние резидентных программ и драйверов, прямое программирование периферий-
ных устройств, управление защищенным режимом и многое другое. Детально
рассматривается архитектура процессоров Пие! вплоть до Репйит Ш. Все главы
иллюстрируются подробными примерами работоспособных программ.
Издание ориентировано как на профессионалов, так и на начинающих без опыта
программирования.
ББК 32.973.26-018.1

Все права защищены. Любая часть этой книги не может быть воспроизведена
в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения
владельцев авторских прав.
Материал, изложенный в данной книге, многократно проверен. Но, поскольку вероятность на-
личия технических и просто человеческих ошибок все равно существует, издательство не может
гарантировать абсолютную точность и правильность приводимых сведений. В связи с этим из-
дательство не несет ответственности за возможные ошибки, связанные с использованием книги.

© ДМК Пресс, 2000


15ВМ 5-94074-003-0 © Зубков С. В., 2000

Зубков Сергей Владимирович


А$зетЫег
для 00$, У\Уш4о\$ и ОМХ
Главный редактор Захаров И. М.
Научный редактор Шалаев Н. В.
Л итературный редактор Космачева Н. А.
ЛР № 01903 от 30.05.2000
Подписано в печать 12.07.2000. Формат 70х100'/,.
Гарнитура «Петербург». Печать офсетная.
Усл. печ. л. 38. Тираж 5000 экз. Зак. № 459
Издательство «ДМК Пресс», 105023, Москва, пл. Журавлева, 2/8

Отпечатано в полном соответствии


с качеством предоставленных диапозитивов
в ИПО «Профиздат»
109044, Москва, Крутицкий вал, 18.
Содержание

Введение ............................иииииииииининининиининиинин 11.


Глава 1. Предварительные сведения ................................. 13
1.1. Что нужно для работы с ассемблером ................... еаннане, 13
1.2. Представление данных в компьютерах ............. нии 14
1.2.1. Двоичная система счисления .......... ии лнииининининиииииннннниньь 14
1.2.2. Биты, байты и слова ........... и... алина иииининь лени 15
1.2.3. Шестнадцатеричная система счисления ..............ииииилиннннниниии 16
1.2.4. Числа со ‘знаком .............. ини линии ини лилинининннньн 17
1.2.5. Логические операции ................ нити зан ниачиуиининни нина 18
1.2.6. Коды СИМВОЛОВ ........... и алииннинниннниия ини нннннни 18
1.2.7. Организация памяти ............. ини 19

Глава 2. Процессоры ие! в реальном режиме ............... 20


2.1. Регистры процессора .........................ааилилииниииниилиннииниалини, 20
2.1.1. Регистры общего назначения .......... нина 20
2.1.2. Сегментные регистры .................ини ииииинииииининнии 22
2.1.3. Стек ........ ен нина ннляннь, 22
2.1.4. Регистр флагов ...............
ии ини анианининнийн И 23
2.2. Способы адресации ......................илиииниининиинииининниниии, 24
2.2.1. Регистровая адресация ............. и ниииниининьни 24
2.2.2. Непосредственная адресация ..................
ин нинииинньниннинннньь, 25
2.2.3. Прямая адресация ............. и иииинининиининиинииниининиииини
ни нинннннь 25
2.2.4. Косвенная адресация ............ нии лниинннни 25
2.2.5. Адресация по базе со сдвигом ............. и иниииииинниннининниниия 26
2.2.6. Косвенная адресация с масштабированием .................... не... 26
2.2.7. Адресация по базе с индексированием ................ и. .лининниниини 27
2.2.8. Адресация по базе с индексированием ,
и масштабированием ............ „нии нии нннииннанннь 27
2.3. Основные непривилегированные команды ....................... 28
2.3.1. Пересылка данных ......... изн ининии ини ину вниз ивы ти зи ити ити нк илов и важна 28
2.3.2. Двоичная арифметика ............. нина нии 34
2.3.3. Десятичная арифметика ........... линии иииининиииининизннининнини 38
41| ||| АззетЫег для 20$, МЛп4аоми5 и ИМХ
2.3.4. Логические операции ........... ини 41
2.3.5. Сдвиговые операции ........... нии 43
2.3.6. Операции над битами и байтами ....... линии ичииннннннии 45
2.3.7. Команды передачи управления ...............
ил. нинианиининнинининьа 47.
2.3.8. Строковые операции ............ и ииииииииининининнияни 54
2.3.9. Управление флагами ............ нина 57
2.3.10. Загрузка сегментных регистров .................. яние нина 59
2.3.11. Другие команды ....... иене 59
2.4. Числа с плавающей запятой ............ „ини щининиия :.:.. 63
2.4.1. Типы данных ЕРЦ .........
и ашьлнньнии линии аниинниннни .... 63
2.4.2. Регистры ЕРЦ ......... ини еанаювнини 65
2.4.3. Исключения ЕРЦ ........ нии 67
2.4.4. Команды пересылки данных ЕРЦ ..............иинининнинининннине 68
2.4.5. Базовая арифметика ЕРЦ ............... ни ининнннжннннннннни 70
2.4.6. Команды сравнения ЕРИЦ ............ и ниииннииннниенниннннниние 74
2.4.7. Трансцендентные операции ЕРЦ ...............иинниинининньне 76
2.4.8. Константы ЕРЦ ........... ини нииннннннннние нии 78
2.4.9. Команды управления ЕРЦ ............ ен ниииинииинниннниня 78
2.5. Расширение {А ММХ ................... или лииаиияни ...... 82
2.5.1. Регистры ММХ ............ ини нннининнинне 82
2.5.2. Типы данных ММХ ......... ини ниньннь 83
2.5.3. Команды пересылки данных ММХ ......... иены езениннянитьннни 83
2.5.4. Команды преобразования типов ММХ .............. иене 84
2.5.5. Арифметические операции ММХ ..............ньнниние ннннннннньн 85
2.5.6. Команды сравнения ММХ .............. и иниинииииниинининаннннии 88
2.5.7. Логические операции ММХ ............ ини 88
2.5.8. Сдвиговые операции ММХ ............ нижние нии 89
2.5.9. Команды управления состоянием ММХ .............. ини 90
2.5.10. Расширение АМО 30. ............. ии нииньннннне 90
2.6. Расширение 55Е ................ нии лиилиниинининния 91
2.6.1. Регистры 5$Е ....... ини ининннинннннни 91
2.6.2: Типы данных $5Е ......... ини инненинннние 92
2.6.3. Команды ЗЗЕ ....... ини нининнни ини 92
2.6.4. Определение поддержки 55Е ....... ини линии и. ‘105
2.6.5. Исключения ........ нение ининннинннинне 105

Глава 3. Директивы и операторы ассемблера .............. 106


3.1. Структура программы .............. ии 106
3.2. Директивы распределения памяти ....... лана ини 108
- 3.2.1. Псевдокоманды определения переменных ............
и иьнииинии 108
3.2.2. Структуры ......... ини ини ининнниннки 109
Содержание О ОИ ПОС
3.3. Организация программы ..........
и ..........
иниилииьнннинни: 110
3.3.1. Сегменты ............. линили
ии ленин ллинининь, 110
3.3.2. Модели памяти и упрощенные директивы
определения сегментов ................ нина нииннинннннниь 112
3.3.3. Порядок загрузки сегментов ..................инннииииииилнннининнии 114
3.3.4. Процедуры ................. ини нининининнннннннь, 115
3.3.5. Конец программы .................иллииииииниинлия
иинииинииии
линии 115
3.3.6. Директивы задания набора,допустимых команд ......... и. 116
3.3.7. Директивы управления программным счетчиком ................... 116
3.3.8. Глобальные объявления ........... ии ииннннииииниинининининьньнь, 117
3.3.9. Условное ассемблирование .................. и аяннннни 118
3.4. Выражения ................ лилии, 120
3.5. Макроопределения ...................... ини 121
3.5.1. Блоки повторений ................ линии лииинннниняннн 123
3.5.2. Макрооператоры ............ ини нишиннинииньньнь, 124.
3.5.3. Другие директивы, используемые в макроопределениях ....... 124
3.6. Другие директивы ................... ии 125
3.6.1. Управление файлами ............. нина ииинннининньшиньии.. 125
3.6.2. Управление листингом .......
а .......
ииинннниияилии лилии
.. 125
3.6.3. Комментарии .......... НА 126
Глава 4. Основы программирования для М$ 00$ ........ 127
4.1. Программа типа СОМ ..................... линии инииьцни, 128
4.2. Программа типа ЕХЕ ........ ни........
ииилилилинилиннинннлианьнинии
.. 130
4.3. Вывод на экран в текстовом режиме .................. лише, - 131
4.3.1. Средства 00$ ......... ини
......
иилааиинининия и иииеншинини 131
4.3.2. Средства ВОЗ .............. иена т нннинниннье: 134
4.3.3. Прямая работа с видеопамятью .......... ии.......
аляяниннинии, 139
4.4. Ввод с клавиатуры ............... ини 140
4.4.1. Средства 00$ ........ нии ии иилиинниананннни 140
4.4.2..Средства ВОЗ .............. ии илииниинннни 148
4.5. Графические видеорежимы ..........
и ........
иииииииинини, 151
4.5.1. Работа с УСА-режимами ............. лини нининииинииинниииияяннинннинии 151
4.5.2. Работа с ЗУСА-режимами ......... и.........
иияянянннянннннини 155
4.6. Работа с мышЬЮ ............. ии иииииинииииилининииииинилиниьннни 166
4.7. Другие устройства ......................илилииииииинилилиинилилилилиниинии 171.
4.7.1. Системный таймер ................ линии ллиининнинииинни 171
4.7.2. Последовательный порт ............. ини нии 178
4.7.3. Параллельный порт ................илилининииииниинннининиинининиьининини 181
6 | 11|] А55етЫег для 00$, ММпдом$ и ИМХ
4.8. Работа с файлами .............. лития
иияниинаянини ‚182
4.8.1. Создание и открытие файлов .................. еее 183
4.8.2. Чтение и запись в файл ......... ии нииаинанннннья ежи 186
4.8.3. Закрытие и удаление файла .................иннининитниннияе иене 187
4.8.4. Поиск файЛОВ ............. „иена ениининининииннь 188
4.8.5: Управление файловой системой .............
у. ииизиньиния ,еинченьни 192 _
4.9. Управление памятью ............... ии ииииииилиииниианиньнинннин 193
4.9.1. Обычная память ............ ини ники аинизнннннииненнни 193
4.9.2. Область памяти ЦМВ .............ииинининиинияииининининиининнии 195
4.9.3. Область памяти НМА ............. и ининииииии и иаиалананинииини 195
4.9.4. Интерфейс ЕМЗ ........... ини тнннание нанниннннние 196
4.9.5. Интерфейс ХМЗ ........... шили анинининаннь, 197
4. 10. Загрузка и выполнение программ и иинениининнни 202
4.11. Командные параметры и переменные среды .............. 208

Глава 5. Более сложные приемы программирования .. 212


5.1. Управляющие структуры ..................
линии нинининьнииниииьнинии 212
5.1.1. Структуры Е... ТНЕМ... ЕЁЗЕ .......... лилии ииилииининнииния 212
’ 5.1.2. Структуры САЗЕ ............ нии нив не нинив 213
5.1.3. Конечные автоматы .......... лилии
анини нии ниницинннньнинни 214
5.1.4. ЦИКЛЫ ....... нина аининами иннининьн, 215
5.2. Процедуры и функции ини анииннаннньни 216
5.2.1. Передача параметров .............. нина ииянииилиииинани нитиналью нании 216
5.2.2. Локальные переменные .............. ини ииияиинииининялньнитнньньннть:.. 221
5.3. Вложенные процедуры ................... лилии 222
‚ 5.3.1. Вложенные процедуры со статическими ссылками ................ 222
‚ 5.3.2. Вложенные процедуры с дисплеями . и иииниииниитнни 223
5.4. Целочисленная арифметика повышенной точности ..... 224
5.4.1. Сложение и вычитание ......... нии иианиинииииининнииненннннниии 225
5.4.2. Сравнение ..............ини ини нина нии ининни нанинннини 225
` 5.4.3. УМНОЖение ........... и ииинииииииининниинаненинининаянаанненния 226
5.4.4. Деление ...............изииииииининнини и нинаини нияжитинаньнь низы 227
5.5. Вычисления с фиксированной запятой ............... лиан 228
5.5.1. Сложение и вычитание ..............инннаниияниинииннния неее овиввзвизинньь 228
5.5.2. Умножение ........... наличии нии тввзннинини 228
5.5.3. Деление ................ или линии ини неннянининнн 229
5.5.4. Трансцендентные
Функции ............. линии инииииинитинниния 229
5.6. Вычисления с плавающей запятой ............. и аииньилини 233
Содержание Г! 7

5.7. Популярные алгоритмы ................ нии НН 238


5.7.1. Генераторы случайных чисел ............ ини 238
5.7.2. Сортировки ......... «нение 242

5.8. Перехват прерываний ....................... линии 245


5.8.1. Обработчики прерываний ......... . т инниннинниннннни* 246
и еинииннниние
5.8.2. Прерывания от внешних устройств ........ иен 249
5.8.3. Повторная входимостьь ........... ее е 253

5.9. Резидентные программы .......


1. ииеииииииииииини
........ нинин 256
5.9.1. Пассивная резидентная программа ........... «1... 256
5.9.2. Мультиплексорное прерывание .............. нение 262
5.9.3. Выгрузка резидентной программы из памяти .............. +... 276
5.9.4. Полурезидентные программы ......... иене 292
5.9.5. Взаимодействие между процессами ........... иене 297
5.10. Программирование на уровне портов ввода-вывода ....305
5.10.1. Клавиатура ........... или еиниинеиненнн 305
5.10.2. Последовательный порт ........... ини 309
5.10.3. Параллельный порт .......... +. 315
5.10.4. Видеоадаптеры УСА ................ ини т ииннннне. 316
5.10.5. Таймер ............ лин ии 331
5.10.6. Динамик .......... ини нива 335
5.10.7. Часы реального времени и СМОЗ-память ............... лечении 336
5.10.8. Звуковые платы ............... ини ини 339
5.10.9. Контроллер ОМА ............... нии 359
5.10.10. Контроллер прерываний ............... ини 366
5.10.11. ДжойСТИК ....... ленин 371
5.11. Драйверы устройств в ОО5 ................. ия 374
5.11.1. Символьные устройства .......... ини 375
5.11.2. Блочные устройства ......... нение 384

Глава 6. Программирование в защищенном режиме ... 388


6.1. Адресация в защищенном режиме .................. 4. 388

6.2. Интерфейс \УСР! ....... .......


нии иянеинние 391
...-
иииниииииииииия
6.3. Интерфейс ОРМГ .................. линии 394
6.3.1. Переключение в защищенный режим ........... ини 394
6.3.2. Функции ОРМ!Г управления дескрипторами ............ нение 395
6.3.3. Передача управления между режимами в ОРМ! .................. 396
6.3.4. Обработчики прерываний ......... ини иииииининиинннннн 398
6.3.5. Пример программы ........... ини 399
8111 АззетЫег для 00$, ММтдоми$ и ИМХ
6.4. Расширители 00$ ............. или линии 403
6.4.1. Способы объединения программы с расширителем иене 403
6.4.2. Управление памятью в ОРМГ ............. ини 405
6.4.3. Вывод на экран через линейный кадровый буфер ................ 406

Глава 7. Программирование для \Мпт4о\м5$ 95/МТ ......... 413


7.1. Первая программа ................... ини 413
7.2. Консольные приложения ............... ии 416
7.3. Графические приложения ................ иене 421
7.3.1. Окно типа Ме$задеВох .......... „ини 421
7.3.2. Окна ....... 4... нити 422
7.3.3. Меню .......... ли ни и ..... 427
7.3.4. Диалоги ...... ин и еезннининнинанинь 431
7.3.5. Полноценное приложение ............. нии 436
7.4. Динамические библиотеки ................... линии 451
7.5. Драйверы устройств ................ линии 457

Глава 8. Ассемблер и языки высокого уровня ............... 460


ии
8.1. Передача параметров ........ ........ .. 460
ииииииининии
8.1.1. Конвенция Разса! ........... нение 460
8.1.2. Конвенция С ....... ини 461
8.1.3. Смешанные конвенции ............. инь еанениннннь. ИА 463
8.2. Искажение имен ................. ее ния 463
8.3. Встроенный ассемблер ................. ии 463
...
ине нниииииииининт
8.3.1. Ассемблер, встроенный в Разса!........ ии 464
8.3.2. Ассемблер, встроенный ВС .......... еее 464

Глава 9. Оптимизация ................... ленин 465


9.1. Высокоуровневая оптимизация ................ иене 465
9.2. Оптимизация на среднем уровне ............+.ееееиниии 465
........
9.2.1. Вычисление констант вне цикЛа ......... ини 466
9.2.2. Перенос проверки условия в конец цикла ............. иене 466
9.2.3. Выполнение цикла задом`наперед ........ ......
уееиинннинниини е 466
9.2.4. Разворачивание циклов ........ ини 467
`9.3. Низкоуровневая оптимизация .......... ини, 468
9.3.1. Общие принципы низкоуровневой оптимизации ................... 468
9.3.2. Особенности архитектуры процессоров Репйит . .
и Репчит ММХ .......... ни и 471
9.3.3. Особенности архитектуры процессоров Репйит Рго
и РепНит И... 472
Содержание лия
Глава 10. Процессоры не! в защищенном режиме..
10.1. Регистры .......... нии: 476
10.1.1. Системные флаги ........- иен 476
10.1.2. Регистры‘управления памятью ........... и иниииинииниии 477
10.1.3. Регистры управления процессором ........... нение 478
10.1.4. Отладочные регистры ............. ии 480
10.1.5. Машинно-специфичные регистры .......... еее 481
10.2. Системные и привилегированные команды ................. 482
10.3. Вход и выход из защищенного режима .......................... 488
10.4. Сегментная адресация ...............
иен ииииииииинеинне 490
10.4.1. Модель памяти в защищенном режиме ................ ление 490
10.4.2. Селектор ......... ини 491
10.4.3. Дескрипторы ......... ине 491
10.4.4. Пример программы .............. линии 493
10.4.5. Нереальный режим ................ нии иене 497
10.5. Обработка прерываний и исключений ........................:.. 499
10.6. Страничная адресация ..................
4....еииииииинииннние 509
10.7. Механизм защиты ............ ини иниииииииенние 516
10.7.1. Проверка ЛИМИТОВ .................еиииниииииининнини 516
10.7.2. Проверка типа сегмента ..................неиииниииннннии 517
10.7.3. Проверка привилегий ............. ии: 517
10.7.4. Выполнение привилегированных команд ..............аинии 518
10.7.5. Защита на уровне страниц ............ ии 519
10.8. Управление задачами .................... линии 519
10.8.1. Сегмент состояния задачи ............. ини 519
10.8.2. Переключение задач ............... нии 521
........ 527
и иииаииинини
10.9. Режим виртуального 8086 .............
10.9.1. Прерывания в \86 ................. нии 527
10.9.2. Ввод-вывод в \86 .......... ини 528

Глава 11. Программирование


на ассемблере в среде ИМХ ....аанаие 529
11.1. Синтаксис АТ&Т ....... ния инииииииненнние 530
11.1.1. Основные правила ........... ини ин ниннннеиннннни 530
11.1.2. Запись команд ......... ин и 531
11.1.3. Адресация ....... ини ни и 532
11.2. Операторы ассемблера .................... ини 533
11.2.1. Префиксные, или унарные, операторы ............. нии. 533
11.2.2. Инфиксные, или бинарные, операторы ............. иене. 533
10 | 1 || || АззетЫег для 20$, \ММп4оми$ и УМХ
11.3. Директивы ассемблера ....................... лилии 534
11:3.1. Директивы определения данных .............
из инлииниинииинннинниея 534
11.3.2. Директивы управления символами ............... и инеиниининнинннья 535
11.3.3. Директивы определения секций .........: у зезенененаь: ааа 535
11.3.4. Директивы управления разрядностью ............. (ии. еилаинининия 536
11.3.5. Директивы управления программным указателем ............... 536
11.3.6. Директивы управления листингом ........... ии иниининяннинннния 536
11.3.7. Директивы управления ассемблированием ......................... 537
11.3.8. Блоки повторения .......... ини ининнннннине 537
11.3.9. Макроопределения ................
1. нии, 538
11.4. Программирование с использованием ПБс .................. 538
11.5. Программирование без использования ПБс ....... ние 540
11.6. Переносимая программа для УМХ ..................ииинаииинии, 543

Заключение .......................
ии иилилиьнлииниинининниий 558
Приложение 1. Таблицы символов ....................... ии 559
1. Символы АЗСИ ......... НИ 559
2. Управляющие символы АЗСИ .............
зи лиииаиниянияиниченине 560
3. Кодировки второй половины АЗСИ .................. еее: 561
4. Коды символов расширенного АЗСИ ................... нение. 564
5. Скан-коды клавиатуры ................ линии 565

Приложение 2. Команды ще! 80х86 ................................... 567


1. Общая информация о кодах команд .....................иьееининии 567
1.1. Общий формат команды процессора Ее! ................ ленин 567
1.2. Значения полей кода команды .......... ини: 567
1.3. Значения поля Мо9ВМ ..............ииниииинииннннниннннини 568
1.4. Значения поля ЭВ .............. и иеиииииииининененинениние. 569
2. Общая информация о скоростях выполнения ........ анна 570
3. Префиксы ................... лилии
иинининянииннннне 571
4. Команды процессоров И\е! 8088 - Реп#ит 1! .................... 572
Используемые. сокращения ..........................иииинньн 595

‘Глоссарий .................... лишили лилии. 599


Алфавитный указатель ........................иииааииинаинининь, 602
Введение
Первый вопрос, который задает себе человек, впервые услышавший об ассембле-
ре, - а зачем он, собственно, нужен? Особенно теперь, когда все пишут на С/С++,
Беры или других языках высокого уровня? Действительно очень многое можно
создать на С, но ни один язык, даже такой популярный, не может претендовать на
то, чтобы на нем можно было написать абсолютно все.
Итак, на ассемблере пишут:
О все, что требует максимальной скорости выполнения: основные компоненты .
компьютерных игр, ядра операционных систем реального времени и просто
критические участки программ;
О все, что взаимодействует с внешними устройствами: драйверы, программы,
работающие напрямую с портами; звуковыми и видеоплатами;
О все, что использует полностью возможности процессора: ядра многозадачных
операционных систем, ОРМ]-серверы и вообще любые программы, перево-
дящие процессор в защищенный режим;
О все, что полностью использует возможности операционной системы: виру-
сы иантивирусы, защиты от несанкционированного доступа, программы, об-
ходящие эти защиты, и программы, защищающиеся от данных программ;
Си многое другое. Стоит познакомиться с ассемблером поближе, как оказыва-
ется, что большую часть из того, что обычно пишут на языках высокого уров-
ня, лучше, проще и быстрее написать на ассемблере.
«Как же так? — спросите вы, прочитав последний пункт. — Ведь всем известно,
что ассемблер — неудобный язык, и писать на нем долго и сложно!» Попробуем
перечислить мотивы, которые обычно выдвигаются в доказательство того, что
ассемблер не нужен.
Говорят, что ассемблер трудно выучить. Любой язык программирования трудно
выучить. Легко выучить С или Реры после Разса|, потому что они похожи. А по-
пробуйте освоить Г4зр, Ко или Рго]ов, и окажется, что ассемблер в действитель-
ности даже проще, чем любой абсолютно незнакомый язык программирования.
Говорят, что программы на ассемблере трудно понять. Разумеется, на ассембле-
ре легко написать неудобочитаемую программу... точно так же, как и на любом дру-
гом языке! Если вы знаете язык и если автор программы нестарался ее запутать, то
понять программу будет не сложнее, чем если бы она была написана на Ваз{с.
Говорят, что программы на ассемблере трудно отлаживать. Программы на
ассемблере легко отлаживать - опять же при условии, что вы знаете язык. Более
того, знание ассемблера часто помогает отлаживать программы на других языках,
потому что оно дает представление о том, как на самом деле функционирует ком-.
пьютер и что происходит при выполнении команд языка высокого уровня.
ЕРИШИИИШИИ! — АззетыЫег для 00$, Мипдо\м$ и УМХ
Товорят, что современные компьютеры такие быстрые, что ассемблер больше
не нужен. Каким бы быстрым ни был компьютер, пользователю всегда хочется
большей скорости, иначе не наблюдалось бы постоянного спроса на еще более
мощные компьютеры. И самой быстрой программой на ‚данном оборудовании все-
гда будет программа, написанная на ассемблере.
Говорят, что писать на ассемблере сложно. В этом есть доля правды. Очень
часто авторы программ на ассемблере «изобретают велосипеды», программируя
заново элементарные процедуры типа форматированного вывода на экран или
генератора случайных чисел, в то время как программисты на С просто вызывают
стандартные функции. Библиотеки таких функций существуют и для ассемблера,
но они не стандартизированы и не распространяются вместе с компиляторами.
Говорят, что программы на ассемблере не переносятся. Действительно, в этом
заключается самая сильная и самая слабая сторона ассемблера. Во-первых, благо-
даря этой особенности программы на ассемблере используют возможности ком-
пьютера с наибольшей полнотой; во-вторых, эти же программы не будут работать
на другом компьютере. Стоит заметить, что и другие языки часто не гарантируют
переносимости - та же программа на С, написанная, например, под УЯпдо\з 95,
не скомпилируется ни на МасикозВ, ни на $С]. .
Далеко не всё, что говорят об ассемблере, является правдой, и далеко не все,
кто говорят об аесемблере, на самом деле знают его. Но даже ярые противники
согласятся с тем, что программы на ассемблере - самые быстрые, самые малень-
кие и могут то, что не под силу программам, созданным на любом другом языке
программирования.
`Эта книга рассчитана на читателей с разным уровнем подготовки - как на на-
чинающих, которые хотят познакомиться с ассемблером серьезно или желают
лишь написать пару программ, выполняющих необычные трюки с компьютером,
так и на профессиональных программистов, которые тоже найдут здесь интерес-
ные разделы.
Почти все, что надо знать об ассемблере, где-нибудь да объяснено, а также
объяснено многое из того, что не заботит большинство программистов. С одной
стороны, чтобы написать простую программу, не нужно знать язык и устройство
процессора в совершенстве, но, с другой стороны, по-настоящему серьезная рабо-
та потребует и основательной подготовки. Уровень сложности в этой книге воз-
растает от начала к концу, но в первой ее половине отдельные абзацы помечены
специальной пиктограммой ©), которая означает, что данный абзац лучше про-
пустить при чтении, если вы знакомитесь с ассемблером впервые. Впрочем, если
у вас есть время и желание выучить ассемблер с нуля, — читайте все по порядку.
Если же вам хочется немедленно приступить к написанию программ, начните
сразу с главы 4, но будьте готовы к тому, что иногда придется возвращаться к пре-
дыдущим главам за более подробным описанием Тех или иных команд. И нако-
нец, если вам уже доводилось программировать на ассемблере, — выбирайте то,
что интересно. |
Глава 1. Предварительные сведения
1.1. Что нужно для работы с ассемблером
Прежде всего вам потребуется ассемблер. Здесь самое время сказать, что язык
программирования, которым мы собираемся заниматься, называется «язык ассем-
блера» (аззетЫу 1апёиаре). Ассемблер — это программа, которая переводит текст
с языка, понятного человеку, в язык, понятный. процессору, то есть говорят, что
она переводит язык ассемблера в машинный код. Однако сначала в повседневной
речи, а затем и в литературе слово «ассемблер» стало также и названием самого
языка программирования. Понятно, что, когда говорят «программа на ассемблере»,
имеют в виду язык, а когда говорят «макроассемблер версии 6.13», имеют в виду
программу. Вместе с ассемблером обязательно должна быть еще одна программа —
компоновщик (ПпКег), которая и создает исполнимые файлы из одного или несколь-
ких объектных модулей, полученных после запуска ассемблера. Помимо этого для
разных целей могут потребоваться дополнительные вспомогательные программы —
компиляторы ресурсов, расширители ОО$ и тому подобное (см. табл. 1).
Трудно говорить о том, продукция какой из трех компаний (Вогапа, Мсгозой
или У’акот) однозначно лучше. С точки зрения удобства компиляции ТАЗМ луч-
ше подходит для создания 16-битных программ для 2О$, МА$М - для 32-бит-
ных программ для 2О$, МАЗМ - для УЛпао\. С точки зрения удобства про-
граммирования развитость языковых средств растет в ряду \\А$М - МАЗМ -
ТАЗМ. Все примеры программ в этой книге ностроены так, что можно использо-
вать любой из этих компиляторов.

Таблица 1. Ассемблеры и сопутствующие программы

00$, тазт или 11, фазт


16 бит пк (16 бит) ЧК УМК
фазт мат
00$, паз или п,
Ник (32 бита) и 90$х
Ник мк
32 бита : м\40$х 40549, ртодем,, 2гах или
НПК (16 бит) и 90$32
или 90$32 м40$Х
пам па$п386 или т! фазт мат
ИПК (32 бита) ЧткЗ2 МПК
ЕХЕ
гс | Ьгсс32 м\гС
фа5т мазт
Мпаом5 тазт386 или"! и й |
оц. Илк (32 бита) |
Шпк32
триб
чик
МЮ
м ГР] | Предварительные сведения
Разумеется, существуют и другие компиляторы, например бесплатно распрос-
траняемый в сети Гбеглеё МАЗМ или условно бесплатный А86, но пользоваться
ими проще, если вы уже знаете турбо- или макроассемблер. Бесплатно распрост-‹
раняемый СМИ ассемблер, баз, вообще использует совершенно непохожий син-
таксис, который будет рассмотрен в главе 11, рассказывающей о программирова-
нии для ОШХ.
Во всех программах встречаются ошибки. Если вы собираетесь не только
упражняться на примерах из книги, но и написать что-то свое, то вам рано или
поздно обязательно потребуется отладчик. Кроме поиска ошибок отладчики иног-
да применяют и для того, чтобы исследовать работу существующих программ. Бе- ,
зусловно, самый мощный отладчик на сегодняшний день — Зо СЕ от №Меяа ^
ЗоЁмаге. Это фактически единственный отладчик для УЛпо\ 95/МТ, позволя;
ющий исследовать все — от ядра УЛп4о\$ до программ на С++, поддерживающий
одновременно 16- и 32-битный код и т. п. Другие популярные отладчики, распро-
страняемые вместе с соответствующими ассемблерами, — Содеме\м (М$), Тафо
ПеБираег (ВоПап4) и \Мабсот ПеБиввег (Уабсот). . |
Еще одна особенность ассемблера, отличающая его от всех остальных языков
программирования, — возможность дизассемблирования. То есть, имея исполняе-
мый файл, с помощью специальной программы (дизассемблера) почти всегда мож
но получить ибходный текст на ассемблере. Например, можно дизассемблировать
ВТО5$ вашего компьютера и узнать, как выполняется переключение видеорежимов,
или драйвер для 2О$, чтобы написать такой же для УЛп4о\е. Дизассемблер не
является необходимой программой, но иногда очень удобно иметь его под рукой.
Лучшие дизассемблеры на сегодняшний день — боигсег от У Соттишсанопв и ТРА.
И наконец, последняя необязательная, но весьма полезная утилита — шестнад-
цатеричный редактор. Многие подобные редакторы (Не\, ргомем, ем, Вехи!)
имеют встроенный дизассемблер, так что можно, например, открыв в таком ре-
дакторе своютрограмму, посмотреть, как скомпилировался тот или иной участок
программы, поправить какую-нибудь команду ассемблера или изменить значения
констант и тут же, без перекомпиляции, запустить программу, чтобы посмотреть
на результат изменений.

1.2. Представление данных в компьютерах


Для того чтобы освоить программирование на ассемблере, следует познако-
миться с двоичными и шестнадцатеричными числами. Иногда в тексте програм-
мы можно обойтись и обычными десятичными числами, но без понимания того,
как на самом деле хранятся данные в памяти компьютера, очень трудно использо-
вать логические и битовые операции, упакованные форматы данных и многое
другое.

1.2.1. Двоичная система счисления


Практически все существующие сейчас компьютерные системы, включая [шие
используют для вычислений двоичную систему счисления. В их электрических
Представление данных в компьютерах 9 ЕЕ
цепях напряжение может принимать два значения, и эти значения назвали нулем
и единицей. Двоичная система счисления как раз и использует только эти две
цифры, а вместо степеней десяти, как в обычной десятичной системе, здесь при-
меняют степени двойки. Чтобы перевести двоичное число в десятичное, надо сло-
жить двойки в степенях, соответствующих позициям, где в двоичном стоят еди-
ницы. Например: |
100101116=1Ж27+0%26+0%25+1Ж21+0%23+1Ж22+1Х2'+1Х20=128+16+4+2+1=151

Для перевода десятичного числа в двоичное мож- Таблица 2. Перевод числа


из десятичной системы
но, например, разделить его на 2, записывая остаток
в двоичную
справа налево (см. табл. 2).
Чтобы отличать двоичные числа от десятичных, Остаток
в ассемблерных программах в конце каждого двоич- | 151/2 =75
ного числа ставят букву Б. 75/2 =37

1.2.2. Биты, байты и слова 37/2 = 18


18/2 =9
Минимальная единица информации называется 9/2 =4
битом. Бит принимает только два значения — обычно 4/2 =2
0и 1. На самом деле они совершенно необязательны —
2/2 =1
один бит может принимать значения «да» и «нет», по-
1/2 =0
казывать присутствие и отсутствие жесткого диска,
Результат: 100101116
а также является ли персонаж игры магом или вои-
ном — важно лишь то, что бит имеет только два значения. Но многие величины
принимают большее число значений, следовательно, для их описания нельзя
обойтись одним битом. ` ,
Единица информации размером 8 бит называется байтом. Байт - это мини-
мальный объем данных, который реально может использовать компьютерная
программа. Даже для изменения значения одного бита в памяти надо сначала
считать байт, содержащий его. Биты в байте нумеруют справа налево, от нуля
до семи, нулевой бит часто называют младшим битом, а седьмой — старшим
(см. рис. 1).
Так как всего в байте восемь бит, он может принимать до 28= 256 разных зна-
чений. Байт используют для представления целых чисел от 0 до 255 (тип ип$1рпед
сВаг в С), целых чисел со знаком от —128 до +127 (тип 15пе4 сВаг в С), набора
символов АЗСП (тип сВаг в С) или переменных, принимающих менее 256 значе-
ний, например для представления десятичных чисел от 0 до 99.
Следующий по размеру базовый тип данных - слово. Размер одного слова в про-
цессорах [пе] — два байта (см. рис. 2). Биты с 0 по 7 составляют младший байт
слова, а биты с 8 по 15 — старший. В слове содержится 16 бит, а значит, оно может

76543210
Рис. 1. Байт
16 | |1] |1 Предварительные сведения `
принимать до 2 = 65 536 разных значений. Слова используют для представле-
ния целых чисел без знака со значениями 0-65 535 (тип ипзепе4 зВогё в С), це-
лых чисел со знаком от —32 768 до +32 767 (тип зВогё шё в С), адресов сегментов
и смещений при 16-битной адресации. Два слова подряд образуют двойное слово,
состоящее из 32 бит, а два двойных слова — одно учетверенное слово (64 бита).
Байты, слова и двойные слова — основные типы данных, с которыми мы будем
работать.

Еще одно важное замечание: в компьютерах с процессорами Ги все дан-


ные хранятся так, что младший байт находится по младшему адресу, по-
этому слова записываются задом наперед, то есть сначала (по младшему
адресу) - последний (младший) байт, а потом (по старшему адресу) —
первый (старший) байт. Если из программы всегда обращаться к слову
как к слову, а к двойному слову как к двойному слову, это не оказывает ни-
какого влияния. Но если вы хотите прочитать первый (старший) байт из
слова в памяти, то придется увеличить адрес на 1. Двойные и учетверен-
ные слова записываются так же — от младшего байта к старшему.

15 87 0

Рис. 2. Слово

‚ 1.2.3. Шестнадцатеричная система счисления


Главное неудобство двоичной системы счисления - это размеры чисел, с ко-
торыми приходится обращаться. На практике с двоичными числами работают,
только если необходимо следить за значениями отдельных битов, а когда разме-
ры переменных превышают хотя бы четыре бита, используется шестнадцатерич-
ная система. Она хороша тем, что компактнее десятичной, и тем, что перевод
в двоичную систему и обратно происходит очень легко. В шестнадцатеричной
системе используется 16 «цифр» (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, А, В, С, О, Е, Е), и но-
мер позиции цифры в числе соответствует степени, в которую надо возвести
число 16, следовательно:

968 = 9Х 16 +6= 150.

Перевод в двоичную систему и обратно осуществляется крайне просто - вме-


сто каждой шестнадцатеричной цифры подставляют соответствующее четырех-
значное двоичное число:
ЭВ = 10016, 61 = 01106, 961 = 100101106

В ассемблерных программах при записи чисел, начинающихся с А, В, С, О, Е,


Е, вначале приписывается цифра 0, чтобы не перепутать такое число с названием
переменной или другим идентификатором. После шестнадцатеричных чисел ста-
вится буква В (см. табл. 3).
Представление данных в компьютерах 0 ООС
Таблица 3. Двоичные и шестнадцатеричные числа

> 00005
00015
00105
00116
01006
01016
01105
01115
10005
ю®хю
аьрьроютю
чо 10016
10105
10116
11005
1101Ь
11105
11116
ен
оплпьотл-Ъо 100006

1.2.4. Числа со знаком


Легко использовать байты, слова или двойные слова для представления целых
положительных чисел — от 0 до 255, 65 535 или 4 294 967 295 соответственно. Чтобы
применять те же самые байты или слова для представления отрицательных чисел,
существует специальная операция, известная как дополнение до двух. Для измене-
ния знака числа выполняют инверсию, то есть заменяют в двоичном представлении
числа все единицы нулями и нули единицами, а затем прибавляют 1.
Например, пусть используются переменные типа слова:
150 = 0096Н = 0000 0000 1004 01106
инверсия дает: 1111 1111 0110 10015
+1 = 1111 1111 0110 10106 = ОРРбАВ

Проверим, что число на самом деле —150: сумма с +150 должна быть равна
нулю:
+150 + (-150) = 00961 + ОРЕбАН = 100008

Единица в 16-м разряде не помещается в слово, следовательно, мы действн-


тельно получили 0. В данном формате старший (7-й, 15-й, 31-й для байта, слова.
двойного слова) бит всегда соответствует знаку числа: 0 — для положительных
и 1 — для отрицательных. Таким образом, схема с использованием дополнения 10
двух выделяет для положительных и отрицательных чисел равные диапазоны:
$
81111 . Предварительные сведения ..
—128...+127- для байта, —32 768...+32 767- для слов, —2 147 483.648...+2 147 483 647 _
ДЛЯ ДВОЙНЫХ СЛОВ.

1.2.5. Логические операции


Самые распространенные варианты значений, которые может принимать один
бит, — это значения «правда» и «ложь», используемые в логике, откуда происхо-
дят так называемые «логические операции» над битами. Так, если объединить
авду»и «правду» — получится «правда», а если объединить «правду» и «ложь»
— «правды» не получится. В ассемблере нам встретятся четыре основные опера-
ции —- И (АМО), ИЛИ (ОБ), «исключающее ИЛИ» (ХОВ) и отрицание (МОТ),
действие которых приводится в табл. 4.
Таблица 4. Логические операции

ОАМОО=0 = ОХОВ
0 =0
О АМО 1 =0 = 0 ХОВ 1=1
ТАМРО=О = 1 ХОН
0 =1
1 АМ 1 =1 = 1 ХОВ 1=0

Все перечисленные операции являются побитовыми, поэтому для выполнения


логического действия над числом надо перевести его в двоичный формат и про-
извести операцию над каждым битом, например:
Э6н АМО ОРИ = 100101106 АМО 000011116 = 000001106 = 061

1.2.6. Коды символов


Для представления всех букв, цифр и знаков, появляющихся на экране ком-
пьютера, обычно используется всего один байт. Символы, соответствующие зна-
чениям от 0 до 127, то есть первой половине всех возможных значений байта,
были стандартизированы и названы символами АЗСИ (хотя часто кодами АЗСИ
именуют всю таблицу из 256 символов). Сюда входят некоторые управляющие
коды (символ с кодом ОШ - конец строки), знаки препинания, цифры (симво-
лы с кодами 30 - 391), большие (41 - 5АБ) и маленькие (611 -— 7АЪ) латинс-
кие буквы. Вторая половина символьных кодов используется для алфавитов дру-
гих языков и псевдографики, набор и порядок символов в ней отличаются
в разных странах и даже в пределах одной страны. Например, для букв одного
только русского. языка существует пять вариантов размещения во второй поло-
вине таблицы символов АЗСП (см. приложение 1). Существует также стандарт,
использующий слова для хранения кодов символов, известный как ОМСОЛЕ
или 0С5-2, и даже двойные слова ((С$-4), но мы пока не будем на нем оста-
навливаться.
Представление данных в компьютерах |! ОТ
1.2.7. Организация памяти
Память с точки зрения процессора представляет собой последовательность
байтов, каждому из которых присвоен уникальный адрес со значениями от 0 до
232—1 (4 Гб). Программы же могут работать с памятью как с одним непрерывным
массивом (модель памяти Йаб) или как с несколькими массивами (сегментирован-
ные модели памяти). Во втором случае для задания адреса любого байта требует-
ся два числа — адрес начала массива и адрес искомого байта внутри массива. По-
мимо основной памяти программы могут использовать регистры - специальные
ячейки памяти, расположенные физически внутри процессора, доступ к которым
осуществляется не по адресам, а по именам. Но здесь мы вплотную подходим
к рассмотрению собственно работы процессора, о чем подробно рассказано в сле-
дующей главе. |
-

Глава 2. Процессоры Не!


в реальном режиме
Процессор [п&е! х86 после включения питания оказывается в так называемом ре- '
жиме реальной адресации памяти, или просто реальном режиме. Большинство
операционных систем сразу же переводит его в защищенный режим, позволяю-
щий им обеспечивать многозадачность, распределение памяти и другие функции.
Пользовательские программы в таких операционных системах часто работают
еще и в режиме У86, из которого им доступно все то же, что и из реального, кроме
команд, относящихся к управлению защищенным режимом. Следовательно, дан-
ная глава описывает реальный режим и \У86, то есть все, что доступно программи-
сту в подавляющем большинстве случаев, если он не проектирует операционную
систему или ОРМ1-сервер.

- 2.1. Регистры процессора


Начиная с 80386 процессоры Пие! предоставляют 16 основных регистров для
пользовательских программ плюс еще 11 регистров для работы с мультимедий-
ными приложениями (ММХ) и числами с плавающей запятой (ЕРО/МРХ). Все
команды так или иначе изменяют значения регистров, и всегда быстрее и удобнее
обращаться к регистру, чем к памяти.
Из реального (но не из виртуального) режима помимо основных регистров
доступны также регистры управления памятью (СОТК, ШТЕВ, ТК, ГОТВ), реги-
стры управления (СВО, СК1 - СКА), отладочные регистры (ОВО - ОВ7) и ма-
шинно-специфичные регистры, но они не применяются для решения повседнев-
ных задач и рассматриваются далее в соответствующих разделах.

2.1.1. Регистры общего назначения


32-битные регистры ЕАХ (аккумулятор), ЕВХ (база), ЕСХ (счетчик), ЕОХ
(регистр данных) могут использоваться без ограничений для любых целей - вре-
менного хранения данных, аргументов или результатов различных операций. На-
звания регистров происходят от того, что некоторые команды применяют их спе-
циальным образом: так, аккумулятор часто необходим для хранения результата
действий, выполняемых над двумя операндами, регистр данных в этих случаях
получает старшую часть результата, если он не умещается в аккумулятор, регистр-_
счетчик работает как счетчик в циклах и строковых операциях, а регистр-база —
при так называемой адресации по базе. Младшие 16 бит каждого из этих регист-
ров применяются как самостоятельные регистры с именами АХ, ВХ, СХ, ОХ. На
Регистры процессора | А ИИС
самом деле в процессорах 8086-80286 все регистры были 16-битными и называ-
лись именно так, а 32-битные ЕАХ - ЕБХ появились с введением. 32-битной ар-
хитектуры в 80386. Кроме этого, отдельные байты в 16-битных регистрах АХ -
ОХ тоже могут использоваться как 8-битные регистры и иметь свои имена. Стар-
шие байты этих регистров называются АН, ВН, СН, ПН, а младшие - АГ, ВТ. СГ.
От. (см. рис. 3).
Остальные четыре регистра — Е$] (индекс источника), ЕО! (индекс приемни-
ка), ЕВР (указатель базы), ЕЗР (указатель стека) — имеют более конкретное на-
значение и применяются для хранения всевозможных временных переменных.
Регистры Е$З1 и ЕП! необходимы в строковых операциях, ЕВР и ЕЗР - при рабо-
те со стеком (см. раздел 2.1.3). Так же как и в случае с регистрами ЕАХ - ЕПХ,
младшие половины этих четырех регистров называются $Т, ОТ, ВР и $Р соот-
ветственно, и в процессорах до 80386 только они и присутствовали

т ПО ЕТ
АХ

31 16 15 87 0
вх

|=)

ОХ |= |) |
"|

ЕЗГ

ВОТ
.

ЕВР

ЕЗР

Рис. 3. Регистры общего назначения


ТИ Процессоры И\е! в реальном режиме
2.1.2. Сегментные регистры
При использовании сегментированных моделей памяти для формирования лю-
бого адреса нужны два числа — адрес начала сегмента и смещение искомого байта
относительно этого начала (в бессегментной модели памяти Йа адреса начал всех
сегментов равны). Операционные системы (кроме РО5) могут размещать сегмен-
ты, с которыми работает программа пользователя, в разных местах памяти и даже
временно записывать их на диск, если памяти не хватает. Так как сегменты способ-
ны оказаться где угодно, программа обращается к ним, применяя вместо настоя-
щего адреса начала сегмента 16-битное число, называемое селектором. В процес-
сорах Пе] предусмотрено шесть 16-битных регистров — С$, 15, Е$, Е5, С$, 5$,
где хранятся селекторы. (Регистры Е$ и С$ отсутствовали в 8086, но появились
ужев 80286.) Это означает, что в любой момент можно изменить параметры, запи-
санные в этих регистрах.

@® В реальном режиме селектор каждого сегмента равен адресу его начала, де-
ленному на 16. Чтобы получить адрес в памяти, 16-битное смещение скла-
дывают с этим селектором, предварительно сдвинутым влево на 4. Таким
образом, оказывается, что максимальный доступный адрес в реальном ре-
жиме 2* — 1 = 1048 575. Для сравнения: в защищенном режиме адрес нача-
ла для каждого сегмента хранится отдельно, так что возможно 2% (64 Тб)
различных логических адреса в формате сегмент:смещение (программа оп-
ределяет до 16 383 сегментов, каждый из которых до 4 Гб), хотя реально
процессор адресуется только к 4 или 64 (для Репнит Рго) Гб памяти.

В отличие от Б$, Е$, С$, Е$, которые называются регистрами сегментов дан-
ных, С5 и 55 отвечают за сегменты двух особенных типов -— сегмент кода и сегмент
стека. Первый содержит программу, исполняющуюся в данный момент, следова-
тельно, запись нового селектора в этот регистр приводит к тому, что далее будет
исполнена не следующая по тексту программы команда, а команда из кода, нахо-
дящегося в другом сегменте, с тем ‘же смещением. Смещение очередной выпол-
няемой команды всегда хранится в специальном регистре.ЕТР (указатель инст-
рукции, 16-битная форма ГР), запись в который также приведет к тому, что далее
будет исполнена какая-нибудь другая команда. На самом деле все команды пере-
дачи управления — перехода, условного перехода, цикла, вызова подпрограммы
ит. п. — и осуществляют эту самую запись в С$ и ЕР.
2.1.3. Стек
Стек — организованный специальным образом участок памяти, который ис-
пользуется для временного хранения переменных, передачи параметров вызыва-
емым подпрограммам и сохранения адреса возврата при вызове процедур и пре-
рываний. Легче всего представить стек в виде стопки листов бумаги (это одно из
значений слова «5(асК» в английском языке) — вы можете класть и забирать листы
только с вершины стопки. Поэтому, если записать в стек числа 1, 2, 3, то при чте-
нии они окажутся в обратном порядке - 3, 2, 1. Стек располагается в сегменте па-
мяти, описываемом регистром 5$, и текущее смещение вершины стека отражено

#
Регистры процессора — | 23
в регистре Е$Р, причем во время записи значение этого смещения уменьшается.
то есть он «растет вниз» от. максимально возможного адреса (см. рис. 4). Такое
расположение стека «вверх ногами» может быть необходимо, к примеру, в бес-
сегментной модели памяти, когда все сегменты, включая сегменты стека и кода,
занимают одну итту же.область — память. целиком. Тогда программа исполняет-
ся в нижней области памяти, в области малых адресов, и ЕР растет, а стек распо-
лагается в верхней области памяти, и Е$Р уменьшается.
При вызове подпрограммы параметры в большинстве случаев помещают в стек,
ав ЕВР записывают текущее значение ЕЗР. Если подпрограмма использует стек
для хранения локальных переменных, Е5Р изменится, но ЕВР можно будет ис-
пользовать для того, чтобы считывать значения параметров напрямую из стека
(их смещения занишутся как ЕВР + номер параметра). Более подробно вызовы
подпрограмм и все возможные способы передачи параметров рассмотрены в раз-
деле 5.2.1
Дно стека
ОРЕЕЕЕЕЕСВ
ОРЕЕЕЕРЕЗВ
Параметры-
ОЕРЕРЕРЕДЬ
ОЕЕЕЕЕЕЕОВ == _—— ЕВР=0ЕЕЕЕЕЕРОВ

ОЕЕЕРЕРЕСЬ
Локальные переменные
ОРЕРЕЕЕЕВВ
ОЕЕЕЕЕРЕДВ < ЕЗР=ОЕЕЕРЕЕАВ

| Рис. 4. Стек

2.1.4. Регистр флагов


Еще один важный регистр, использующийся при выполнении большинства ко-
манд, — регистр флагов. Как и раньше, его младшие 16 бит, представлявшие собой
весь этот регистр до процессора 80386, называются ЕГАС5. В ЕЕГАС$ каждый
бит является флагом, то есть устанавливается в 1 при определенных условиях или
установка его в 1 изменяет поведение процессора. Все флаги, расположенные
в старшем слове регистра, имеют отношение к управлению защищенным режи-
мом, поэтому здесь рассмотрен только регистр ЕГАСЗ (см. рис. 5):
Я СЕ - флаг переноса. Устанавливается в 1, если результат предыдущей опера-
ции не уместился в приемнике и произошел перенос из старшего бита или

Гоеаоея оо [ее 52
15 : | |
Рис. 5. Регистр флагов ЕЕАС$
РИМИШИШШИИ | Процессоры Не]! в реальном режиме
если требуется заем (при вычитании), в противном случае - в 0. Например,
после сложения слова ОЕЕЕЕК и 1, если регистр, в который надо поместить
результат, — слово, в него будет записано 0000 и флаг СЕ = 1..
ОРЕ - флаг четности. Устанавливается в 1, если младший байт результата
предыдущей команды содержит четное число битов, равных 1, ив 0, если
нечетное. Это не то же самое, что делимость на два. Число делится на два
без остатка, если его самый младший бит `равен нулю, и не делится, когда он
равен 1.
ОСАЕ-— флаг полупереноса или вспомогательного переноса. Устанавливается
в 1, если в результате предыдущей операции произошел перенос (или заем)
из третьего бита в четвертый. Этот флаг используется автоматически коман-
дами двоично-десятичной коррекции.
о 7Е - флаг нуля. Устанавливается в 1, если результат предыдущей команды —
НОЛЬ. |
О5Е- флаг знака. Он всегда равен старшему биту результата.
ОТЕ- флаг ловушки. Он был предусмотрен для работы отладчиков, не ис-
пользующих защищенный режим. Установка его в 1 приводит к тому, что
после выполнения каждой программной команды управление временно пере-
дается отладчику (вызывается прерывание 1 - см. описание команды 1МТ).
ОТЕ - флаг прерываний. Сброс этого флага в 0 приводит к тому, что процессор
перестает обрабатывать прерывания от внешних устройств (см. описание ко-
манды ПМТ). Обычно его сбрасывают на короткое время для выполнения
критических участков кода.
орЕ - флаг направления. Он контролирует поведение команд обработки
строк: когда он установлен в 1, строки обрабатываются в сторону уменьше-
ния адресов, когда ОЕ = 0 — наоборот.
СОР - флаг переполнения. Он устанавливается в 1, если результат предыду-
щей арифметической операции над числами со знаком выходит за допусти-
мые для них пределы. Например, если при сложении двух положительных
чисел получается число со старшим битом, равным единице, то есть отрица-
тельное, и наоборот.

Флаги ТОРТ. (уровень привилегий ввода-вывода) и МТ (вложенная задача)


` применяются в защищенном режиме.

2.2. Способы адресации


Большинство команд процессора вызываются с аргументами, которые в ассем-
-блере принято называть операндами. Например: команда сложения содержимого
регистра с числом требует задания двух операндов — содержимого регистра и чис-
ла. Далее рассмотрены все существующие способы задания адреса хранения опе-
рандов — способы адресации.
2.2.1. Регистровая адресация
Операнды могут располагаться в любых регистрах общего назначения и сегмент-
ных регистрах. Для этого в тексте программы указывается название соответствующего
Способы адресации 125
регистра, например: команда, копирующая в регистр АХ содержимое регистра ВХ,
записывается как
моу ах, Вх

2.2.2. Непосредственная. адресация


Некоторые команды (все арифметические, кроме деления) позволяют ука-
зывать один из операндов непосредственно в тексте программы. Например:
команда
оу ах, 2

помещает в регистр АХ число 2.

2.2.3. Прямая адресация


Если у операнда, располагающегося в памяти, известен адрес, то его можно
использовать. Если операнд - слово, находящееся в сегменте, на который указы-
вает Е$, со смещением от начала сегмента 0001, то команда
поУ ах,
ез :0001

поместит это слово в регистр АХ. В реальных программах для задания статичес-
ких переменных обычно используют директивы определения данных (раздел 3.3),
которые позволяют ссылаться на статические переменные не по адресу, а по име-
ни. Тогда, если в сегменте, указанном в Е$, была описана переменная мо г4_уаг
размером в слово, можно записать ту же команду как
мо\у ах, ез: чогд_\уаг

В таком случае ассемблер сам заменит слово могд_уаг на соответствующий


адрес. Если селектор сегмента данных находится в 05, то имя сегментного реги-
стра при прямой адресации можно не указывать, 0$ используется по умолча-
нию. Прямая адресация иногда называется адресацией по смещению.
Адресация отличается для реального и защищенного режимов. В реальном
(так же как и в режиме \86) смещение всегда 16-битное. Это значит, что ни не-
посредственно указанное смещение, ни результат сложения содержимого разных
регистров в более сложных методах адресации не могут превышать границ слова.
При работе в \УЛпао\з, 0О$4С, РМОПЕ и в других ситуациях, ‘когда программа
будет запускаться в защищенном режиме, смещение не должно превышать гра-
ниц двойного слова.
2.2.4. Косвенная адресация
По аналогии с регистровыми и непосредственными операндами адрес операн-
са в памяти также можно не указывать, а хранить в любом регистре. До процессо-
ра 80386 для этого можно было использовать только ВХ, $1, ОГ и ВР но потом
ограничения были сняты и адрес операнда разрешили считывать также из ЕАХ,
ЕВХ, ЕСХ, ЕОХ, ЕЗ1, ЕП, ЕВР и ЕЗР (но не из АХ, СХ, ОХ или $Р напрямую —
нало использовать ЕАХ, ЕСХ, ЕОХ, Е$ЗР соответственно или предварительно ско-
пировать смещение в ВХ, $1, ОГ или ВР). Например, следующая команда помещает
РОЗНИ ИИШИВИШИ — Процессоры име! в реальном режиме
в регистр АХ слово из ячейки памяти, селектор сегмента которой находится в05,
а смещение - в ВХ:
оу ах, [6х] ии ЕО АЫ

Как и в случае с прямой адресацией, 0$ используется по умолчанию, но.не


всегда: если смещение берут из регистров Е$Р, ЕВР или ВР, то в качестве сегмен-.
тного. регистра применяется 5$. В реальном режиме можно свободно работать со
всеми 32-битными регистрами, надо только следить, чтобы их содержимое не прё-
вышало границ 16-битного слова.

2.2.5. Адресация по базе со сдвигом


Теперь скомбинируем два предыдущих метода адресации. Следующая команда
Мом ах, [6х+2]
помещает в регистр АХ слово, которое есть в сегменте, указанном в`05, со смеще-
нием на два больше, чем число из ВХ. Так как слово занимает ровно 2 байта, эта
команда поместила в АХ слово, непосредственно следующее за тем, которое было-
в предыдущем примере. Такая форма адресации используется в тех случаях, ког-
да в регистре находится адрес начала структуры данных, а доступ надо осуще-
ствить к какому-нибудь ее элементу. Еще один вариант применения адресации по
базе со сдвигом — доступ из подпрограммы к параметрам, переданным в стеке, ис-
пользуя регистр ВР (ЕВР) в качестве базы и номер параметра в качестве смеще-
ния, что детально рассмотрено в разделе 4.3.2. Другие допустимые формы записи
этого ‚ способа адресации:
оу ах, [6р]+2
оу ах, 2[6р

До процессора 80386 в качестве базового регистра разрешалось-использовать


только ВХ, ВР, $1 или О! и сдвиг мог быть только байтом или словом (со знаком).
Начиная с 80386 и старше, процессоры Пие| позволяют дополнительно использо-
вать ЕАХ, ЕВХ, ЕСХ, ЕОХ, ЕВР, Е$Р, Е $1 и ЕП], так же как и для обычной косвен-
ной адресации. С помощьюуэтого метода разрешается организовывать доступ К од-`
номерным массивам Я, смещение соответствует адресу начала массива,
а число в регистре — индексу элемента массива, который надо считать. Очевидно,
что, если массив состоит не из байтов, а из слов, придется умножать базовый ре-
гистр на два, а если из двойных слов — на четыре. Для этого предусмотрен специ-
альный метод — косвенная адресация.

2.2.6. Косвенная адресация с масштабированием


| Этот метод адресации полностью идентичен предыдущему, однако с его помо-
щью можно прочитать элемент массива слов, ДВОЙНЫХ слов или учетверенных
слов, просто поместив номер элемента в регистр:
| поу ах, [ез1*2 ]+2 | .

Множитель, который равен 1, 2, 4 или 8, соответствует размеру элемента мас-


сива — байту, слову, двойному или учетверенному слову. Из регистров в этом
Способы адресации 1 В А ВИ ПИ ИЕ
варианте адресации можно использовать только ЕАХ, ЕВХ, ЕСХ, ЕОХ, ЕЗ1, ЕТ,
ЕВР, Е$Р, но не $1, ПИ, ВР или $Р.

2.2.7. Адресация по базе с индексированием


В этом методе адресации смещение операнда в памяти вычисляется как сумма
чисел, содержащихсяв двух регистрах, и смещения, если оно указано. Все перечис-
ленные ниже команды представляют собой разные формы. записи одного и того же
действия:

моу ах, [6х+$1+2]


[1 ах,[6х][$1]+2
оу ах, [6х+2][$1]
МОУ ах, [6х] [$1+2]
ЮУ ах, 2[6х] [$1]

В регистр АХ помещается слово из ячейки памяти со смещением, равным сум-


ме чисел, содержащихся в ВХ, $1, и числа 2. Из 16-битных регистров так можно
складывать только ВХ + $1, ВХ + 11, ВР + $1 и ВР + ПГ, аиз 32-битных - все
восемь регистров общего назначения. Как и для прямой адресации, вместо непос-
редственного указания числа разрешено использовать имя переменной, заданной
одной из директив определения данных. Таким образом можно считать, напри-
мер, число из двумерного массива: если задана таблица 10х10 байт, 2 — смещение
ее начала от начала сегмента данных (на практике будет использоваться имя этой
таблицы), ВХ = 20, а $1 = 7, приведенные команды прочитают слово, состоящее
из седьмого и восьмого байтов третьей строки. Если таблица состоит не из оди-
ночных байтов, а из слов или двойных слов, удобнее использовать наиболее пол-
ную форму - адресацию по базе с индексированием и масштабированием.

2.2.8. Адресация по базе


с индексированием и масштабированием
Это самая полная схема адресации, в которую входят все случаи, рассмотрен-
ные ранее как частные. Полный адрес операнда можно записать как выражение,
представленное на рис. 6.
Смещение может быть байтом или двойным словом. Если ЕЗР или ЕВР ис-
пользуются в роли базового регистра, селектор сегмента операнда берется по
умолчанию из регистра 55, во всех остальных случаях - из 0$.

ЕАХ БАХ
С8: | ЕВХ
$$: | ЕСХ
ВХ |
ЕОХ ЕСХ 2
25 + ЕБХ * + смещение
Е$:| ЕВР Е ВР 4

сы 8
ЕП

ЕЯ

Рис. 6. Полная форма адресации


281111] Процессоры Н\е! в реальном режиме
2.3. Основные непривилегированные команды
В этом разделе описаны все непривилегированные команды процессоров ие!
серии х86, включая команды расширений ГА МРХ (чаще называемое ЕРУ - рас-
ширение для работы с.числами с плавающей запятой) и ТА ММХ (мультимедий-
ное расширение). Для каждой команды указана форма записи, название и модель
процессоров. [пе], начиная с которой она поддерживается: 8086, 80186, 80286,
80386, 80486, Р5 (Репиит), ММХ, Р6 (Репиит Рго и Репа П).

2.3.1. Пересылка данных


Команда . Назначение | Процессор
МОУ приемник, источник Пересылка данных 8086

Базовая команда пересылки данных. Копирует содержимое источника в при- |


емник, источник не изменяется. Команда МОУ действует аналогично операторам
присваивания из языков высокого уровня, то есть команда |
|
моу ‚ ах, 6х

эквивалентна выражению

ах:=6х; |

языка Разса! или


ах=Ьх;

языка С, за исключением того, что команда ассемблера позволяет работать не


только с переменными в памяти, но и со всеми регистрами процессора.
В качестве источника для МОУ могут использоваться: число (непосредствен-
ный операнд), регистр общего назначения, сегментный регистр.или переменная
(то есть операнд, находящийся в памяти); в качестве приемника: регистр общего
назначения, сегментный регистр (кроме С$) или переменная. Оба операнда дол-
‚ жны быть одного и того же размера — байт, слово или двойное слово.
Нельзя выполнять пересылку данных с помощью МОТУ из одной переменной
в другую, из одного сегментного регистра в другой и нельзя помещать в сегмент-
ный регистр непосредственный операнд -— эти операции выполняют двумя коман-
дами МОУ (из сегментного регистра в обычный и уже из него в другой сегмент-
ный) или парой команд РОЗН/РОР. |

@& Загрузка регистра 55 командой МОУ автоматически запрещает прерывания


до-окончания следующей за ней команды МОТ, поэтому можно не опасаться,
что в этот момент произойдет прерывание, обработчик которого получит
неправильный стек. В любом случае для загрузки значения в регистр 55 пред-
почтительнее команда [55.

Команда °’ Назначение Процессор


_ СМО\сс приемник, источник ° Условная пересылка данных Рб
+

Непривилегированные команды Г]| | 29


Это набор команд, которые копируют содержимое источника в приемник, если
удовлетворяется то или иное условие (см. табл. 5). Источником может быть ре-
гистр общего назначения или переменная, а приемником — только регистр. Тре-
бование; которое должно выполниться, — просто равенство нулю или единице тех
или иных флагов из.регистра ЕТ.АС$, но, если использовать команды СМО\Усс
сразу после СМР (сравнение) с теми же операндами, условия приобретают осо-
бый смысл, например:
стр ах, 5х ; Сравнить ах и Бх.
стом] ах, 6х ; Если ах < 6х, скопировать Бх в ах.

Слова «выше» и «ниже» в табл. 5 относятся к сравнению чисел без знака, сло-
ва «больше» и «меньше» учитывают знак.

Таблица 5. Разновидности команды СМО\Усс

|| СМО\МА = = Если выше


|СМОУМВЕ СР=бийЕ=0 Если не ниже и не равно
| СМОУАЕ Если выше или равно
|СМОУМВ СЕ=0 Если не ниже
|СМОУМС Если нет переноса
|СМОУВ . | Если ниже
| СМОУМАЕ СЕ=1 Если не выше и не равно
+ СМОУС | Если перенос
; СМОУВЕ м _ Если ниже или равно
{ СМОУМА СЕ = Т или 22 = 1 Если не выше
СМОУЕ 7Е=1 Если равно
‚ СМО\У2 Если ноль
|смоУуе Если больше
СМОУМЕЕ 2Е=Ои5Е = ОР. Если не меньше и не равно
' СМОУСЕ ЗЕ = ОЕ Если больше или равно
+ СМОУМЕ Если не меньше
| СМОМЕ . Если меньше:
‚ СМОУМСЕ ЗЕ <> ОЕ Если не больше и не равно
+: СМОМЕЕ _ Если меньше или равно
‹ СМОУМ@ 2Е = 1 или ЗЕ <> ОР Если не больше
|СМОУМЕ 7Е=0 Если не равно
; СМОММ2 . ‚ | Если не ноль
|
р СМОММО ОЕ=0 Если нет . переполнения
|смоУо . ОЕ=1 Если есть переполнение
СМОУМР РЕ=О Если нет четности
СМОУРО Если нечетное
| СМОУР РЕ= : ‚.| Если есть четность
СМОУ\УРЕ Если четное
; СМОУМ$ ЗЕ =0 Если нет знака
р —.
} СМО\У$ $Е = „_ [Если есть знак
ЕГИШИИ
И И ИИИ — Процессоры пе в реальном режиме
8
Команда Назначение | Процессор
ХСНС операнд1, операнд? Обмен операндов между собой | , 8086

Содержимое операнда 2 копируется в операнд 1,’а старое содержимое операн-


да 1 - в операнд 2. ХСНС можно выполнять над двумя регистрами или над реги-
стром и переменной.
хСпа вах, ебх ; То же, что три.‘команды на’ языке С:
‚; Тетр = еах;еах = ебх;ебх = Тетр.
хспа а1, а1 ; А эта команда ничего не делает.

Команда Назначение — Процессор


——_и
ВУ\МАР регистр32 Обмен байтов внутри регистра 80486

Обращает порядок байтов в 32-битном регистре. Биты 0-7 (младший байт


младшего слова) меняются местами с битами 24-31 (старший байт старшего
слова), а биты 8-15 (старший байт младшего слова) — с битами 16-23 (младший .
байт старшего слова).
тоу еах, 123456788
Ьзиар еах ; Теперь в еах находится 785634121.
о
л
Чтобы обратить порядок байтов в 16-битном регистре, следует использовать
команду ХСНС:
хсНа а1, ай ,‹ Обратить порядок байтов в АХ.
В процессорах [бе] команду В$\УГАР. можно использовать и для обращения
порядка байтов в 16-битных регистрах, но в некоторых совместимых процессорах
других фирм этот вариант не реализован.
Команда Назначение | и Процессор
РУЗН источник . Поместить данные в стек | 8086

Помещает содержимое источника в стек. Источником может быть регистр, сег-


ментный регистр, непосредственный операнд или переменная. Фактически эта ко-
манда уменьшает Е$Р на размер источникав байтах (2 или 4) и копирует содер-
жимое источника в память по адресу $53: Е$Р]. Команда РОЗН почти всегда
используется в паре с РОР (считать данные из стека). Поэтому, чтобы скопиро-
вать содержимое одного сегментного регистра в другой (что нельзя выполнить од-
ной командой МОУ), можно использовать такую последовательность команд:
‚ ризй 6$ :
рор_ 95 ; Теперь 05 указывает. на тот же сегмент, ‘что и 55.

Другой вариант применения команд РОЗН/РОР - временное хранение пере-'.


менных, например:
ризв ° вах ; Сохраняет текущее значение ЕАХ.
Г. ; Здесь располагаются какие-нибудь команды,
: которые используют ЕАХ, например СМРХСНС.
рор “’`вах’”. ` ; Восстанавливает старое значение ЕАХ.
Непривилегированные команды |3
Начиная с процессора 80286 команда РОЗН ЕЗР (или ЗР) помещает в стек
значение ЕЗР до того, как она же его уменьшит, а на 8086 регистр ЗР располагал-
ся в стеке уже уменьшенным на два.

Команда | | Назначение — | Процессор


РОР приемник Считать данные из стека 8086

Помещает в приемник слово или двойное слово, находящееся в вершине сте-


ка, увеличивая ЕЗР на 2 или 4 соответственно. РОР выполняет действие, полно-
стью обратное РОЗН. Приемником может быть регистр общего назначения, сег-
ментный регистр, кроме С$ (чтобы загрузить С$ из стека, надо воспользоваться
командой ВЕТ), или переменная. Если в роли приемника выступает операнд, ис-
пользующий ЕР для косвенной адресации, команда РОР вычисляет адрес опе-
ранда уже после того, как она увеличивает ЕЗР.
Команда Назначение , Процессор
—ждд
т

РИЗНА Поместить в стек. 80186


РУЗНАО все регистры общего назначения 80386

РУЗНА располагает в стеке регистры в следующем порядке: АХ, СХ, ОХ, ВХ,
$Р, ВР ЗГи 01. РОЗНАР помещает в стек ЕАХ, ЕСХ, ЕМОХ, ЕВХ, Е$ЗР ЕВР ЕЗ1
нЕПТ. (В случае с ЗРи ЕЗР используется значение, которое находилось в регист-
ре до начала работы команды.) В паре с командами РОРА/РОРАР, считывающи-
ми эти же регистры из стека в обратном порядке, это позволяет писать подпро-
граммы (обычно обработчики прерываний), которые не должны изменять
значения регистров по окончании своей работы. В начале такой подпрограммы
вызывают команду РОЗНА, а в конце - РОРА.

На самом деле РИ5НА и РИ$НАО - одна и та же команда с кодом 60#.


© Ее поведение определяется тем, выполняется ли она в 16- или в 32-битном
режиме. Если программист использует команду РИЗНАЛ в 16-битном сегмен-
те или РИ$ЗНА в 32-битном, ассемблер просто записывает перед ней префикс
изменения размерности операнда (66й). Это же будет распространяться
на некоторые другие пары команд: РОРА/РОРАО, РОРЕ/РОРЕО, РО$НЕ/
РИ$НЕР, /СХЕЛЕСХ2, СМР5\У/СМР5О, 15/5, ГОО5У/ОО5,
МОУ5\/МОУ$О, ООТ5\/ООТ5О, 5СА5У/5САЗШ и 5ТО5У//5ТО5$О.

Команда Назначение Процессор


РОРА Загрузить из стека 80186
РОРАО все регистры общего назначения 80386

Команды выполняют действия, полностью обратные действиям РОЗНА


и РОЗНАО, но помещенное в стек значение $Р или Е$Р игнорируется. РОРА загру-
жает из стека ОТ, $1, ВР увеличивает УР на два, загружает ВХ, ОХ, СХ, АХ, аРОРАО
загружает ЕПТ, Е$Т, ЕВР увеличивает Е$Р на 4 и загружает ЕВХ, ЕШОХ, ЕСХ, ЕАХ.
32| |1 || ГП Процессоры И\е! в реальном режиме
Команда Назначение Процессор

1№ приемник, источник ‚ Считать даныые из порта 8086

Копирует число из порта ввода-вывода, номер которого указан в источнике,


в приемник. Приемником может быть только АТ, АХ или ЕАХ. Источник - или
непосредственный операнд, или ОХ, причем во время использования непосред-
ственного операнда можно указывать лишь номера портов не больше 255.
Команда Назначение. Процессор
ОЧТ приемник, источник Записать данные а порт 8086 _

Копирует число из ‘источника (АТ., АХ или ЕАХ) в порт ввода-вывода, номер


которого указан в приемнике. Приемник может быть либо непосредственным
номером порта (не больше 255), либо регистром ОХ. На командах ПМ и ОПТ стро-
ится все общение процессора с устройствами ввода-вывода — клавиатурой, жест-
кими дисками, различными контроллерами, и используются они, в первую оче-
редь, в драйверах устройств. Например, чтобы включить динамик РС, достаточно
выполнить команды:
17 а1, 61н
ог а1,3
ит 618,а1

Программирование портов ввода-вывода рассмотрено подробно в разделе 5.10.


Команда Назначение : .° Процессор
—————ыыщы————щ————щ—ы———————————Щ——————————
д ———А—/—А-[-[—-А-—-[щ—.—.ц.——

смо Конвертирование слова в двойное слово 8086


соа Конвертирование двойного слова 80386
в учетверенное

Команда С\УО превращает слово в АХ в двойное слово, младшая половина


которого (биты 0-15) остается.в АХ, а старшая (биты 16-31) располагается в ОХ.
Команда СРО выполняет аналогичное действие по отношению к двойному слову
в ЕАХ, расширяя его до учетверенного слова в ЕОХ:Е АХ.
Эти команды лишь устанавливают все биты регистра ОХ или ЕБХ в значение,
равное величине старшего бита регистра АХ или ЕАХ, сохраняя таким образом

Команда Жазначение Процессор

СВ Конвертирование байта в слово 8086


СМОЕ Конвертирование слова в двойное слово 80386

СВУ/ расширяет байт, находящийся в регистре АТ, до слова в АХ; С\/ПЕ рас-
ширяет слово в АХ до двойного слова в ЕАХ. Команды С\УШОЕ и С\УШ отличают-
ся тем, что С\УПЕ размещает свой результат в ЕАХ, в то время как СУ/Ю, выпол-
няющая точно такое же действие, располагает результат в паре регистров ОХ:АХ.
Так же как и в командах С\УШ/СОО, расширение выполняется путем установки
Непривилегированные команды И: ЕЕ
каждого бита старшей половины результата равным старшему биту исходного
байта или слова, то есть:
` ®_
МОУ а1, ОЕ5П ; АЁ = ОЕ5И = 245 = -11.
СБ ; Теперь АХ = ОЕЕЕБН = 65 525 = -1}.
© `Как и в случае с командами РИЗНА/РИ$НАО, пара СУБ/СРО — это одна
команда с кодом 99, и пара СВУ/СУ’ЮЕ - одна команда с кодом 98#. Интер-
претация этих команд зависит от того, в каком (16-битном или в 32-бит-
ном) сегменте они исполняются. Если указать СПО или СУПЕ в 16-битном
сегменте, ассемблер поставит префикс изменения разрядности операнда.

Команда р Назначение Процессор

МОУ$Х приемник, источник Пересылка с расширением знака 80386

Копирует содержимое источника (регистр или переменная размером в байт


или слово) в приемник (16- или 32-битный регистр) и расширяет знак аналогич-
но командам СВУ’/СУ/ШЕ.

Команда ` Назначение Процессор


МОУХХ приемник, источник Пересылка с расширением нулями 80386

Копирует содержимое источника (регистр или переменная размером в байт или


слово) в приемник (16- или 32-битный регистр) и расширяет нулями, то есть команда
по\7х ах, 51

эквивалентна паре команд

пом а1, 61
том ап, 0

Команда Назначение ` Процессор


ХЬАТ адрес Трансляция в соответствии с таблицей 8086
ХАТВ

Помещает в АГ. байт из таблицы в памяти по адресу ЕЗ:ВХ (или ЕЗ:ЕВХ) со


смещением относительно начала таблицы равным АГ. В качестве аргумента для
ХГАТ в ассемблере можно указать имя таблицы, но эта информация никак не
используется процессором и служит только в качестве комментария. Если он не
нужен, можно применить форму записи ХГАТВ: Например, можно написать сле-
дующий вариант преобразования шестнадцатеричного числа в А5СП-код соответ-
ствующего ему символа: |
поу а1, осп
том х, ОЕРзет втае
хат

если в сегменте данных, на который указывает регистр ЕЪ, было записано

-7851е 96 “012345678 ЗАВСОЕЕ”

- Зак. 459
34| Процессоры те! в реальном режиме
то теперь АТ. содержит не число ОСЬ, а А5СП-код буквы С. Разумеется, это пре-
образование разрешается выполнить посредством более компактного кода всего
из трех арифметических команд, который будет рассмотрен в.описании команды
РА$, но с ХГАТ можно осуществить любые преобразования такого рода.
3
Команда . Назначение Процессор

ТЕА приемник, источник Вычисление эффективного адреса 8086

Вычисляет 5ффективный адрес источника (переменная) и помещает ‹его в при-


емник (регистр). С помощью ГЕА можно вычислить адрес переменной, которая
описана сложным методом адресации, например по базе с индексированием. Если
адрес - 32-битный, а регистр-приемник - 16-битный, старшая половина вычис-
ленного адреса теряется, если наоборот, приемник - 32-битный, а адресация -
16-битная, то вычисленное смещение дополняется нулями.

Команду ГЕА часто используют для быстрых арифметических вычисле- -


ний, например умножения:
{еа фх[ерх+ебх*4] ; ВХ = ЕВХ Х5
или сложения:
еа ‘ефх,[еах+12] —;ЕВХ = ЕАХ + 12
(эти команды меньше, чем соответствующие МОУ и АОГ, и не изменяют флаги)

2.3.2. Двоичная арифметика


Все команды этого раздела, кроме команд деления и умножения, изменяют
флаги ОЕ 5Е 7Е АЕ СЕ РЕ в соответствии с назначением каждого из них (см.
раздел 2.1.4).
Команда Назначение ‚ Процессор
АБО приемник, источник Сложение 8086

Команда выполняет арифметическое сложение приемника и источника, поме-


щает сумму в приемник, не изменяя содержимое источника. Приемник может
быть регистром или переменной, источник — числом, регистром или переменной,
но нельзя использовать переменную одновременно и для источника, и для при-
емника. Команда АО никак не различает числа со знаком и без знака, но, упот-
ребляя значения флагов СЕ (перенос при сложении чисел без знака), ОР (пере-
нос при сложении чисел со знаком) и 5Е (знак результата), разрешается
применять ее и для тех, и для других. |
——————_——б—б6—6—&8&б8ИиИиД——Ш—————8—ж—
о —д——дддцдд—д—д—дкдк
Команда. Назначение ее Процессор
АОС приемник, источник _. Сложение ‹ переносом 8086

Эта команда аналогична АОШ, но при этом выполняет арифметическое сложе-


ние приемника, источника и флага СЕ Пара команд АРР/АБС используется для
Непривилегированные команды ИТ: 35]
сложения чисел повышенной точности. Сложим, например, два 64-битных целых
числа. Пусть одно из них находится в паре регистров ЕОХ:ЕАХ (младшее двой-
зюе слово (биты 0—31) - в ЕАХ и старшее (биты 32-63) -вЕБХ), а другое - в паре

а93 еах, есх


адс едх, ебх

Если при сложении младших двойных слов произошел перенос из старшего


газряда (флаг СЕ = 1), то он будет учтен следующей командой АОС.

Команда Назначение Процессор


ООО бе ии
ХАОО приемник, источник Обменять между собой и сложить 80486

Выполняет сложение, помещает содержимое приемника в источник, а сумму


‚ операндов - в приемник. Источник - всегда регистр, приемник может быть регист-
ром и переменной. | |
Команда Назначение | Процессор

ЗУВ приемник, источник Вычитание 8086

Вычитает источник из приемника и помещает разность в приемник. Прием-


: шик может быть регистром или переменной, источник — числом, регистром или
| теременной, но нельзя использовать переменную одновременно и для источника,
и для приемника. Точно так же, как и команда АЮО, ЗОВ не делает различий
между числами со знаком и без знака, но флаги позволяют иснользовать ее и для
тах. и для других.
Команда Назначение | Процессор

$В8В приемник, источник Вычитание с займом | 8086

Эта команда аналогична ЗОВ, но она вычитает из приемника значение источ-


вика и дополнительно вычитает значение флага СЕ Ее можно использовать для
вычитания 64-битных чисел в ЕОХ:ЕАХ и ЕВХ:ЕСХ аналогично АРОУАОС:
546 = еах,есх
$5Ь едх, евх

Если при вычитании младших двойных слов произошел заем, то он будет уч-
тен при вычитании старших слов.

Команда Назначение Процессор

МАЛ. источник Умножение чисел со знаком р 8086


ЗАЛ. приемник, источник . 80386
АЛ. приемник, источник] ‚источник? | ‚ 80186
361111 Процессоры И\е! в реальном режиме
Эта команда имеет три формы, различающиеся числом операндов:
1. МУР источник: источник (регистр или переменная) умножается на АТ, АХ
или ЕАХ (в зависимости от размера операнда), и результат располагается
в АХ, ОХ:АХ или ЕРХ:ЕАХ соответственно.
2. МОГ. приемник, источник: источник (число, регистр или переменная) ум-
ножается на приемник (регистр), и результат заносится в приемник.
3. ПМУЕ приемник‚источник1,‚источник?: источник 1 (регистр или переменная)
умножается на источник 2 (число), и результат заносится в приемник (регистр).
Во всех Трех вариантах считается, что результат может занимать в два раза
больше места, чем размер источника. В первом случае приемник автоматически
оказывается очень большим, но во втором и третьем случаях существует вероят-.
ность переполнения и потери старших битов результата. Флаги ОР и СЕ будут
равны единице, если это произошло, и нулю, если результат умножения помес-
тился целиком в приемник (во втором и третьем случаях) или в младшую поло-
вину приемника (в первом случае).
Значения флагов ЗЕ ГЕ АЕи РЕ после команды [МТТ не определены.

Команда Назначение - ‘Процессор

МОЕ источник . Умножение чисел без знака | 8086

Выполняет умножение содержимого источника (регистр.или переменная) и ре-


гистра АГ, АХ, ЕАХ (в зависимости от размера источника) и помещает результат
ВАХ, ОХ:АХ, ЕОХ:ЕАХ соответственно. Если старшая половина результата (АН,
ОХ, ЕШОХ) содержит только нули (результат целиком поместился в младшую
половину), флаги СЕ и ОЕ устанавливаются в 0, иначе — в 1. Значение остальных
флагов (ЗЕ, ГЕ АЕи РЕ) не определено.

Команда . Назначение „ Процессор

ОМ источник Целочисленное деление со знаком 8086

Выполняет целочисленное деление со знаком АТ, АХ или ЕАХ (в зависимос-


ти от размера источника) на источник (регистр или переменная) и помещает ре-
зультат в АТ, АХ или ЕАХ, а остаток - в АН, ОХ или ЕОХ соответственно. Ре-
зультат всегда округляется в сторону нуля, знак остатка совпадает со знаком
делимого, абсолютное значение остатка меньше абсолютного значения делителя.
Флаги СЕ ОЕ $Е 7Е АЕи РЕ после этой команды не определены, а переполне-
ние или деление на ноль вызывает исключение #0Е (ошибка при делении) в за-
щищенном режиме и прерывание 0 — в реальном.

Команда ` Назначение Процессор

ОУ источник Целочисленное деление без знака 8086

Выполняет целочисленное деление без знака А|.. АХ.сили ЕАХ (в зависимости от


размера источника) на источник (регистр нли переменная) и помещает результат
ВАГ, АХ или ЕАХ, а остаток— в АН, ОХ или ЕБХ соответственно. Результат всегда
Непривилегированные команды ИТ:
| | 37
округляется в сторону нуля, абсолютное значение остатка меньше абсолютного
значения делителя. Флаги СЕ ОЕ ЗЕ 2Е АЕи РЕ после этой команды не опреде-
даны, а переполнение или деление на ноль вызывает исключение #П0Е (ошибка
три делении) в защищенном режиме и прерывание ( — в реальном.

Команда
ОО Назначение
ло Процессор
ыы
Ж№3С приемник Инкремент 8086

Увеличивает приемник (регистр или переменная) на 1. Единственное отличие


этой команды от АБО приемник,1 состоит в том, что флаг СЕ не затрагивается.
‚ Остальные арифметические флаги (ОЕ 5Е 7Е АЕ РР) устанавливаются в соот-
| = ствии с результатом сложения.
анда Назначение Процессор
НЕС -риемник Декремент 8086

Уменьшает приемник (регистр или переменная) на 1. Единственное отличие


<; команды от ЗОВ приемник, 1 заключается в том, что флаг СЕ не затрагивает-
== Остальные арифметические флаги (ОЕ 5Е 7Е АЕ РЕ) устанавливаются в со-
ит=е-ствии с результатом вычитания.

па Назначение . Процессор
5 ^риемник ^ Изменение знака 8086

Выполняет над числом, содержащимся в приемнике (регистр или переменная),


цию дополнения до двух. Эта операция эквивалентна обращению знака опе-
:. если рассматривать его как число со знаком. Если приемник равен нулю,
с СЕ устанавливается в 0, иначе - в 1. Остальные флаги (ОЕ, ЗЕ Е АЕ РЕ)
резке: заются в соответствии с результатом операции.

| Красивый пример использования команды МЕС - получение абсолютного


>>) значения числа, применяя всего две команды — изменение знака и переход
на первую команду еще раз, если знак отрицательный:
1аре0: пеё еах
} авео

ь Назначение | ‚ Процессор
трьемник, ИСТОЧНИК Сравнение - 8086

ь Сра=нивает приемник и источник и устанавливает флаги. Действие осуществ-


№тся сотем вычитания источника (число, регистр или переменная) из прием-
2 ‹регистр или переменная; приемник и источник не могут быть переменны-
в от=-временно), причем результат вычитания никуда не записывается.
встзенным следствием работы этой команды оказывается изменение флагов
КОР ЗЕ. ГЕ АЕ и РЕ Обычно команду СМР используют вместе с командами
реза -г- перехода (]сс), условной пересылки данных (СМОУ\сс) или условной
3811111 Процессоры те! в реальном режиме `
установки байтов (ЗЕТсс), которые позволяют применить результат сравнения,
не обращая внимания на детальное значение каждого флага. Так, команды СМОТУЕ,
ТЕ и ЗЕТЕ выполнят соответствующие действия, если значения операндов пред-
шествующей команды СМР были равны.

@& Несмотря на то что условные команды почти всегда вызываются сразу


после СМР, не надо забывать, что их можно использовать после любой ко-
манды, модифицирующей флаги, например: проверить равенство АХ нулю
более короткой командой
‚ {25 ах,ах
а равенство единице — однобайтной командой
4ес. ах

Команда Назначение . . Процессор


СМРХСНС приемник, источник Сравнить и обменять между собой 80486

Сравнивает значения, содержащиеся в АГ. АХ, ЕАХ (в зависимости от разме-


ра операндов), с приемником (регистром). Если они равны, информация из ис-
точника копируется в приемник и флаг 7Е устанавливается в 1, в противном слу-
чае содержимов приемника копируется в АГ, АХ, ЕАХ и флаг (Е устанавливается
в 0. Остальные флаги определяются по результату операции сравнения, как после
СМР Источник - всегда регистр, приемник может быть регистром и переменной.
Команда | Назначение Процессор
СМРХСНСВ8В приемник Сравнить и обменять 8 байт Р5

Выполняет сравнение содержимого регистров ЕОХ:ЕАХ как 64- битного чис-


ла (младшее двойное слово -— в ЕАХ, старшее - вЕОХ) с приемником (8-байтная
переменная в памяти). Если они равны, содержимое регистров ЕСХ:ЕВХ как
64-битное число (младшее двойное слово в ЕВХ, старшее - в ЕСХ) помещается
в приемник. В противном случае содержимое приемника копируется в ЕОХ:ЕАХ.

2.3.3. Десятичная арифметика


Процессоры ие! поддерживают операции с двумя форматами десятичных чисел:
неупакованное двоично-десятичное число — байт, принимающий значения от 00
до 091, и упакованное двоично-десятичное число — байт, принимающий значения
от 00 до 99Б. Все обычные арифметические операции над такими числами приво-
дят к неправильным результатам. Например, если увеличить 19 на 1, то полу-
чится число 1АВ, а не 201. Для коррекции результатов арифметических действий
над двоично-десятичными числами используются приведенные ниже команды.
—_
о
Команда - Назначение . . Процессор
РАА ° ВХ ВСО-коррекция после сложения 8086

Если эта команда выполняется сразу после АБП (АРС, ПМС или ХАОО) ивре-
гистре АТ. находится сумма двух упакованных двоично-десятичных чисел, то в АТ.
Непривилегированные команды И:| | 39
записывается упакованное двоично-десятичное число, которое должно было
стать результатом сложения. Например, если АГ. содержит число 19Ъ, последова-
тельность команд
1пс а1
Чаа

гриведет к тому, что в АТ, окажется 201 (а не ТАЗ, как было бы послё ПМС).

РАА выполняет следующие действия:


1. Если младшие четыре бита АГ. больше 9 или флаг АЕ = 1,
то АГ увеличивается на 6, СЕустанавливается, если при этом сложении
произошел перенос, и АЕ устанавливается в 1.
2. Иначе АЕ= 0.
3. Если теперь старшие четыре бита АГ больше 9 или флаг СЕ = 1,
то АГ увеличивается на 608 и СЕ устанавливается в 1.
4. Иначе СЕ = 0.
Флаги АЕ и СР устанавливаются, если в ходе коррекции происходил перенос
из первой или второй цифры. 5ЁЕ, 7Е и РЕ устанавливаются в соответствии с ре- .
зультатом, флаг ОЕ не определен.
Команда ° Назначение Процессор
ОА$5 ‚ ВСО-коррекция после вычитания 8086

| Если эта команда выполняется сразу после ЗОВ (5ЗВВ или ОЕС) и в регистре АГ,
ваходится разность двух упакованных двоично-десятичных чисел, то в АГ. записыва-
ется упакованное двоично-десятичное число, которое должно было быть результатом
вычитания. Например, если АТ. содержит число 201, последовательность команд

приведет к тому, что в регистре окажется 191 (а не 1ЕВ, как было бы после РЕС).
© РА$ выполняет следующие действия:
1. Если младише четыре бита АГ больше 9 или флаг АЕ = 1,
то АГ уменьшается на 6, СЕ устанавливается, если при этом вычита-
нии произошел заем, и АЕ устанавливается в 1.
2. Иначе АЕ= 0.
3. Если теперь старшие четыре бита АГ. больше 9 или флаг СЕ= 1,
то АГ уменьшается на 60й и СЕ устанавливается в 1.
4. Иначе СЕ = 0.
Известный пример необычного использования этой команды — самый ком-
пактный вариант преобразования шестнадцатеричной цифры в АУСП-код
соответствующего символа (более длинный и очевидный вариант этого
преобразования рассматривался в описании команды ХГАТ):
стр @р10 `
5ЬЬ а,69й
4а5
401 |1] 11 Процессоры Не! в реальном режиме
После 5ВВ числа 0-9 превращаются в 96Ё — ЭЕЙ, а числа ОАЙ — ОЕВ -
в ОАЛЁ - ОАбЁ. Затем РА5 вычитает 66# из первой группы чисел, переводя
их в ЗО — 39, и 60Р из второй группы чисел, переводя их в Ч1Ё — 46й.
Флаги АЕ и СЕ устанавливаются, если в ходе коррекции происходил заем из
первой или второй цифры. ЗЕ, ЕиРЕ устанавливаются в соответствии с резуль-
татом, ‚ флаг ОЕ не определен.

Команда Назначение Процессор


ААА , АЗСН-коррекция после сложения ` 8086

Корректирует сумму двух неупакованных двоично-десятичных чисел в АГ.


Если коррекция приводит’ к десятичному переносу, АН увеличивается на 1. Эту
команду. лучше использовать сразу после команды сложения двух таких чисел.
Например, если при сложении 05 и 06 в АХ окажется число 000ВВ, то команда
ААА скорректирует его в 01011 (неупакованное десятичное 11). Флаги СЕи ОЕ
устанавливаюхся в 1, если произошел перенос из АТ. в АН, в противном случае
они равны нулю. Значения флагов ОЕ 5Е 7Ри РЕ не определены.

Команда Назначение Процессор


ААЗ .* АЗСН-коррекция после вычитания 8086

Корректирует разность двух неупакованных двоично-десятичных чисел в АТ,


сразу после команды ЗОВ или ЗВВ. Если операция приводит к займу, АН уменьша-
ется на 1. Флаги СЕ и ОЕ устанавливаются в 1, если произошел заем из Ав АН,
и в ноль - в противном случае. Значения флагов ОЕ 5Е 7Еи РЕ не‘определены.
Команда Назначение Процессор
ААМ А$С!-коррекция после умножения 8086

Корректирует результат умножения неупакованных двоично-десятичных чисел,


который находится в АХ после выполнения команды МОТ. преобразовывая полу-
ченное в пару неупакованных двоично-десятичных чисел (в АН и А1Т.). Например:
то а1,5
моу 1,5 ; Умножить 5 на 5.
по 51 ‚ Результат в АХ - 00191.
аая ‚ Теперь АХ содержит 02051.

ААМ устанавливает флаги ЗЕ 7Еи РЕ в соответствии с результатом и остав-


ляет ОЕ АЕ и СЕ неопределенными.

Код команды ААМ — Пай ОАй, где ОАЙ — основание системы счисления, по
@® отношению к которой выполняется коррекция. Этот байт можно заме-
нить на любое другое число (кроме нуля). и ААМ преобразует АХ к двум не-
упакованным цифрам любой системы счисления. Такая обобщенная форма
ААМ работает на всех процессорах (начиная с 8086), но появляется в доку-
ментации [те! только с процессоров Реппит. Фактически действие, кото-
рое выполняет ААМ, -— целочисленное деление А. на ОА (или любое другое
Непривилегированные команды |1 О О ПО ИР

число в общем случае), частное помещается в АН, и остаток - в АГ, поэто-


му команду часто используют для быстрого деления в высокооптимизиро-
ванных алгоритмах. |

Команда Назначение Процессор


ААО АЗСЙ-коррекция перед делением _ 8086

Выполняет коррекцию неупакованного двоично-десятичного числа, находяще-


гося в регистре АХ, так, чтобы последующее деление привело к десятичному ре-
3 льтату. Например, разделим десятичное 25 на 5:
оу ах, 02051 . ; 25 в неупакованном формате.
ОУ 61,5
ааа ; Теперь в АХ находится 191.
ЧУ 51 . _; АХ = 0005.

Флаги ЗЕ, 7Е и РЕ устанавливаются в соответствии с результатом, ОЕ АЕ и СЕ


ве определены.

Команда ААП, как и ААМ, используется с любой системой счисления: ее код —


Рэй ОА, и второй байт можно заменить на любое другое число. Действие
ААО заключается в том, что содержимое регистра АН умножается на
второй байт команды (ОАЁ по умолчанию) и складывается с АГ, после чего
АН обнуляется, так что ААР можно использовать для быстрого умноже-
ния на любое число.

2.3.4. Логические операции


Шоманда Назначение . Процессор
С приемник, источник Логическое И 8086

Команда выполняет побитовое «логическое И» над приемником (регистр или


ше-еменная) и источником (число, регистр или переменная; источник и прием-
их не могут быть переменными одновременно) и помещает результат в прием-
ииих. Любой бит результата равен 1, только если соответствующие биты обоих
ытерандов были равны 1, и равен 0 в остальных случаях. Наиболее часто АМО
ас :меняют для выборочного обнуления отдельных битов. Например, команда
апа а1, 000011116

сехлит старшие четыре бита регистра АТ, сохранив неизменными четыре младших.
’ Флаги ОЕ и СЕ обнуляются, ЗЕ, Е и РЕ устанавливаются в соответствии с ре-
ит льтатом, АЁ не определен.

Шоманда Назначение . Процессор


-сиемник, источник Логическое ИЛИ 8086

Зыполняет побитовое «логическое ИЛИ» над приемником (регистр или пере-


мечная) и источником (число, регистр или переменная; источник и приемник не
4211 ||| Процессоры {е! в реальном режиме
могут быть переменными одновременно) и помещает результат в приемник. Любой
бит результата равен 0, только если соответствующие биты обоих операндов были
равны 0, и равен 1 в остальных случаях. Команду ОВ чаще всего используют для
выборочной установки отдельных битов. Например, команда
ог а1, 000011116

приведет к тому, что младшие четыре бита регистра АТ. будут установлены в 1.
При выполнении команды ОК флаги ОЕ и СЕ обнуляются, ЗЕ, 2Е и РЕ уста-
навливаются в соответствии с результатом, АЁ не определен.
Команда: Назначение | Процессор
Эдо
ХОЯ приемник, источник -Логическое исключающее ИЛИ 8086

Выполняет побитовое «логическое исключающее ИЛИ» над приемником (ре-


гистр или переменная) и источником (число, регистр или переменная; источник
и приемник не могут быть переменными одновременно) и помещает результат
в приемник. Любой бит результата равен 1, если соответствующие биты операн-
дов различны, и нулю - в противном случае. ХОК используется для самых раз-
ных операций, например:
хог ах, ах ; Обнуление регистра АХ.
ИЛИ у
хог ах,5х
хог 6х,ах
хог ах, 6х ; Меняет местами содержимое АХ и ВХ.

Оба примера могут выполняться быстрее, чем соответствующие очевидные


команды
моу ах,.0
или |
хсН9 ах, ох

Команда ’ Назначение Процессор


МОТ приемник Инверсия 8086

Каждый бит приемника (регистр или переменная), равный нулю, устанавли-


вается в 1, и каждый бит, равный 1, сбрасывается в 0. Флаги не затрагиваются.
Команда Назначение Процессор со
аааал

‚ ТЕЗТ приемник, источник Логическое сравнение 8086

Вычисляет результат действия побитового «логического И» над приемником


(регистр или переменная) и источником (число, регистр или переменная; источник
и приемник не могут быть переменными одновременно) и устанавливает флаги 5Е
2Е иРРЕ в соответствии с полученным показателем, не сохраняя результата (фла-
ги ОРи СЕ обнуляются, значение АЕ не определено). ТЕ$Т, так же как и СМР.
используется в основном в сочетании с командами условного перехода (]сс),
условной пересылки данных (СМО\сс) и условной установки байтов (ЗЕТсс).
а
а
о
а
ча

Р
Непривилегированные команды — СО О О ОНИ ЕЕ
2.3.5. Сдвиговые операции
Команда ._. Назначение Процессор

ЗАНЯ приемник, счетчик Арифметический сдвиг вправо 8086


ЗАЁ приемник, счетчик Арифметический сдвиг влево 8086
УНВ приемник, счетчик Логический сдвиг вправо 8086
УНЕ приемник, счетчик : Логический сдвиг влево 8086

Эти четыре команды выполняют двоичный сдвиг приемника (регистр или пере-
менная) вправо (в сторону младшего бита) или влево (в сторону старшего бита)
за значение счетчика (число или регистр СГ. из которого учитываются только
младшие 5 бит, принимающие значения от 0 до 31). Операция сдвига на 1 экви-
=алентна умножению (сдвиг влево) или делению (сдвиг вправо) на 2. Так, число
3)10Ъ (2) после сдвига на 1 влево превращается в 0100Ъ (4). Команды ЗАГ
= ЗНГ. выполняют одну и ту же операцию (на самом деле это одна и та же коман-
-) — на каждый шаг сдвига старший бит заносится в СЕ все биты сдвигаются
лево на одну позицию, и младший‘бит обнуляется. Команда 5НК осуществляет
=рямо противоположную операцию: младший бит заносится в СЕ всебиты сдви-
-зются на 1 вправо, старший бит обнуляется. Эта команда эквивалентна беззнако-
зому целочисленному делению на 2. Команда ЗАК действует по аналогии с $НК,
-элько старший бит не обнуляется, а сохраняет предыдущее значение, вот почему,
=зпример, число 11111100 (-4) перейдет в 11111110Ъ (-2). ЗАВ, таким обра-
вом, эквивалентна знаковому делению на 2, но, в отличие от ТРТУ, округление
-роисходит не в сторону нуля, а в сторону отрицательной бесконечности. Так,
=сли разделить -9 на 4 с помощью ПТУ, получится -2 (и остаток —1), аесли вы-
толнить арифметический сдвиг вправо числа -—9 на 2, результатом будет -3. Сдви-
—и больше 1 эквивалентны соответствующим сдвигам на 1, выполненным после-
совательно. Схема всех сдвиговых операций приведена на рис. 7.
Сдвиги на 1 изменяют значение флага ОЕ. ЗАГ./$ НЕ. устанавливают его в 1,
если после сдвига старший бит изменился (то есть старшие два бита исходного
=исла не были одинаковыми), и в 0, если старший бит остался тем же. ЗАВ уста-
«звливает ОЕв 0, а $НВ - в значение старшего бита исходного числа. Для сдви-
гов на несколько битов значение ОЕ не определено. Флаги ЗЕ, Е РЕ назначаются

и 7,15,31
с:
вл Е 753
-=-
зн а 7,15,31

Рис. 7. Сдвиговые операции


4411 ||| | Процессоры {ев реальном режиме
всеми сдвигами в соответствии с результатом, параметр АЕ не определен (кроме
случая, когда счетчик сдвига равен нулю: ничего не происходит и флаги не изме-
няются). —
В процессорах 8086 в качестве второго операнда можно было задавать лишь
число 1 и при использовании СГ. учитывать все биты, а не только младшие 5, но
уже начиная с 80186 эти команды приняли свой окончательный вид.
и

Команда : Назначение Процессор


УЗНАО приемник, источник, счетчик Сдвиг повышенной точности вправо 80386
НЬЮ приемник, источник, счетчик Сдвиг повышенной точности влево 80386

Приемник (регистр или переменная) сдвигается влево (в случае НЕ.) или впра-
во (в случае ЗНВО) на число битов, указанное в счетчике (число или регистр СГ.
откуда используются только младшие 5 бит, принимающие значения от 0 до 31).
Старший (для ЗНГ.О) или младший (в случае $ЗНКО) бит не обнуляется, а счи-
тывается из источника (регистр), значение которого не изменяется. Например,
если приемник содержит 00101001Ъ, источник — 1010Ъ;то счетчик равен 3, ЗНВР
даст в результате 010001015, а ЗНТО - 01001101Ъ (см. рис. 8).

зко Г кок
15,3] 0
| 15,31
пин 0

зо < [9 15,31
зы 0
Го жж
15,31 0

Рис. 8. Сдвиги двойной точности

Флаг ОЕ устанавливается при сдвигах на 1 бит, если изменился знак прием-


ника, и сбрасывается в противном случае; при сдвигах на несколько битов флаг
ОЕ не определен. Во всех случаях ЗЕ, 7Еи РЕ устанавливаются в соответствии
с результатом и АЕ не определен, кроме варианта со сдвигом на 0 бит, в котором
значения флагов не изменяются. Если счетчик больше, чем разрядность прием-
ника, - результати все флаги не определены.

Команда Назначение Процессор


ВОЯ приемник, счетчик Циклический сдвиг вправо 8086
ВОЕ приемник, счетчик Циклический сдвиг влево 8086
ВСВ приемник, счетчик Циклический сдвиг вправо через флаг переноса 8086
ВСЕ приемник, счетчик Циклический сдвиг влево через флаг переноса 8086

Эти команды осуществляют циклический сдвиг приемника (регистр или пе-


ременная) на число битов, указанное в счетчике (число или регистр СТ. из кото-
рого учитываются только младшие 5 бит, принимающие значения от 0 до 31 }.При
выполнении циклического сдвига на 1 команды КОВ (КОТ.) перемещают каждый
бит приемника вправо (влево) на одну позицию, за исключением самого младшего
(старшего), который записывается. в позицию самого старшего (младшего) бита.
Непривилегированные команды ПЕ: |! 45
у

7,15,31 0 —

-«— 7.15.31 0

т =

РИ
| 7,1531
нии 0 В
Рис. 9. Циклические сдвиги

К: манды ВСВ и ВСГ. выполняют аналогичное действие, но включают флаг СЕ.


в -икл, как если бы он был дополнительным битом в приемнике (см. рис. 9).
‚ — После выполнения команд циклического сдвига флаг СЕ всегда равен последне-
мг. вышедшему за пределы приемника биту, флаг ОЕ определен только для сдвигов
вс: — он устанавливается, если изменилось значение самого старшего бита, и сбра-
сы зается в противном случае. Флаги 5ЁЕ.7Е АЕиРЕ не изменяются.
2.3.6. Операции над битами и байтами
кри
ЧЕоманда Назначение Процессор
ЗОО
ШТ -2за, смещение Проверка бита - _ 80386

Команда ВТ считывает в флаг СЕ значение бита из битовой строки, определен-


с первым операндом — битовой базой (регистр или переменная), со смещением,
тусзанным во втором операнде — битовом смещении (число или регистр). Когда
ше-зый операнд - регистр, то битовой базой считается бит 0 в названном регистре
№ -мещение не может превышать 15 или 31 (в зависимости от размера регистра);
ти оно превышает эти границы, в качестве смещения будет использоваться оста-
ок от деления на 16 или 32 соответственно. Если первый операнд — переменная, то
в х-честве битовой базы нужен бит 0 указанного байта в памяти, а смещение может
ис инимать значения от 0 до 31, если оно установлено непосредственно (старшие
биты процессором игнорируются), и от —23' до 28!—1, если оно указано в регистре.

э
Несмотря на то что эта команда считывает единственный бит из памя-
ти, а процессор — целое двойное слово по адресу База + (4 Х (Смещение/
32)) или слово по адресу База + (2 Х (Смещение/16)), в зависимости от
разрядности адреса, все равно не следует пользоваться ВТ вблизи от недо-
ступных для чтения областей памяти.
СОШИИШИИШИИ | — Процессоры име! в реальном режиме
После выполнения команды ВТ флаг СЕ равен значению считанного бита,
флаги ОЕ ЗЕ 2Е АЕи РЕ не определены.
Команда Назначение Процессор
ВТ$ база, смещение Проверка и установка бита „ 80386
ВТВ база, смещение Проверка и сброс бита 80386
ВТС база, смещение Проверка и инверсия бита 80386

Эти три команды соответственно устанавливают в 1 (ВТ$), сбрасывают в 0


(ВТВ) и инвертируют (ВТС) значение бита, который находится в битовой строке
с началом, определенным в базе (регистр или переменная), и смещением, указан-
ным во втором операнде (число от 0 до 31 или регистр). Если битовая база - ре-
гистр, то смещение не может превышать 15 или 31 в зависимости от разрядности
этого регистра. Если битовая база — переменная в памяти, то смещение может
принимать значения от —23! до 23'-1 (при условии, что оно указано в регистре).
После выполнения команд ВТ$, ВТК и ВТС флаг СЕ равен значению считан-
ного бита до его изменения в результате действия команды, флаги ОЕ $Е 7Е АЕ
и РЕ не определены.

Команда Назначение Процессор


——ии до
дио иЩи
В$Е приемникисточник Прямой поиск бита 80386
В$Я приемник, источник Обратный поиск бита `` 80386

В$Е сканирует источник (регистр или переменная), начиная с самого младшего


бита, и записывает в приемник (регистр) номер первого встретившегося бита, рав-
ного 1. Команда ВВ сканирует источник, начиная с самого старшего бита, и воз-
вращает номер первого встретившегося ненулевого бита, считая от нуля. То есть,
если источник равен 0000 0000 0000 0010Ь, то ВЗ$Е возвратит 1, а ВЗЁ - 14.
Если весь источник равен нулю, значение приемника не определено и флаг Е
а
устанавливается в 1, иначе 7Е всегда сбрасывается. Флаги СЕ ОЕ 5Е АЕи РЕ не
определены.
Команда Назначение ` Процессор
дм
ЗЕТсс приемник Установка байта по условию 80386

Это набор команд, устанавливающих приемник (8-битный регистр или пере-


‚ менная размером в 1 байт) в 1 или 0, если удовлетворяется или не удовлетворяется
а
ви
а
Е.
определенное условие. Фактически в каждом случае проверяется состояние тех
или иных флагов, но, когда команда из набора ЗЕТсс используется сразу после
СМР, условия приобретают формулировки, соответствующие отношениям меж-
ду операндами СМР (см. табл. 6). Скажем, если операнды СМР были неравны, то
команда ЗЕТМЕ, выполненная сразу после СМР, установит значение своего опе-
ранда в 1.
Слова, «выше» и «ниже» в таблице относятся к сравнению чисел без знака,
слова «больше» и «меньше» учитывают знак.
Непривилегированные команды | |4),
Таблица 6. Команды ЗЕТсс

Кодноменды Если выше


Условие для СМР
‹ ЗЕТА = = |
ЗЕТМВЕ СЕ =0и2==0 Если не ниже и не равно

ЗЕТАЕ Если выше или равно


ЗЕТМВ СЕ=0 Если не ниже
ЗЕТМС Если нет переноса

ЗЕТВ Если ниже


ЗЕТМАЕ . СЕ=1 Если не выше и не равно .
ЗЕТС Если перенос
ЗЕТВЕ _ _ Если ниже или равно
ЗЕТМА СЕ =Т или 28 =1 Если не выше
‚ ЗЕТЕ | ТЕ =1 Если равно
ЗЕТА. Если ноль
Е
; ЗЕТ@ _ _ Если больше .
' ЗЕТМЕЕ 27=би5Е=ОР . Если не меньше ине равно _ .
: ЗЕТОЕ - ЗЕ = ОЕ : ‚| Если больше или равно.
| ЗЕТМЕ | Если не меньше

|ЗЕТЬ Если меньше


ЗЕТМЕ З2 <> ОР , : Если не больше и не равно

Е
; 4
р ИЕН
Если не равно
ЗЕТМЕ 2Е=0
ЗЕТМА. Если не ноль

{ ЗЕТМО ОЕ=0 Если нет переполнения


| ЗЕТО ГОЕ=1 | Если есть переполнение
|
‚ЗЕТМР РЕ 0 у Если нет четности
| ЗЕТРО | Если нечетное
ЗЕТР” РЕ=1 Если есть четность
| ЗЕТРЕ Если четное
ЗЕТМЗ ЗЕ=0 Если
— | нет знака
ЗЕТЗ ЗЕ =1 _ | Если есть знак

2.3.7. Команды передачи управления


Команда Назначение Процессор

УМР операнд Безусловный переход — 8086

]]МР персдает управление в другую точку программы, не сохраняя какой-либо


информации для возврата. Операндом может быть непосредственный адрес для пе-
рехода (в программах используют имя метки, установленной перед командой, на
которую выполняется переход), а также регистр или переменная, содержащая адрес.
В зависимости от типа перехода различают:

О переход типа зо” (короткий переход) — если адрес перехода находится в пре-
делах —128...+127 байт от команды МР;
|
481111] Процессоры Н\е! в реальном режиме
О переход типа иеаг (ближний переход) - если адрес перехода находится в том
же сегменте памяти, что и команда ]МР;
О переход типа /аг (дальний переход) - если адрес перехода находится‘в дру-
гом сегменте. Дальний переход может выполняться и в тот же самый сегмент
при условии, что в сегментной части операнда указано число, совпадающее
с текущим значением С$;
О переход с переключением задачи — передача управления другой задаче в мно-
гозадачной среде. Этот вариант будет рассмотрен в разделе, посвященном за-
щищенному режиму.
При выполнении переходов типа зПог( и пеаг команда ]МР фактически преоб-
разовывает значение регистра Е1Р (или [Р), изменяя тем самым смещение следу-
ющей исполняемой команды относительно начала сегмента кода. Если операнд —
регистр или переменная в памяти, то его показатель просто копируется в ЕГР, как
если бы это была команда МОУ. Если операнд для ]МР - непосредственно ука-
занное число, то его значение суммируется с содержимым ЕТР, приводя`к относи-
тельному переходу. В ассемблерных программах в качестве операнда обычно
указывают имена меток, но на уровне исполняемого кода ассемблер вычисляет
и записывает именно относительные смещения. :
Выполняя дальний переход в реальном, виртуальном и защищенном режимах
(при переходе в сегмент с теми же привилегиями), команда ] МР просто загружа-
ет новое значение в ЕГР и новый селектор сегмента кода в С$, используя старшие
16 бит операнда как новое значение для С$ и младшие 16 или 32 битв качестве
значений ГР или ЕР
Команда Назначение Процессор
Усс метка Условный переход 8086 °

Это набор команд, выполняющих переход (типа зВог( или пеаг), если удовлет-
воряется соответствующее условие, которым в каждом случае реально является
состояние тех или иных флагов. Но, когда команда из набора ]сс используется
сразу после СМР, условия приобретают формулировки, соответствующие отно-
шениям между операндами СМР (см. табл. 7). Например, если операнды СМР
были равны, то команда ]Е, выполненная сразу после СМР осуществит переход.
Операнд для всех команд из набора ]сс - 8-битное или 32-битное смещение отно-
сительно текущей команды.
` Слова «выше» и «ниже» в таблице относятся к сравнению чисел без знака; сло-
ва «больше» и «меньше» учитывают знак.
Команды ]сс не поддерживают дальних переходов, поэтому, если требуется вы-
полнить условный переход на дальнюю метку, необходимо использовать команду
из набора ]сс с обратным условием и дальний ]МР как, например:
стр ах,0
пе 10са1_1
тр Гаг_]абе1 ; Переход, если АХ = 0. -
10са1_1:
Непривилегированные команды | | 49]
Таблица 7. Варианты команды Усс

ЧА СЕ=би2Е=0 Если выше


УВЕ Если не ниже и не равно |

ЧАЕ Если выше или равно


мВ СЕ=0 Если не ниже .
УМС Если нет переноса
УВ Если ниже `
УМАЕ СЕ=1 Если не выще и не равно
УС Если перенос
ВЕ _ _ _ Если ниже или равно
УМА СЕ =Тили 28 =1 Если не выше
ЧЕ _ Если‘равно
у. 2Е=1 |Если ноль
46 _ = Если больше . |
УМЕ 2Е=0и ЗЕ =ОЕ Если не меньше и не равно

УСЕ _ Если больше или равно |


УМЕ ЗЕ = ОР Если не меньше .
КВ . | Е <> ОЕ Если меньше _
УМОЕ ) Если не больше и не равно

ЛЕ 7Е-1 или $Е <> ОЕ — | Если меньше или равно


_м@ | Если не больше
УМЕ _ Если не равно
м7 2Е0 | Если не ноль |
мо ОЕ=О Если нет переполнения |
40 ОЕ =1 Если есть переполнение -

МР РЕ=О Если нет четности |


4РО Если нечетное -
УР РЕ=1 Если есть четность
РЕ Если четное
ЗЕ =0 Если нет знака
ЗЕ =1 Если есть знак

Команда Назначение Процессор


Олово бы
4СХР метка Переход, если СХ = 0 8086
ЗЕСХ2 метка Переход, если ЕСХ = 0 80386
оО ль О

Выполняет ближний переход на указанную метку, если регистр СХ или ЕСХ


‹ для ]СХ7 и ]ЕСХЕ соответственно) равен нулю. Так же как и команды из серии
1сс, СХЕ. и ЕСХА не могут выполнять дальних переходов. Проверка равенства
СХ нулю, например, может потребоваться в начале цикла, организованного ко-
мандой [ГООРМЕ, - если в него войти с СХ = 0, то он будет выполнен 65 535 раз.
дави АААииии_и—
Команда Назначение Процессор

ГООР метка ° Цикл 8086


——Ц_‚*-"_"3
иди
50 | 1 11| Процессоры т{е! в реальном режиме
Уменьшает регистр ЕСХ на 1 и выполняет переход типа зВог на метку (кото-
рая не может быть дальше расстояния -128...+127 байт от команды ГООР), если
ЕСХ не равен нулю. Эта команда используется для организации циклов, в кото-
рых регистр ЕСХ (или СХ при 16-битной адресации) играет роль счетчика. Так,
в следующем фрагменте команда АОЛ выполнится 10 раз:
мо\ сх, САН
1оор_зтаге:
‚209 ‘ах, сх
1оор 1оор_зтагт ,
"Команда ГООР полностью эквивалентна паре команд
дес есх
917 метка :
'НоТООР короче этих двух команд на один байт и не изменяет значения флагов.
=.
Команда Назначение Процессор
ГООРЕ метка . Цикл, пока равно 8086
ТООРР метка Цикл, пока ноль .- 8086
-ООРМЕ метка Цикл, пока не равно в ` 8086
ТООРМ2. метка Цикл, пока не ноль 8086

Все перечисленные команды уменышпают регистр ЕСХ на один, после чего вы-
полняют переход типа Вог, если ЕСХ не равен нулю и если выполняется условие.
Для команд ГООРЕ и 1ООРЯ условием является равенство единице флага ГЕ для
команд ГТООРМЕ и ГООРМУ - равенство флага 7Е нулю. Сами команды ТООРсс
не изменяют значений флагов, так что 2Е должен быть установлен (или сброшен)
предшествующей командой. Например, следующий фрагмент копирует строку из
05:51 в строку в Е$:01 (см. описание команд работы со строками), пока не кончится
строка (СХ = 0) или пока не встретится символ с АЗСП-кодом 13 (конец строки):
поу `^ сх, 55г_1епаев
поуе 10оор:
10956 `,
$1085
стр а1,13
209рп2 моуе_1оор |

Команда Назначение Процессор .


еек
САНЫ. операнд Вызов процедуры | 8086

Сохраняет текущий адрес в стеке и передает управление по адресу, указанно-


му в операнде. Операндом может быть непосредственное значение адреса (метка
в ассемблерных программах), регистр или переменная, содержащие адрес пере-
хода. Если в качестве адреса перехода указано только смещение, считается, что
адрес располюжен в том же сегменте, что и команда СА. При этом, так же как
и в случае с УМР выполняется ближний вызов процедуры. Процессор помещает
значение регистра ЕТ? (ТР при 16-битной адресации), соответствующее следую-
щей за СА. команде, в стек и загружает в ЕТР новое значение, осуществляя тем
Непривилегированные команды ГГ
самым передачу управления. Если операнд СА. - регистр или переменная, то
его значение рассматривается как абсолютное смещение, если операнд - ближ-
няя метка в программе, то ассемблер указывает ее относительное смещение. Что-
бы выполнить дальний СА. в реальном режиме, режиме \У86 или в защищен-
ном режиме при переходе в сегмент с теми же привилегиями, процессор помещает
в стек значения регистров С$ и ЕР (ТР при 16-битной адресации) и осуществляет
дальний переход аналогично команде ]МР.

Команда Назначение ` Процессор

ВЕТ число : - из процедуры


_ Возврат 8086
ВЕТМ число °
ВЕТЕ число

ВЕТМ считывает из стека слово (или двойное слово, в зависимости от режима


адресации) и загружает его в ГР (или ЕТР), выполняя тем самым действия, обрат-
ные ближнему вызову процедуры командой СА!1.. Команда ВЕТЕ загружает из
стека [Р (ЕТР) и С$,возвращаясь из дальней процедуры. Если в программе указа-
на команда ВЕТ, ассемблер заменит ее на КЕТМ или ВЕТЕ в зависимости от того,
как была описана процедура, которую эта команда завершает. Операнд для ВЕТ
необязателен, но, если он присутствует, после.считывания адреса возврата из сте-
ка будет удалено указанное количество байтов — это нужно, если при вызове про-
цедуры ей передавались параметры через стек. -
АА——А———А—[-[А——/—/—Ааж—3——
Команда Назначение Процессор

1МТ число Вызов прерывания 8086

[МТ аналогично команде САГЛ. помещает в стек содержимое регистров ЕЕГАС$,


СЗ и Е[Р после чего передает управление программе, называемой обработчиком
прерываний с указанным в качестве операнда номером (число от 0 до ОЕЕ[). В ре-
альном режиме адреса обработчиков прерываний считываются из таблицы, начи-
нающейся в памяти по адресу 0000Ъ:0000. Адрес каждого обработчика занимает
4 байта, вот почему, например, обработчик прерывания 10} находится в памяти
по адресу 00008:00401. В защищенном режиме адреса обработчиков прерываний
находятся в таблице ТОТ и обычно недоступны для прямого чтения или записи,
так что для установки собственного обработчика программа должна обращаться
к операционной системе. В РО$ вызовы прерываний используются для выполне-
ния большинства системных функций - работы с файлами, вводом/выводом
ит. д. Например, следующий фрагмент кода завершает выполнение программы
и возвращает управление РОЗ: | `

‚ МОУ ах, 46018


‚11 211
—_ иди
Команда Назначение ` ° Процессор
в
около ади
ООО
1АЕТ Возврат из обработчика прерывания 8086
1АЕТО | |
5211 ||| Процессоры те! в реальном режиме
Возврат управления из обработчика прерывания или исключения. 1ВЕТ за-
гружает из стека значения ГР СЗ и ЕГАС$, а [ВЕТО - ЕР, С$'и ЕЕГАС$ соот-
ветственно. Единственное отличие ВЕТ от КЕТЕ состоит в том, что значение ре-
гистра флагов восстанавливается, из-за чего многим обработчикам прерываний
приходится изменять величину ЕРГАС5, находящегося в стеке, чтобы, например,
вернуть флаг СЁ установленный в случае ошибки.
Команда Назначение | | Процессор

мтз Вызов прерывания 3 8086

Размер этой команды — один байт (код ОССЬ), что делает ее удобной для до-
водки программ отладчиками, работающими в реальном режиме. Они записыва-
ют этот байт вместо первого байта команды, перед которой требуется точка оста-
нова, Ичтереопределяют адрес обработчика прерывания 3 на соответствующую
процедуру внутри отладчика.

Команда ‘`` Назначение Процессор


то Вызов прерывания 4 при переполнении 8086

[МТО - еще одна специальная форма команды [МТ. Она вызывает обработчик
прерывания 4, если флаг ОЕ установлен в 1.

Команда. Назначение- Процессор

ВОЧМО индекс,границы ‹ Проверка выхода за границы массива 80186

ВОЧМО проверяет, не выходит ли значение первого операнда (регистр), взя-


тое как число со знаком, за границы, указанные во втором операнде (переменная).
Границы — два слова или двойных слова (в зависимости от разрядности операн-
дов), рассматриваемые как целые со знаком и расположенные в памяти подряд.
Первая граница считается! нижней, вторая — верхней. Если индекс меньше ниж-
ней границы или больше верхней, вызывается прерывание 5 (или исключение
#ВБЕ). причем адрес возврата указывает не на следующую команду, а на ВОЦМЮ,
так что обработчик должен исправить значение индекса или границ, прежде чем
выполнять команду ВЕТ.

` Назначение Процессор

ЕМТЕН размер. уровень Вход в процедуру 80186

Команда ЕМТЕК создает стековый кадр заданного размера и уровня вложен-


ности (оба операнда — числа; уровень вложенности может принимать значения
только от 0 до 31) с целью вызова процедуры, использующей динамическое рас-
пределение памяти в стеке для своих локальных переменных. Так, команда
ептег 2048,3 — .
помещает в стек указатели на стековый кадр текущей процедуры и той, из кото-
рой вызывалась текущая, создает стековый кадр размером 2 Кб для вызываемой
*
Непривилегированные команды
процедуры и помещает в ЕВР адрес начала
кадра. Пусть процедура МА!М имеет уровень
старый ЕВР
вложенности 0, процедура РКОСА запускает-
ся из МАМ и, имеет уровень вложенности 1, ЕВР для МАП
и РКОСВ запускается из РВОСА с уровнем
вложенности 2. Тогда стек при. входе в проце-
дуру МАГМ имеет вид, показанный на рис. 10.
Теперь процедура МАГМ может определять
свои локальные переменные в памяти, исполь-
зуя текущее значение ЕВР Рис. 10. Стековый кадр
На первом урбвне вложенности процедура процедуры нулевого уровня
РВОСА, как показано на рис. 11, может созда- (МАМ)
вать свои локальные переменные, применяя текущее значение ЕВР и получит до-
ступ к локальным переменным процедуры МАТХ, используя значение ЕВР для
МАГУ, помещенное в стек командой ЕМТЕВ.
Процедура РКОСВ на втором уровне вложен-
ности (см. рис. 12) получает доступ как к локаль-
ным переменным процедуры РКОСА, применяя старый ЕВР
значение ЕВР для РКОСА, так и к локальным ЕВР для МАМ
переменным процедуры МАПМ, используя зна- локальные

чение ЕВР для МАГУ. ! переменные ,;

ЕВР для МАПМ


ЕВР для МАГУ
ЕВР для РКОСА
локальные
! переменные '
для РКОСА
<—— ЕВР

° локальные |

Рис. 11. Стековый кадр Рис. 12. Стековый кадр процедуры


процедуры первого уровня (РВОСА) второго уровня (РВОСВ)

Команда Назначение Процессор


СЕАУЕ Выход из процедуры 80186

Команда выполняет действия, противоположные команде ЕМТЕК. Фактически


СЕАУЕ только копирует содержимое ЕВР в ЕЗР тем самым выбрасывая из стека
5111 |11 Процессоры 4е! в реальном режиме
весь кадр, созданный последней выполненной командой ЕМТЕЕК, и считывает из
стека ЕВР для предыдущей процедуры, что одновременно восстанавливает и зна-
чение, которое имел ЕЗР до вызова последней команды ЕМТЕК. |
2.3.8. Строковые операции
Все команды для работы со строками считают, что строка-источник находится
по адресу 05:51 (или О$:Е$ 1), то есть в сегменте памяти, указанном в 0$ со сме-
щением в $1, а строка-приемник - соответственно в ЕЗ:01 (или ЕЗ; ЕБГ); Кроме
того, все строковые команды работают только с одним элементом строки (байтом,
словом или двойным словом) за один раз. Для того чтобы команда выполнялась .
над всей строкой, необходим один из префиксов повторения операций.
—_—_—_иди_иди
Команда Назначение Процессор
ВЕР Повторять . 8086
'ВЕРЕ” ° Повторять, пока равно 8086
ЛЕРМЕ Повторять, Пока не равно = 8086
ВЕРХ Повторять, пока ноль р '8086
ВЕРМ: | `Повторять, пока не ноль № 8086

Все перечисленные команды являются префиксами для операций над строка-


ми. Любой из префиксов выполняет следующую за ним команду строковой обра-
ботки столько раз, сколько указано в регистре ЕСХ (или СХ, в зависимости от
разрядности адреса), уменьшая его при каждом выполнении команды на 1. Кроме
того, ВЕРА и ВЕРЕ прекращают повторения команды, если флаг 7Е сброшен в 0,
а ВЕРМА и КЕРМЕ прекращают повторения, если флаг 7Е установлен в 1. Пре-
фикс ВЕР обычно используется с командами П\$, ОЧТ$, МОУ$, 100$, $ТО$,
а префиксы ВЕРЕ, ВЕРМЕ, ВЕРА и ВЕРМИ, - с командами СМР$ и $СА$. Пове-
дение префиксов в других случаях не определено.
Команда Назначение Процессор |
МО\У$ приемник, источник Копирование строки 8086
МОУ$В Копирование строки байтов 8086
МОУ$М Копирование строки слов 8086
МОУ5О Копирование строки двойных слов 80386

Копирует один байт (МОУЗВ), слово (МОУ$\\) или двойное слово (МОУ$О)
из памяти по адресу О5:Е$Т (или 05:51, в зависимости от разрядности адреса) в па-
мять по адресу Е:ЕП] (или Е5:ОГ). При использовании формы записи МОУ$
ассемблер сам определяет по типу указанных операндов (принято указывать имена
копируемых строк, но можно применять любые два операнда подходящего типа), ка-
кую из трех форм этой команды (МОУЗВ, МОУ$\/ или МОУ$О) выбрать. Исполь-
зуя МОУ5 с операндами, разрешается заменить регистр 0$ другим с помощью пре-
фикса замены сегмента (Е$:, С5;, Е$:, С$;, $$:), регистр Е$ заменить нельзя. После
выполнения команды регистры Е$Е (или $1) и ЕП (или ОТ) увеличиваются на 1, 2
или 4 (если копируются байты, слова или двойные слова), когда флаг ОЕ = 0,
Непривилегированные команды ПИТ 155
и уменьшаются, когда ОЕ = 1. Команда МОУ$ с префиксом ВЕР выполняет копи-
рование строки длиной в ЕСХ (или СХ) байтов, слов или двойных слов.

Команда Назначение Процессор


СМР5 приемник, источник Сравнение строк 8086
СМРЗВ Сравнение строк байтов ‚ 8086
СМРЗМ < Сравнение строк слов . ` 8086
СМР5Б Сравнение строк двойных слов , 80386

Сравнивает один байт (СМРЗВ), слово (СМР$УУ) или двойное слово (СМР$Р)
из памяти по адресу 05:Е$1 (или 05:31, в зависимости от разрядности адреса) с бай-
том, словом или двойным словом по адресу ЕЗ:ЕПЛ (или ЕЗ:01) и устанавливает
флаги аналогично команде СМР При использовании формы записи СМР$ ассемб-
лер сам определяет по типу указанных операндов (принято указывать имена срав-
ниваемых строк, но можно использовать любые два операнда подходящего типа), .
какую из трех форм этой команды (СМРЗВ, СМР5У/ или СМР5О) выбрать.
Применяя СМР5 с операндами, можно заменить регистр 0$ другим, воспользо-
завшись префиксом замены сегмента (Е5;:, С$;, Е$;:, С$;:, $5: ), регистр Е$ заменить
нельзя. После выполнения команды регистры Е$] (или ЭТ) и ЕПГ (или ОТ) уве-
личиваются на 1, 2 или 4 (если сравниваются байты, слова или двойные слова),
хогда флаг ОЕ= 0, и уменьшаются, когда РЕ = 1. Команда СМР$ с префиксами
КЕРМЕ/КЕРМ2 или ВЕРЕ/ВЕРУ выполняет сравнение строки длиной в ЕСХ
‹ или СХ) байтов, слов или двойных слов. В первом случае сравнение продолжает-
-я до первого совпадения в строках, а во втором — до первого несовпадения:
ри
Команда Назначение Процессор
$СА$ приемник | Сканирование строки 8086
$САЗВ Сканирование строки байтов . 8086
САМ Сканирование строки слов 8086
$САЗО Сканирование строки двойных слов 80386

Сравнивает содержимое регистра АТ. ($СА$В), АХ ($СА$У”) или ЕАХ ($САЗО)


г байтом, словом или двойным словом из памяти по адресу. ЕЗ: ЕП] (или ЕЗ:П. в за-
зисимости от разрядности адреса) и устанавливает флаги аналогично команде СМР
При использовании формы записи $СА$ ассемблер сам определяет по типу указан-
зого операнда (принято указывать имя сканируемой строки, но можно использовать
любой операнд подходящего типа), какую из трех форм этой команды (ЗСАЗВ,
ЗСАЗУ или $СА$О) выбрать. После выполнения команды регистр ЕПТ (или ОГ)
узеличивается на 1, 2 или 4 (если сканируются байты, слова или двойные слова),
=_гда флаг ОЕ- 0, и уменьшается, когда ОЕ = 1. Команда $СА$ с префиксами
КЕРМЕ/ВЕРМА или КЕРЕ/КЕРА, выполняет сканирование строки длиной в ЕСХ
и или СХ) байтов, слов или двойных слов. В первом случае сканирование продолжа-
ется до первого элемента строки, совпадающего с содержимым аккумулятора. а во
зтором— до первого отличного.
56 || 1111] Процессоры 1т{е! в реальном режиме
Команда Назначение _ Процессор

1005 источник Чтение из строки 8086


тоО$В Чтение байта из строки | _ 8086
+00$\М р Чтение слова из строки ` 8086
Ео0$В ` Чтение двойного слова из строки 80386

Копирует один байт (ГООЗВ), слово ((ОР$У\/) или двойное слово (1005$)
‚ из памяти по адресу 05:Е51 (или О5:$Т, в зависимости от разряяности адреса)
_в регистр АТ, АХ или ЕАХ соответственно. При использовании формы записи
ГОО5 ассемблер сам определяет по типу указанного операнда (принято указы-
вать имя строки, но можно использовать любой операнд подходящего типа), ка-
кую из трех форм этой команды (ГООЗВ, 1ОО$У/ или [ОО$) выбрать. Приме-
няя [05 с операндом, можно заменить регистр 0$ на другой с помощью
префикса замены сегмента (Е$:, С5:, Е$:, С$:, 55:). После выполнения команды
регистр Е$ЗТ (или $Т) увеличивается на 1, 2 или 4 (если считывается байт, слово
или двойное слово), когда флаг ОЕ = 0, и уменьшаётся, когда ОЕ = 1. Команда
ГОО5 с префиксом ВЕР выполнит копирование строки длиной в ЕСХ (или СХ),
и ваккумуляторе окажется последний элемент строки. На самом деле 1ОО$ ис-
пользуют без префиксов, часто внутри цикла в паре с командой ЗТО$, так что
ГОО считывает число, другие команды выполняют над ним какие-нибудь дей-
ствия, а затем ЗТО$ записывает измененное число на прежнее место в памяти.

Команда Назначение Процессор


$ТО$ приемник Запись в строку 8086
$То$В Запись-байта в строку | 8086
$10$5\М Запись слова в строку 8086
$10$0 : Запись двойного слова в строку 80386

Копирует регистр АГ. (ЗТОЗВ), АХ (5ТОЗУ) или ЕАХ ($ТО5) влпамять по


адресу ЕЗ:ЕОТ (или Е5:0} в зависимости от разрядности адреса). При использо-
вании формы записи ЭТО$ ассемблер сам определяет по типу указанного операн-
да (принято указывать имя строки, но можно использовать любой операнд под-
ходящего типа), какую из трех форм этой команды (ЗТОЗВ, ЗТО$\/ или $ТО$О)
выбрать. После выполнения команды регистр ЕПГ (или ОТ) увеличивается на
1, 2 или 4 (если копируется байт, слово или двойное слово), когда флаг ОЕ = 0,
и уменьшается, когда ОЁ = 1. Команда ЗТО$ с префиксом ВЕР заполнит строку
длиной в ЕСХ (или СХ) числом, находящимся в аккумуляторе.

Команда Назначение Процессор


1№5$ источник,
ОХ Чтение строки из порта 80186
М$5В Чтение строки байт из порта 80186
1М$\М Чтение строки слов из порта 80186
№$О Чтение строки двойных слов из порта 80386
Непривилегированные команды ЕЕ
ЕТ т 57
Считывает из порта ввода-вывода, номер которого указан в регистре ОХ, байт
‚ [УЗВ), слово (9$ \)) или двойное слово (М5) в память по адресу ЕЗ:ЕО] (или
=5:Т1 в зависимости от разрядности адреса). При использовании формы записи
№5 ассемблер определяет по типу указанного операнда, какую из`трех форм этой
хоманды (ПУЗВ, ПМ5\ или 1$) употребить. После выполнения команды ре-
гистр ЕБГ (или 01) увеличивается на 1, 2 или 4 (если считывается байт, слово
или двойное слово), когда флаг ОЕ = 0, и уменьшается, когда ОЕ = 1. Команда
№5 с префиксом ВЕР считывает блок данных из порта длиной в ЕСХ (или СХ)
Зайтов, слов или двойных слов. | ”
мзж——
ид
Команда Назначение Процессор
ОЧТ$ ОХ, приемник | Запись строки в порт 80186
ОТВ Запись строки байтов в порт 80186
ОУТ$М Запись строки слов в порт 80186
ОУТ$О Запись строки двойных слов в порт 80386

Записывает в порт ввода-вывода, номер которого указан в регистре ОХ, байт


ОПТЗВ), слово (ОО`Т$ У) или двойное слово (ОЧТЗР) из памяти по ‘адресу
Э5:Е$1 (или 2$:$1, в зависимости от разрядности адреса). При использовании
эормы записи ООТ$ ассемблер определяет по типу указанного операнда, какую
1з трех форм этой команды (ООТЗВ, ООТ$\ или ОПТ$О) употребить. Приме-
чяя ОПТ$ с операндами, также можно заменить регистр 2$ другим с помощью
зрефикса замены сегмента (Е$:, С$;:, ЕЗ;:, С$;, 55:). После выполнения команды
регистр ЕЗТ (или $Т) увеличивается на 1, 2 или 4 (если считывается байт, слово
или двойное слово), когда флаг ПЕ = 0, и уменьшается, когда ОЕ = 1. Команда
ОПТ$ с префиксом КЕР записывает блок данных размером в ЕСХ (или СХ) бай-
тов, слов или двойных слов в указанный порт. Все процессоры до Репита не про-
зеряли готовность порта принять новые данные в ходе выполнения команды КЕР
ОЧТ5, так что, если порт не успевал обрабатывать информацию с той скорос-
тью, с которой ее поставляла эта команда, часть данных терялась.

2.3.9. Управление флагами


——_—_д—икидодидд
Команда р . Назначение Процессор
$ТС Установить флаг переноса 8086

Устанавливает флаг СЕВ 1. |


ЫУы——_—_
Команда Назначение Процессор
сес о Сбросить флаг переноса 8086

Сбрасывает флаг СЕв 0. |


ди
Команда Назначение . . Процессор
смс Инвертировать флаг‘переноса 8086
ЕЕ И МИИНО" — Процессоры иче! в реальном режиме
Инвертирует флаг СЕ
Команда | р Назначение . Процессор

$ТО Установить флаг направления | 8086

Устанавливает флаг РЕ в 1, так что при последующих строковых операциях


регистры БГ и $1 будут уменьшаться.
Команда | | Назначение ‚ Процессор
сер Сбросить флаг направления | | 8086

Сбрасывает флаг ОЕ в 0, так что при последующих строковых операциях ре-


гистры`П] и $1 будут увеличиваться.

Команда Назначение . Процессор

ГАНЕ | Загрузить флаги состояния в АН 8086

Копирует младший байт регистра ЕТ.АС$ в АН, включая флаги ЗЕ (бит 7), СЕ
(бит б), АЕ (бит 4), РЕ (бит 2) и СЕ (бит 0). Бит 1 устанавливается в 1, биты 3
и5-в0. :
Команда Назначение Процессор
ЗАНЕ Загрузить флаги состояния из АН 8086

Загружает флаги ЗЕ 2Е, АЕ РЕи СЕ из регистра АН значениями битов 7, 6, 4, 2


и 0 соответственно. Зарезервированные биты 1, 3и 5 регистра флагов не изменяются.

Команда Назначение Процессор


РУЗНЕ | Поместить ЕЕАС$ в стек 8086
РУЗНЕО Поместить ЕРСАС$ в стек 80386

Эти команды копируют содержимое регистра ЕГАС$ или ЕЕГАС$ в стек


(уменьшая 5Р или ЕБЗР на 2 или 4 соответственно). При копировании регистра
ЕЕРАС$ флаги УМ и КЕ (биты 16 и 17) не копируются, а соответствующие биты
в двойном слове, помещенном в стек, обнуляются.
Команда Назначение Процессор
РОРЕ Загрузить ЕЕАС$ из стека 8086
РОРЕВ Загрузить ЕРЕАС$ из стека- 80386

Считывает из вершины стека слово (РОРЕ) или двойное слово (РОРЕР) и по-
мещает в регистр ЕТ.АС$ или ЕЕЕАС$. Эффект этих команд зависит от режима,
в котором выполняется программа: в реальном и защищенном режимах с уров-
нем привилегий 0 модифицируются все незарезервированные флаги в ЕРГ.АС$,
кроме УТР, УТЕ и УМ. У[Р и УТЕ обнуляются, и УМ не изменяется. В защищен-
ном режиме с уровнем привилегий, большим нуля, но меньшим или равным
.
Непривилегированные команды ИО!| 59
ТОРГ, модифицируются все флаги, кроме УТР, УТЕ УМ и ГОРГ. В режиме У86 не
модифицируются флаги УТЕ, У[Р УМ, ОРГ и ВЕ

Команда Назначение Процессор


оы Запретить прерывания 8086

‚ Сбрасывает флаг ТЕ в 0. После выполнения этой команды процессор игнори-


рует все прерывания от внешних устройств (кроме ММП). В защищенном режиме
эта команда, так же как и все другие команды, модифицирующие флаг 1Е (РОРЕ
или ВЕТ), выполняется, только если программе даны соответствующие приви-
легии (СР1. < 1ОРР.).

Команда Назначение | Процессор


и | Разрешить прерывания 8086

Устанавливает флаг [Е в 1, отменяя тем самым действие команды СТЛ.

Команда . ` Назначение Процессор


ЗАЕС | Установить АЁ в соответствии с СЕ 8086

Устанавливает АГ. в РЕВ, если флаг СЕ = |, и сбрасывает в 001, если СЕ = 0. Это


недокументированная команда с кодом 006, присутствующая во всех процессо-
зах Пе] и совместимых с ними (начиная с 8086). В документации на Репцит Рго
команда ЗАС упоминается в общем списке команд, но ее действие не описывается
‹ оно аналогично 5ВВ АГ. АТ, однако значения флагов не изменяются). .

2.3.10. Загрузка сегментных регистров


Команда Назначение . Процессор
0$ приемник, источник Загрузить адрес, используя 05 8086
ЬЕ$ приемник, источник Загрузить адрес, используя Е$ 8086
$ приемник, источник Загрузить адрес, используя Е$ 80386
16$ приемник, источник Загрузить адрес, используя @5 80386
$$ приемник, источник Загрузить адрес, используя 5$ 8086

Второй операнд (источник) для всех этих команд — переменная в памяти раз-
мером в 32 или 48 бит (в зависимости от разрядности операндов). Первые 16 или
32 бита из этой переменной загружаются в регистр общего назначения, указанный
з качестве первого операнда, а следующие 16 бит - в соответствующий сегмент-
ный регистр (05$ для [.0$, Е$ для 1.Е$ ит. д.). В защищенном режиме значение,
загружаемое в сегментный регистр, всегда должно быть правильным селектором
сегмента (в реальном режиме любое число может использоваться как селектор).
2.3.11. Другие команды
Команда Назначение Процессор
ОР Отсутствие операции 8086
[557 ОР ООО ОО ОО В ВАЗ Процессоры име! в реальном режиме
МОР - однобайтная команда (код 906), которая не выполняет ничего, только
занимает место и время. Код этой команды фактически соответствует ХСНС
АГ, АГ. Многие команды разрешается записать так, что они не будут приводить
ни к каким действиям, например:
оу ах, ах ; 2 байта.
хсп9 ах, ах. ; 2 байта.
]еа Ьх, [6х+0] ; 3 байта (801, 5Ей, ООН, но многие ассемблеры,
‚ встретив такую команду, реально используют более
; короткую 1еа 5х, [6х] с кодом 808 1ЕП).
$11 еах, 0 ‚ 4 байта. |
эНга еах, еах, 0 ‚ 5 байт.

Команда Назначение | Процессор

ЕоскК Префикс блокировки шины данных 8086

На все время выполнения команды, снабженной таким префиксом, будет заб-


локирована шина данных, и если в системе присутствует другой процессор, он не
сможет обращаться к памяти, пока не закончится выполнение команды с префик-
сом ГОСК. Команда ХСНС всегда выполняется автоматически с блокировкой до-
ступа к памяти, даже если префикс ГОСК не указан. Этот префикс можно исполь-
зовать только с командами АОО, АОС, АМО, ВТС, ВТК, ВТ$, СМРХСНС, ОЕС,
ПУС, МЕ©, МОТ, ОБ, $ВВ, ЗОВ, ХОВ, ХАШОШ и ХСНС.

Команда Назначение Процессор

ир2 Неопределенная операция Рб

Эта команда всегда вызывает ошибку «неопределенная операция» (исключе-


ние #0 О). Впервые она описана как таковая для РепЧит РГго, но во всех предыду-
щих процессорах ЧО2 (код ОЕВ ОВВЬ) не была определена и, естественно, приво-
дила к такой же ошибке. Команда предназначена для тестирования программного
обеспечения, в частности операционных систем, которые должны уметь коррект-
но обрабатывать такую ошибку. Название команды происходит от команды 00
(код ОРВ ОЕЕЬ), которая была определена АМШ для процессоров АМО К5.
Команда О Назначение . . Процессор .
СРОЮ ` Идентификация процессора 80486

СРО сообщает информацию о производителе, типе и модификации процес-


сора и о наличии различных расширений. Команда СРИТО поддерживается [ше],
начиная с процессоров ше! 804860Х/5Х/ОХ2 $1, ОМС 45$, Сумх М1, АМО
804860Х4. Попробуйте установить флаг 1 в 1 (бит 21 в регистре ЕЕГ.АС5) — если
это получается, значит, команда СРО поддерживается.
Результат работы СРО зависит от значения регистра ЕАХ. Если ЕАХ = 0,
СРУТ возвращает в ЕАХ максимальное значение, с которым ее можно вызывать
(2 для Рб, 1 для Р5), а регистры ЕВХ-ЕСХ:Е
ОХ содержат 12-байтную строку - иден-
‚ тификатор производителя (см. табл. 8).
Непривилег ированные команды ПА НОЕ
В И
Таблица 8. Строки производителей в СРУО

УМС УМС УМС УМС


Супх Супхтуеаа
АМО АщпепюАдАМО
еж МехСепОпуеп
Сетаиг Тесплоюду СепаиНа!з

Например, для процессоров [ие] регистр ЕВХ содержит Сепи (156Е654ТЬ),


ЕСХ - ше! (49656Е69В), а ЕОХ — пе! (6С65746ЕЪ).
Если ЕАХ = 1, СРОШ возвращает в ЕАХ информацию о версии процессора,
авЕМОХ - сведения о поддерживаемых расширениях. Многие понятия в этом опи-
сании относятся к работе процессора в защищенном режиме и рассмотрены ниже.
Информация о версии процессора:
Биты 3-0 — модификация.
Биты 7-4 - модель.
= [
Биты 11-8 — семейство (3 для 386, 4 для 486, 5 для Репиит, 6 для РепНит Рто).
Биты 13-12 — тин (0 - ОЕМ, 1 - Оуегануе, 2 — Риа!|).
Биты 31-14 — зарезервированы и равны нулю.
Поддерживаемые расширения (регистр ЕОХ):
Бит 0: ЕРО — процессор содержит ЕРЧО и может выполнять весь набор команд
80387. -
Бит 1: УМЕ - процессор поддерживает усовершенствованный режим \У86
(флаги УТЕ и УТР в ЕЕГАС$, биты УМЕ и РУ в СВО).
Бит 2: ОЕ - процессор поддерживает точки останова по вводу/выводу, бит РЕ
в СВО.
‚ Бит 3: РЗЕ - процессор поддерживает страницы до 4 Мб, бит РЕ в СВА, мо-
дифицированные биты в элементах списков страниц (РОЕ) и таблиц стра-
ниц (РТЕ).
Бит 4: ТЗС -— процессор поддерживает команду КОТЗС и бит Т$С в СКА.
Бит 5: М$К- процессор поддерживает команды КОМ$В и \/ВМ$Е и машин-
но-специфичные регистры, совместимые с Репйит.
Бит 6: РАЕ - процессор поддерживает физические адреса больше 32 бит, до-
полнительный уровень в таблицах трансляции страниц, страницы по 2 Мб
и бит РАЕ в СВА. Число битов для физических адресов зависит от модели
процессора. Так, Репёит Рго поддерживает 36 бит. |
Бит 6: РТЕ (только для Суйх). ря

Бит 7: МСЕ - процессор поддерживает бит МСЕ в СКА.


Бит 8: СХ8 — процессор поддерживает команду СМРХСНСВ8В.
Бит 9: АР[С - процессор содержит встроенный контроллер прерываний
(АРТС), который активизирован и доступен.
Бит 9: РСЕ (только для АМО).
СУЗИИШИВИШИИ | —— Процессоры ие! в реальном режиме
Бит 10: зарезервирован.
Бит 11: ЗЕР- процессор поддерживает быстрые системные вызовы, команды
° ЗУЗЕМТЕК и ЗУЗЕХИТ (Репцит П).
Бит 12: МТВК — процессор поддерживает машинно-специфичные регистры
МТВЕ.
Бит 13: РСЕ- процессор поддерживает бит РСЕ в СКА и глобальные флаги
в РТПЕ и РТЕ, указывающие элементы 'ТТ.В, которые принадлежат сразу
нескольким задачам.
Бит 14: МСА - процессор поддерживает машинно-специфичный регистр
МСС_САР. |
Бит 15: СМОУ - процессор поддерживает команды СМОУСсс и (если бит 0
ЕБХ установлен) ЕСМО\сс (Репиит Рго).
Бит 16; РАТ- процессор поддерживает таблицу атрибутов страниц.
Биты 17-22: зарезервированы.
Бит 23: ММХ - процессор поддерживает набор команд ММХ.
Бит 24; ЕХЗК - процессор поддерживает команды быстрого чтения/записи
(ММХ2).
Бит 25: $3Е- процессор поддерживает расширения 55Е (Репёит Ш).
Биты 31—26; зарезервированы.
Если ЕАХ = 2, СРО на процессорах семейства Рб возвращает в регистрах
ЕАХ, ЕВХ, ЕСХ и ЕОХ информацию о кэшахи ТТ.В. Самый младший байт ЕАХ
(регистр АТ.) определяет, сколько раз надо вызвать СРО с ЕАХ = 2, чтобы полу-
чить информацию обо всех кэшах (1 для Репнит Рго и Репиии П). Самый старший
бит (бит 31) каждого регистра указывает, содержит ли этот регистр правильную ин-
формацию (бит 31 = 0) или он зарезервирован (бит 31 = 1). В первом случае регистр
содержит информацию в 1-байтных дескрипторах со следующими значениями:
00}— пустой дескриптор;
016 - ТГВ команд, 4-килобайтные страницы, 4-“сторонняя ассоциативность,
32 элемента;
025 —ТТ.В команд, 4- мегабайтные страницы, 4-сторонняя ассоциативность,
4 элемента;
ОЗЬ-—ТГВ данных, 4-килобайтные страницы, 4-сторонняя ассоциативность,
64 элемента;
О4Ь — ТГВ данных, 4- мегабайтные страницы, 4-сторонняя ассоциативность,
8 элементов;
06Ъ -— кэш команд, 8 Кб, 4-сторонняя ассоциативность, 32 байта в строке; '
08В — кэп! команд, 16 Кб, 4-сторонняя ассоциативность, 32 байта в строке;
ОА - кэш данных, 8 Кб, 2-сторонняя ассоциативность, 32 байта в строке;
ОСЬ— кэш данных, 16 Кб, 2-сторонняя ассоциативность, 32 байта в строке;
41В- унифицированный кэш, 128 Кб, 4-сторонняя ассоциативность, 32 байта
в строке; |
428— унифицированный кэш, 256 Кб, 4-сторонняя ассоциативность, 32байта
в строке;
АЗЬ -- унифицированный кэш, 512 Кб, 4-сторонняя ассоциативность, 32 байта
в строке;
Числа с плавающей запятой =
44}- унифицированный кэш, 1 Мб, 4-сторонняя ассоциативность, 32 байта
в строке. .
Совместимые с ше! процессоры АМ и Супх поддерживают вызов «расши-
ренных функций» СРО со значениями ЕАХ, в которых самый старший бит
всегда установлен в 1.
ЕАХ= 800000001: возвращает в ЕАХ максимальный номер расширенной фун-
кции СРОТО, поддерживаемой данным процессором.
ЕАХ= 800000011: возвращает в ЕАХ 051ХЬ для АМШО К5 (Х ‘номер модифи-
кации) или 061ХВ для АМО Кб. В ЕОХ эта функция возвращает информацию
о поддерживаемых расширениях (указаны только флаги, отличающиеся ат
СРОШ с ЕАХ = 1).
Бит 5: М5К - процессор поддерживает машинно-специфичные регистры, со-
вместимые с К5.
Бит 10: процессор поддерживает команды ЗУЗСА!Т. и ЗУЗВЕТ.
‚ Бит 16: процессор поддерживает команды ЕСМО\Усс.
Бит 24: процессор поддерживает ММХ с расширениями от Супх.
Бит 25: процессор поддерживает набор команд АМО ЗО.
ЕАХ = 800000025, 800000031 и 800000048 — последовательный вызов СРИТО
с этими значениями в ЕАХ возвращает в ЕАХ:ЕВХ:ЕСХ:ЕШОХ последовательно
четыре 16-байтные части строки — имени процессора. Например: АМО-К5(ит)
Ргосеззог. .
ЕАХ =- 800000058 — команда возвращает информацию о ТТ-В в регистре ЕВХ
(старшее слфво— ТЁЕВ данных, младше слово — ТЕВ команд, старший байт - ас-
социативность, младший байт — число элементов), о кэше данных в регистре ЕСХ
и о кэше команд в регистре ЕОХ (биты 31—24- размер в килобайтах, биты 23-16 —
ассоциативность, биты 15-8 — число диНий` на Тэг, биты 7—0 — число байтов на
линию).

2.4. Числа с плавающей запятой


В процессорах Пже| все операции с плавающей запятой выполняет специаль-
ное устройство — ЕРО (Е!оайпя Рони Оп!) - с собственными регистрами и набо-
ром команд, поставлявшееся сначала в виде сопроцессора (8087, 80287, 80387,
80487), а начиная с 804860Х - встраивающееся в основной процессор. ЕРО пол-
ностью соответствует стандартам [ЕЕЁЕ 754 и ТЕЕЕ 854 (с 80486).

2.4.1. Типы данных ЕРИУ


Числовой процессор может выполнять операции с семью разными типами дан-
НЫХ, представленными в табл. 9: три целых
1 двоичных, один целый десятичный
и три с плавающей запятой.
Вещественные числа хранятся, как и все данные, в форме двоичных чисел.
Двоичная запись числа с плавающей запятой аналогична десятичной, только по-
зиции справа от запятой соответствуют не делению на 10 в соответствующей сте-
пени, а делению на 2. Переведем для примера в двоичный вид число 0,625:
6411 ||] ’ . Процессоры Не! в реальном режиме
Таблица 9. Типы данных ЕРУ

Количество
Тип данных Бит . значащих Пределы
цифр

Короткое целое 7 32 | 9

Длинное слово
Упакованное десятичное
т
Короткое вещественное 32 — 7 1,18%10-38 ... 3,40%1038
Длинное вещественное 64 15-16 2,23%10-308 ... 1,79х10308

аи ренное 3,37х10-з2 ... 1,1810% 2

0,625 — 1/2 = 0,125


1/4 больше, чем 0,125
0,125 - 1/8 =0
Итак, 0,625= 0,101Ъ. При записи вещественных чисел всегда выполняют нор-
мализацию — умножают число на такую степень двойки, чтобы перед десятичной
точкой стояла единица, в нашем случае
‚ 0,625 = 0,101Ъ = 1,01 Хх2-1.
Говорят, что число имеет мантиссу 1,01 и экспоненту —1. Как можно заметить,
при использовании этого алгоритма первая цифра мантиссы всегда равна 1, по-
этому ее можно не писать, увеличивая тем самым точность представления числа
дополнительно на 1 бит. Кроме того, значение экспоненты хранят не в виде цело-
го со знаком, а в виде суммы с некоторым числом так, чтобы всегда было только
положительное число и чтобы вещественные числа легко сопоставлялись —
в большинстве случаев достаточно сравнить экспоненту. Теперь мы можем рас-
смотреть вещественные форматы ГЕЕЕ, применяемые в процессорах [14е!:
© короткое вещественное: бит 31 - знак мантиссы, биты 30—23 - 8-битная эк-
спонента +127, биты 22-0 — 23-битная мантисса без первой цифры;
Э длинное вещественное: бит 63 - знак мантиссы, биты 62—52 — 11-битная эк-
спонента +1024; биты 51-0 - 52-битная мантисса без первой цифры;
9 расширенное вещественное: бит 79 - знак мантиссы, биты 78—64 — 15-бит-
ная экспонента +16 383, биты о — 64-битная мантисса с первой цифрой
(то есть бит 63 равен 1).
ЕРО выполняет все вычисления в 80-битном расширенном формате, а 32-
и 64-битные числа используются для обмена данными с основным процессором
и памятью.

@& Кроме обычных чисел формат [ЕЕЁ предусматривает несколько специаль-


ных случаев, которые могут получаться в результате математических
операций и над которыми также можно выполнять отдельные операции:
О полежеытельный ноль: все биты числа сброшены в’ноль;
О отрицательный ноль: знаковый бит — 1, все остальные биты - нули;
Числа с плавающей запятой | 111!65
`@ положительная бесконечность: знаковый бит — 0, все биты мантисс
ы —
0, все биты экспоненты - 1;
.
отрицательная бесконечность: знаковый бит - 1, все биты мантиссы —
0, все биты экспоненты - 1;
О денормализованные числа: все биты экспоненты — 0 (используются для ра-
боты с очень маленькими числами — до 10-1644 ддя расширенной точности);
О неопределенность: знаковый бит - 1, первый бит мантиссы (первые два
для 80-битных чисел) — 1, а остальные - 0, все биты экспоненты — 1;
О не-число типа 5МАМ (сигнальное): все биты экспоненты — 1, первый бит
мантиссы — 0. (для 80-битных чисел первые два бита мантиссы — 10),
а среди остальных битов есть единицы;
О не-число типа ОМАМ (тихое): все биты экспоненты - 1, первый бит ман-
тиссы (первые два для 80-битных чисел) - 1, среди остальных битов
есть единицы. Неопределенность — один из вариантов ОМАМ:
О неподдерживаемое число: все остальные ситуации. |
Остальные форматы данных ЕРИ также допускают неопределенность —'
единица в старшем бите и'нули в остальных для целых чисел, и старшие _
16 бит — единицы для упакованных десятичных чисел.
д
2.4.2. Регистры ЕРИ
ЕРО предоставляет восемь регистров для хранения данных и пять вспомога
-
тельных регистров. |
Регистры данных (КО - В7) не адресуются по именам, как регистры основног
о
процессора, а рассматриваются в качестве стека, вершина которого называет
ся 5Т,
более глубокие элементы — $Т(1), $Т(2) и так далее до $Т(7). Если, например
,
в какой-то момент времени регистр В5 называется 5Т (см. рис. 13), то
после запи-
си в этот стек числа оно будет записано в'регистр ВА, который станет называть
ся
ЗТ, В5 станет называться 5Т(1) ит. д.

в 9%
ОИ Г.
И
И
И
С ОНИ К
И
к
79
©
0
СВ ЕР
$8 ЕОР
ТУ 47 0
15 0

Рис. 13. Регистры ЕРИ


3 Зак. 459
6611 |111 Процессоры И\{е! в реальном режиме
ООН
Крегистрам ЮО- Е7 нельзя обращаться напрямую;то именам, но если про-
цессор поддерживает расширение ММХ, то мантиссы, находящиеся в этих
регистрах, становятся доступны, как ММО — ММ:.

Регистр состояний $В содержит слово состояния ЕР:


бит 15: В — занятость ЕРУ -` этот флаг существует-для совместимости с 8087,
_ иего значение всегда совпадает с Е5
бит 14: СЗ-— условный флаг 3
биты 13-11: ТОР - число от 0 до 7, показывающее, какой из регистров данных
Во - В7 в настоящий момент является вершиной стёка,
бит 10: С2- условный флаг 2
бит 9: С1 — условный флаг 1
бит 8: С0 -— условный флаг 0
бит 7: Е$ — общий флаг ошибки - равен 1, если произошло хотя бы одно не-
маскированное исключение
бит 6: ЗЕ — ошибка стека. Если С1 = 1, произошло переполнение (команда пы-
талась писать в непустую позицию в стеке), если С1 = 0, произошло
антипереполнение (команда пыталась считать число из пустой
позиции в стеке)
-бит 5: РЕ - ‘флаг неточного результата — результат не может быть представ-
лен точно
бит 4: ОЕ - флаг антипереполнения - результат слишком маленький
бит 3: ОЕ - флаг переполнения - результат слишком большой
бит 2: 2Е — флаг деления на ноль — выполнено деление на ноль
бит 1: РЕ - флаг денормализованного операнда — выполнена операция ‘над’
денормализованным числом
бит 0: 1Е -— флаг недопустимой операции — произошла ошибка стека (5Е = 1)
или выполнена недопустимая операция |
Биты С0 — СЗ применяются так же, как и биты состояния в основном процес- |
соре, - их значения отражают результат выполнения предыдущей команды и ис-
пользуются для условных переходов; команды |
1$15м ах
Зе
Загл}

копируют значения битов в регистр ЕГАС$ так, что флаг С0 переходит в СЁ С2 —


в РЕа СЗ -— в 7Е (флаг С2 теряется). |
Биты 0-5 отражают различные ошибочные ситуации, которые могут возникать
при выполнении команд ЕРУИ. Они рассмотрены в описании управляющих регистров.
Регистр управления СВ:
биты 15-13: зарезервированы:
бит 12: [С - управление бесконечностью (поддерживается для совместимо-
сти с 8087 и 80287 - вне зависимости от значения этого би-
та +о° > —оэ);
биты 11-10: ВС — управление округлением;
биты 9-8: РС. - управление точностью;
\
Числа с плавающей
запятой
ГАО И ВОНИ
биты 7-6: зарезервиров
аны;
бит 5: РМ — маска неточн
ого результата;
бит 4: (ИМ- маска антипе
реполнения;
бит 3: ОМ- маска переполнения;
бит 2: 7М — маска деления на ноль;
бит 1: ОМ- маска денормализованного опе
бит 0: [М — ранда;
маска недействительной операц
ии.
Биты ВС определяют спо
соб округления результат
ной точности (см. табл. ов команд ЕРИ до зад
ан-
10).
Таблица 10. Способы
округления

АИИС ВИССТИ
Значение ВС
Способ округления

1 К отрицательной бес
конечности
2 К положительной
бесконечности
3 К нулю
Биты РС определяют
точность результатов
ЕМЧТ, ЕТУ, ЕПГУК и команд ЕАБЬ, ЕЗОВ,
ЕЗОВТ (см. табл. 11). ЕЗОВВ,
Таблица 11. Точность
результатов

Но ОБинериая точность{92битыечот —
ИИ И И
2 [ов ба
б то
л
3 [Рбвиренная неит з )—
точность(-бии
тные чиста—
Биты 0-5 регистра СК
маскируют соответствую
кирующий бит установле щие исключения -— если
н, исключения не происх мас-
одит, а результат вызвав
шей его

пара битов (тэгов) равна


11, соответствующий рег
гистр содержит число, истр пуст. 00 означает,
01 — НОЛЬ, 10 — не-число, что ре-
ное число, неподдержива бесконечность, денорм
емое число. ализован- .
Регистры ЕР и ЕОр сод |
ержат адрес последней
е ЕПМТТ, ЕСГЕХ, ЕГОСУ, выполненной команды
, ЕЗТСУ, ЕЗТЗ У, ЕЗ (кро-
"САУЕ, ЕВЗТОВиЕ УМА ТЗУАХ, ЕЗТЕМУ, ЕГОЕ
ТТ) и адрес ее операнда МУ,
‚ обработчиках исключени соответственно и исполь
й для анализа вызвавшей зуются
его команды.
2.4.3. Исключения ЕР
и |
68 | | ||| Процессоры Н\е! в реальном режиме
флаг в регистре ЗВ устанавливается в 1 и, если маска этого исключения в регис-
тре СЁ не установлена, вызывается обычное прерывание ПМТ 106 (если бит МЕ
в регистре центрального процессора СВО установлен в 1) или 1КО13 (МТ 758),
обработчик которого может прочитать регистр ЭВ, чтобы определить тип исклю-
чения (и Е[Р, и Е,Р) и команду, которая его породила, а затем попытаться испра-
вить ситуацию. Если бит маски наступившего исключения в регистре СВ уста-
новлен в 1, по умолчанию выполняются следующие действия:
О неточный результат: результат округляется в соответствии с битами КС (на
самом деле это исключение происходит очень часто; например: дробь 1/6 не
может быть представлена десятичным вещественным числом любой точно-
сти и округляется). При этом флаг С1 показывает, в какую сторону про-
изошло округление: 0 - вниз, 1 — вверх;
о антипереполнение: результат слишком мал, чтобы быть представленным
обычным числом, — он преобразуется в денормализованнее число;
С переполнение: результат преобразуется в бесконечность соответствующего
знака; .
о деление на ноль: результат преобразуется в бесконечность соответствующе-
го знака (учитывается и знак нуля);
О денормализованный операнд: вычисление продолжается, как обычно;
О. недействительная операция: результат определяется из табл. 12.

Таблица 12. Результаты операций, приводящих к исключениям

Ошибка стека Неопределенность


Операция с неподдерживаемым числом Неопределенность

Операция с ЗМАМ _| ЯМАМ

Сравнение числа с МАМ С0=С2 = С3 =1

Сложение бесконечностей с одним знаком Неопределенность


д
или вычитание - с разным
г
Умножение нуля на бесконечность Неопределенность
Деление бесконечности на бесконечность или 0/0 й Неопределенность

Команды ЕРВЕМ и ЕРВЕМ1, если делитель - 0 : Неопределенность и С2 =0 |


или делимое - бесконечность
Тригонометрическая операция над бесконечностью Неопределенность и С2 =0

Корень или логарифм, если х < 0, 109(х+1), если х < —1 Неопределенность

ЕВЗТР, если регистр-источник пуст, содержит МАМ, Десятичная


бесконечность или превышает 18 десятичных знаков | неопределенность
т
ЕХСН, если один из операндов пуст ; Неопределенность

2.4.4. Команды пересылки данных ЕРУ


Назначение Процессор
Команда
рии
команда
РЕД источник Загрузить вещественное число в стек ° 8087
Числа с плавающей запятой 1:1
| | 69
Команда помещает содержимое источника (32-, 64- или 80-битная переменная
или 5Т(п)) в стек и уменьшает ТОР на 1. Команда ЕТО 5Т(0) делает копию вер-
шины стека.

Команда Назначение Процессор


ЕТ приемник Скопировать вещественное число из стека 8087
Е$ЗТР приемник Считать вещественное число из стека 8087

Копирует 5Т(0) в приемник (32- или 64-битную переменную или пустой


ЭТ(п) в случае ЕЗТ, 32-, 64- или 80-битную переменную или пустой ЗТ(п) в слу-
чае Е5ТР). ЕЗТР после этого выталкивает число из стека (помечает 5Т(0) как
пустой и увеличивает ТОР на один).

Команда Назначение | Процессор


РО источник Загрузить целое число в стек 8087

Преобразовывает целое число со знаком из источника (16-, 32- или 64-битная


переменная) в вещественный формат, помещает в вершину стека и уменьшает
ТОР на 1. у

Команда Назначение Процессо


ЕЗТ приемник Скопировать целое число из стека . 8087
НЗТР приемник Считать целое число из стека 8087

Преобразовывает число из вершины стека в целое со знаком и записывает его


в приемник (16- или 32-битная переменная для ЕТЗТ: 16-, 32- или 64-битная пере-
менная для ЕТЗТР). ЕИЗТР после этого выталкивает число из стека (помечает
ЗТ (0) как пустой и увеличивает ТОР на один). Попытка записи слишком боль-
шого числа, бесконечности или не-числа приводит к исключению «недопустимая
операция» (и записи целой неопределенности, если 1М = 1).

Команда Назначение Процессор


РВЕО источник Загрузить десятичное число в стек 8087

Преобразовывает ВСР число из источника (80-битная переменная в памяти),


помещает в вершину стека и уменьшает ТОР на 1.

Команда Назначение Процессор


ЕВЗТР приемник Считать десятичное число из стека 8087

Преобразовывает число из вершины стека в 80-битное упакованное десятичное,


записывает его в приемник (80-битная переменная) и выталкивает это число из
стека (помечает 5Т(0) как пустой и увеличивает ТОР на один). Попытка записи
слишком большого числа, бесконечности или не-числа приводит к исключению
«недопустимая операция» (и записи десятичной неопределенности, если 1М = 1).
701 1 | | ТЕ Процессоры |п4е! в реальном режиме.
Команда Назначение Процессор
рее
ЕХСН источник Обменять местами два регистра стека ’ 8087

Обмен местами содержимого регистра 5Т(0) и источника (регистр ЗТ(п)). |


Если операнд не указан, обменивается содержимое 5Т(0) и 5Т(1).

Команда. Назначение Процессор


т
ЕСМО\Усс приемник, источник Условная пересылка данных Рб

Это набор команд, каждая из которых копирует содержимое источника (ре-


гистр $Т(п)) в приемник (только 5Т(0)), если выполняется необходимое условие.
Реально каждое условие соответствует тем или иным значениям флагов регистра
ЕГАС$, но после команд
сом (или другие команды сравнения)
Рэм ах
саре

в регистр ЕГАС$ загружаются флаги С0, С1 и СЗ, и последующая команда из


набора ЕСМО\Усс приобретает смысл обработки результата предыдушего сравне- `
ния (см. табл. 13). 1

Таблица 13. Команды ЕСМО\Усс

ЕСМОУЕ 2Е=1 Если равно


ЕСМОУМЕ — [Е =0 Если не равно
ЕСМОУВ СЕ=1 Если меньше
ЕСМОУВЕ . ‚| СЕ=1и2Е=1 Если меньше или равно
РСМОУМВ СЕ=0 Если не меньше
ЕСМОУМВЕ СЕ=би2Е=0 Если не меньше или равно
ЕСМОУЦ —_[ВЕ =1 Если несравнимы
АСМОУМУ РЕ =0 Если сравнимы

2.4.5. Базовая арифметика ЕРИ


„Команда Назначение Процессор

РАСО приемник, источник Сложение вещественных чисел 8087


РАООР приемник, источник Сложение с выталкиванием из стека 8087
НАОО источник Сложение целых чисел 8087

`Команда выполняет сложение источника и приемника и помещает результат


в приемник. Команда ЕАОЮР после этого выталкивает 5Т(0) из стека (помечает
ЗТ() как пустой и увеличивает ТОР на один). Команды сложения могут прини-
мать следующие формы:
Числа с плавающей запя
той | ия
о АДР источник, когда исто
чником является 32- или 64-б
а приемнико итная переменная,
м - $5Т(0);
9/4АБР 5Т(0),5Т(п), ЕАБР 5 Т(п),5Т(
О), ЕАРОР 5Т. (7),5Т(0), когда исто
и приемник заданы в виде регистро чник
в ЕРИ;
9 РАБО без операндов эквивалентна
ЕАОШ $Т(0),5Т(1); ЕАРОР без опер
эквивалентна ЕАООР 5Т(1),5Т(0); андов
оЕАрр источник, когда источн
иком является 16- или 32-битна
содержащая цело я переменная,
е число, а приемником — $Т(О).
Команда
Назначение
РЗЦВ приемник, источник
Процессор
Вычитание вещественных чисе
л 8087
ЕЗИВР приемник, источник
Вычитание с выталкиванием
из стека 8087
АЗОВ источник
Вычитание целых чисел
8087
Выполняет вычитание источника
из приемника и сохраняет результа
емнике. Команда ЕЗОВР после этог т в при-
о выталкивает 5Т(0) из стека (пом
ечает $1(0)
следующие формы:
95 0В источник, когда источнико
м является 32- или 64-битная пере
содержащая вещественное число, менная,
а приемником — $Т(0);
9250В 5Т(0),5Т(п), ЕЗОВ 5Т(п),5Т 1
(0), ЕЗОВР 5Т(п),5Т(0), когда исто
и приемник заданы явно в виде реги чник
стров ЕРИ;
О 250В без операндов эквивалентна |
РОВ $Т(0),5Т(1); ЕЗИВР без опер
эквивалентна ЕЗОВР $Та),5Т( андов
0);
о Н5ОВ источник, когда источн
иком является 16- или 32-битна
содержащая целое число, а приемн я переменная,
иком — $Т(0).
Если один из операндов — бесконеч
ность, то результат — бесконечност
ветствующего знака. Если оба опер ь соот-
анда — бесконечности одного знак
не определен (происходит исключен а, результат
ие «недопустимая операция»).
Команда
Назначение
Процессор
ЕЗОВЯ приемник, источник.
Обратное вычитание вещественных чисел
ЕЗУВАР приемник, источник 8087 .
`Обратное вычитание с выталкивание
НЗОВВ источник м `8087
Обратное вычитание целых чисел | 8087
Эти команды эквивалентны Е$ ОВ/
ЕЗОВР/Е1$ОВ, но при этом они
ют вычитание приемника из источник выполня-
а, а не источника из приемника.
Команда’ ` ° Назначение
Процессор
РМ приемник, источник
Умножение вещественных чисел
ЕМУР приемник, источник 8087
Умножение с выталкиванием из
стека 8087
ЕМОЕ источник
Умножение целых чисел
8087
721 ||| |1 Процессоры Не! в реальном режиме
Выполняет умножение источника и приемника и помещает результат в при-
емник. Команда ЕМОТР после этого выталкивает 5Т(0) из стека (помечает 5'Т(0)
как пустой и увеличивает ТОР на один). Так же как и остальные команды базо-
вой арифметики, команды умножения могут принимать следующие формы:
о ЕМИЕ источник, когда источником является 32- или 64-битная переменная,
а приемником -— $Т(0);
с ЕМОЕ 5Т(0),5Т(®), ЕМОГ 5Т@),5Т(О), ЕМОЕР 5Т(п)„5Т(0), когда источник`
и приемник заданы явно в виде регистров ЕРО; .
о ЕМОГ без операндов эквивалентна ЕМОГ. $Т(0),$Т(1); ЕМОЕР без операн-
дов эквивалентна ЕМОГР 5Т(1),$Т(0);
о НМОЕ источник, когда источником является 16- или 32-битная переменная,
содержащая целое число, а приемником - 5Т(0).

Команда р Назначение Процессор

РОМ приемник, источник Деление вещественных чисел 8087


ЕОЛУР приемник, источник Деление с выталкиванием из стека | 8087
ЕИЗУ источник Деление целых чисел _ 8087

Выполняет деление приемника на источник и сохраняет результат в приемни-


ке. Команда ЕОТУР после этого выталкивает 5Т(0) из стека (помечает 5Т(0) как
пустой и увеличивает ТОР на один). Команды вычитания могут принимать сле-
дующие формы:
о РОЙ/ источник, когда ‘источником является 32- или 64-битная переменная,
содержащая вещественное число, а приемником — $Т(0);
о ЕОГУ 5Т(0),5Т@т), ЕБГУ 5Т(и),5 ТО), ЕРГУР 5Тп),5Т(0), когда источник и при-
емник заданы явно в виде регистров ЕРО;
о РОГ без операндов эквивалентна ЕМУ $Т(0),5Т(1); ЕРГУР без операндов
эквивалентна ЕОТУР $Т(1),5Т(0);
э НЬЫГУ источник, когда источником является 16- или 32-битная переменная,
содержащая целое число, а приемником -— $Т(0).
При делении бесконечности на ноль (так же как и на любое число) результат —
бесконечность, при делении нуля на бесконечность (так же как и на любое число)
результат — ноль. При делении на ноль нормального числа происходит исключе-
ние деления на ноль, аесли флаг. СМ = 1, в качестве результата записывается бес-
конечность соответствующего знака.
Команда Назначение Процессор

РОМА приемник, источник Обратное деление вещественных чисел 8087


ЕОМУЯР приемник, источник Обратное деление с выталкиванием 8087
АРУУВ источник Обратное деление целых чисел 8087

Эти команды эквивалентны ЕСЛУ/ЕОГУР/ЕПЛТУ, но при этом они выполня-


ют деление источника на приемник, а не приемника на источник.
Числа с плавающей запятой 3
Команда
Назначение _ Процессор
МР
ЕРВЕМ Найти частичный остаток от деления 8087
ЕРВЕМ1 Найти частичный остаток в стандарте 1ЕЕЕ 80387

Эти команды выполняют деление 5Т(0) на $Т(1) и помещают остаток от деле-


ния в 5Т(0). Деление осуществляется при помощи последовательных вычитаний
$Т(1) из $Т(0), но за один раз выполняется не более 64 таких вычитаний. Если
$Т(0) не стал меньше $Т(1) за это время, говорят, что в $Т(0) находится частич-
ный остаток от деления. Если был получен точный остаток, флаг С2 сбрасывает-
ся в 0, если частичный - устанавливается в 1, так что можно повторять эту коман-
ду до обнуления С2. Если вычисление привело к точному остатку, три младших
бита частного (то есть числа потребовавшихся вычитаний) сохраняются в С0, СЗ,
С1 (биты 2, 1, 0 соответственно). Например, используя ЕРВЕМ1, можно умень-
игить аргумент тангенса, вычислив его остаток от деления на п/4, тогда потребу-
ются младшие три бита частного, чтобы определить, не поменялся ли при этой
операции знак тангенса. о
Различие между ЕРВЕМи ЕРКЕМ! заключается в разном определении значения
частного. Сначала эти команды выполняют вещественное деление УТ(0»на ЗТ(1),
округляют результат (ЕРВЕМ1 - к ближайшему целому, ЕРВЕМ - к нулю), а затем,
если частное меньше 64, вычисляют точный остаток, а если больше — частичный.
Фидо —_ Ц
Команда Назначение ` Процессор
ЕАВ$ Найти абсолютное значение 8087

Если 5Т(0) был отрицательным числом - переводит его в положительное.


————_д—и———»—оЮ—»—»“»_»_дди___——_—_
Команда Назначение Процессор
ЕСН$ | ` Изменить знак 8087

Изменяет знак $Т(0), превращая положительное число в отрицательное,


и наоборот. -
Ым—®>—>——ди——д———а———_Ь——»зкжкжжж——_—оо——_—_—_—_—_——_—_
Команда. | Назначение Процессор
а
РАМОМТ . Округлить до целого : 8087

Округляет значение $Т(0) до целого числа в соответствии с режимом округ-


ления, заданным битами ВС.
м—ид———д———ы—————ц_—_ы_дд—_—_—————_——_—__—_——_—
Команда ` р Назначение Процессор
ЕЭСАЕЕ Масштабировать по степеням двойки 8087

Умножает 5Т(0) на два в степени 5Т(1) и записывает результат в 5Т(О). Зна-


чение 5Т(1) предварительно округляется в сторону нуля до целого числа. Эта
команда выполняет действие, обратное ЕХТВАСТ,
9741111] Процессоры И\е! в реальном режиме
Команда В Назначение р Процессор
дд
ЕХТВАСТ | Извлечь экспоненту и мантиссу 8087

Разделяет число в $Т(0) на мантиссу и экспоненту, сохраняет экспоненту в 5Т(0)


и помещает мантиссу в стек, так что после этого ТОР уменьшается на 1, мантисса
оказывается в $Т(0), а экспонента - в $Т(1).

Команда ` Назначение . Процессор


ово во ОО
Е5ОЛАТ __ Извлечь квадратный корень ” 8087

Вычисляет квадратный корень из 5Т(0) и сохраняет результат в 5Т(0).

2.4.6. Команды сравнения ЕРИ


=
——————————
— ——————————————————————ДД——цЖжЖж————————
Команда Назначение Процессор

ЕСОМ источник Сравнить вещественные числа 8087

ЕРСОМР источник Сравнить и вытолкнуть из стека ` 8087


ЕСОМРР. ‚ Сравнить и вытолкнуть из стека два числа 8087

Команды выполняют сравнение содержимого регистра УТ(0) с источником


(32- или 64-битная переменная или регистр ЭТ(п), если операнд не указан —
$Т(1)) и устанавливают флаги С0, С2 и СЗ в соответствии с табл. 14.

Таблица 14. Флаги сравнения ЕРУ

$Т(0) > источник


$Т(0) < источник

Несравнимы,

Если один из операндов - не-число или неподдерживаемое число, происходит |


исключение «недопустимая операция», а если оно замаскировано (флаг 1М = 1), .
все три флага устанавливаются в 1. После команд сравнения посредством ЕЗТЗ\
и ЗАНЕ можно перевести флаги СЗ, С2 и Сб в 2Е РЕи СЕ соответственно, затем |
все условные команды (]сс, СМО\сс, ЕСМО\сс, ЗЕТсс) используют результат |
сравнения. как после команды СМР. 4
Команда ЕСОМР после выполнения сравнения выталкивает из стека содер- '
жимое $Т(0) (помечает его как пустой и увеличивает ТОР на 1), а команда |
ЕСОМРР выталкивает из стека и 5Т(0), и $Т(1).
0—0
—————щ————————_————ы—ы————ШбШ&ШЩШЙ——ж—ж—
Команда Назначение Процессор
Ровинь
РОСОМ источник Сравнить вещественные числа без учета порядков 80387
РУСОМР источник Сравнить без учета порядков и вытолкнуть из стека 80387
РУСОМРР . _ Сравнить без учета порядков и вытолкнуть 80387
: из стека два числа , ‚
Числа с плавающей запятой ИГ: 75]
Эти команды аналогичны ЕСОМ/ЕСОМР/ЕСОМР
Р во всем, но в’'роли источ-
ника могут выступать только регистры 5Т(п), и если один
из операндов —- ОМАМ
(<тихое» не-число), флаги СЗ, С2, С0 устан
авливаются в единицы, однако исключе-
ние «недопустимая операция» не вызывается. Если
один из операндов — ЗМАМ или
неподдерживаемое число, эти команды ведут себя
так же, как и обычное сравнение.
Команда | Назначение | Процессор
НСОМ источник Сравнить целые числа
8087.
АСОМР источник Сравнить целые и вытолкнуть из стека
8087 |
Эти команды сравнивают содержимое регистра
5Т(0) и источника (16- или 32-
битная переменная), причем считается, что источник
содержит целое число. В ос-
тальном действие СОМ/Е!СОМР полностью
эквивалентно ЕСОМ/ЕСОМР -
Команда Назначение
Процессор
РСОМЕ источник Сравнить и установить ЕРЕАС$
Рб
ЕСОМИР источник Сравнить, установить ЕРЕАС$ и вытолкнуть
_ `Рб
РОСОМ! источник Сравнить без учета порядков и установить
ЕРРАС$ —Рб
РУСОМИР источник Сравнить без учета порядков, установить
ЕРРАС$ Рб
и вытолкнуть из стека

Выполняет сравнение регистра $Т(0) и источника


(регистр $Т(п)) и устанав-
ливает флаги регистра ЕЕГ.АС$ соответственно
табл. 15. | -
Таблица 15. Флаги после команд ЕКИСОМ

Условие
$Т(0) > источник
$Т(0) < источник
$Т(0} = источник
Несравнимы

Эти команды эквивалентны командам ЕГСО


М/ЕСОМРИ/Е ОСОМ/ЕОСОМР
вслед за которыми исполняются ЕЗМ$\/ АХи ЗАНЕ но они не изменяют содер-
жимого регистра АХ и выполняются быстрее.

Команда Назначение : Процессор


ЕТЗТ Проверить, не содержит ли 5Р(0) ноль
. 8087
Сравнивает содержимое $Т(0) с нулем и выставляет
флаги СЗ, С? и С0 анало-
гично другим командам сравнения.
Команда Назначение . Процессор
ЕХАМ Проанализировать содержимое $Т(0)
8087
‚ Устанавливает флаги СЗ, С2 и СО в зависимост
и от типа числа, находящегося
в 5Т(0), в соответствии с правилами, приведенны
ми в табл. 16.
761111111 Процессоры те! в реальном режиме
.{
Таблица 16. Результаты действия команды ЕХАМ

Нормальное конечное
число
Бесконечность
Ноль
Регистр пуст
Денормализованное
число

Флаг С1 устанавливается равным знаку числа в $Т(0) независимо от типа


числа (на самом деле он устанавливается, даже если регистр помечен как пустой).

2.4.7. Трансцендентные операции ЕРИУ


Команда Назначение Процессор

Ем Го Синус 80387
Вычисляст синус числа, находящегося в 5Т(0), и сохраняет результат в этом
же регистре. Операнд считается заданным в радианах и не может быть больше 28
или меньше —283 (можно воспользоваться ЕРВЕМ с делителем 27, если операнд
слишком велик). Если операнд выходит за эти пределы, флаг С2 устанавливается
в 1 и значение $Т(0) не изменяется.

Команда Назначение Процессор

ЕСО$ Косинус 80387

Вычисляет косинус числа, находящегося в 5'Г (0), и сохраняет результат в этом


же регистре. Операнд считается заданным в радианах и не может быть больше 283
или меньше —28 (так же, как и в случае синуса, можно воспользоваться ЕРКЕМ
с делителем 2л, если операнд слишком велик). Если операнд выходит за эти пре-
делы. флаг С2 устанавливается в 1 и значение 5Т(0) не изменяется.

Команда Назначение Процессор


ЕЯМСО$ Синус и косинус 80387

Вычисляет синус и косинус числа, находящегося в 5Т(0), помещает синус в 5Т(0),


‚ азатем косинус в стек (так что синус оказывается в 5Т(1), косинус - в 5Т(0), иТОР
уменьшается на 1). Операнд считается заданным в радианах и не может быть боль-
ше 283 или меньше —283. Если операнд выходит за эти пределы, флаг С2 устанав-
ливается в 1 и значение $Т(0) и стек не изменяются.
Числа с плавающей запятой — ПОС
Команда Назначение Процессор
ЕРТАМ , _ Тангенс 8087

Вычисляет тангенс числа, находящегося в регистре 5Т(0), заменяет его на


вычисленное значение и затем помещает 1 в стек, так что результат оказывается
в 5Т(1), 5Т(0) содержит 1, а ТОР уменьшается на единицу. Как и для остальных
тригонометрических команд, операнд считается заданным в радианах и не может
быть больше 283 или меньше —283. Если операнд выходит за эти пределы, флаг С2
устанавливается в 1 и значение 5Т(0) и стек не изменяются. Единица помещает-
ся в стек для того, чтобы можно было получить котангенс вызовом команды
ЕОТУК сразу после ЕРТАМ.

Команда _ Назначение _° ` Процессор

ЕРАТАМ Арктангенс 8087 —


Вычисляет арктангенс числа, получаемого при делении 5Т(1) на $Т(0), сохра-
няет результат в 5Т(1) и выталкивает 5Т(0) из стека (помечает $Т(0) как пустой
и увеличивает ТОР на 1). Результат всегда имеет тот же знак, что и $Т(1), и мень-
ше л по абсолютной величине. Смысл этой операции в том, что ЕРАТАМ вычис-
ляет угол между осью абсцисс и линией, проведенной из центра координат в точ-
ку $Г(1), $Т(0).
ЕРАТАМ может выполняться над любыми операндами (кроме не-чисел), давая
результаты для различных нулей и бесконечностей, определенные в соответствии
со стандартом ТЕЕЕ (как показано в табл. 17).

Таблица 17. Результаты работы команды ЕРАТАМ!

—Х

от +п до +1]2
+л/2

Команда | Назначение Процессор


Е2ХМ1 —.° Вычисление 2х-1 8087

Возводит 2 в степень, равную 5Т(0), и вычитает 1. Результат сохраняется


в 5'Г(0). Значение 5Т(0) должно лежать в пределах от —1 до +1, иначе результат
не определен.

`Е в этой таблице — конечное вещественное число.


78111111] Процессоры Н\е! в реальном режиме '
Команда Назначение Процессор
РУЕ2Х - Вычисление ух юд,„(х) 8087

Вычисляет 5Т(1) Х 108,($5Т(0)), помещает результат в ЗТ(1) и выталкивает .


5Т(0) из стека, так что после этой операции результат оказывается в $Т(0). Пер-
воначальное значение 5Т(0) должно быть неотрицательным. Если регистр $Т(0) `
содержал ноль, результат (если 2М = 1) будет равен бесконечности со знаком,
обратным 5Т(1).

Команда : Назначение | ‚ Процессор


РУЁ2ХР1 ` Вычисление у Хх ю9.(х+1) ‚ 8087

Вычисляет $Т(1) Х 10&,(5Т(0) + 1), помещает результат в 5Т(1) и выталкивает .


$Т(0) из стека, так что после этой операции результат оказывается в 5Т(0). Пер-
воначальное значение $Т(0) должно быть в пределах от —(1 — \2 /2) до (1+ \2/2),
в противном случае результат не определен. Команда ЕУТ.2ХР1 дает большую точ-
ность для 5Т(0), близких к нулю, чем ЕУТ.2Х для суммы того же $Т(0) и 1.

2.4.8. Константы ЕРИ


Команда ‘ Назначение Процессор
РЕО1 Поместить в стек 1,0 8087
РЕОХ . Поместить в стек +0,0 8087
- РЫОР] Поместить в стек число п 8087
РЕОЬ2Е ‚ _ Поместить в стек ю9„(е) 8087
РОТ Поместить в стек 109,(10) 8087
РЕРЕМ2 Поместить в стек п(2) 8087
РЕОЕС2 Поместить в стек 16(2} 8087

Все эти команды помещают в стек (то есть уменьшают ТОР на один и поме-
щают в 5Т(0)) соответствующую часто используемую константу. Начиная с со-
процессора 80387, все константы хранятся в более точном формате, чем 80-бит-
ный формат, используемый в регистрах данных, и при загрузке в стек происходит
округление в соответствии с полем КС.

2.4.9. Команды управления ЕРИ


—_—_—_ддж——оооод—д_до__о_„о
Команда Назначение - И Процессор

РМС$УТР Увеличить указатель вершины стека 8087


*

‚ ПолеТОР регистра состояния ЕР увеличивается на 1..Если ТОР было равно


семи, оно обнуляется. Эта команда не эквивалентна выталкиванию $Т(0) из сте-
‚ ка, потому что регистр данных, который назывался ЭТ(0) и стал 5Т(7), не поме-
чается как пустой.
Числа с плавающей запятой Тс | 79
Команда | Назначение Процессор
—_—_——_—_
д ни
РОЕСЗТР Уменьшить указатель вершины стека 8087.

Поле ТОР регистра состояния ЕРИ уменьшается на 1. Если ТОР было равно
нулю, оно устанавливается в 7. Содержимое регистров данных и ТУ” не изменяется.
———ы—ы»ы»5»„»»»—»—»—»—»—»—»—»—»—ы„3з_—»—ы—ы—ю—ы—ы=—_ю—=—==—ы=—.„.—ы—ЫЫы——ЫыЫ——Ы—Ы—Ы—
Ы—Ы—Ы—=—==—=ПЛыП=[2,—,.П—=ы—=——=...
Команда . Назначение Процессор
—_
Р е
РЕВЕЕ операнд | Освободить регистр данных 8087

Команда отмечает в регистре ТУ, что операнд (регистр данных $Т(п)) пустой.
Содержимое регистра и ТОР не изменяется.

Команда Назначение Процессор


АМТ Инициализировать ЕРУ 8087
РАМИМЕТ ^ Инициализировать ЕРУ без ожидания ‚8087

Команды ЕИМИТ и ЕМПМТ восстанавливают значения по умолчанию в регистрах


СК, 5В, ТУ\ а начиная с 80387 — ЕТР и ЕОР Управляющий регистр инициализируется
значением 037ЕЪ (округление к ближайшему, 64-битная точность, все исключе-
ния замаскированы). Регистр состояния обнуляется (ТОР = 0, флаги исключе-
ний не установлены). Регистры данных никак не изменяются, но все они помеча-
ются пустыми в регистре ТУ\У. Регистры ЕПР и Е,Р обнуляются. Команда “ПИТ,
в отличие от ЕМПМТ, проверяет наличие произошедших и необработанных ис-
ключений и обрабатывает.их до инициализации. Команда ЕПМТ полностью эк-
вивалентна (и на самом деле является) \УАТТ ЕМПМТ.

Команда Назначение Процессор


РСЪЕХ Обнулить флаги исключений 8087
ЕМСЬЕХ ` Обнулить флаги исключений без ожидания 8087

Команды обнуляют флаги исключений (РЕ, ОЕ, ОЕ, 7Е, РЕ, 1Е), а также фла-
ги Е$, 5Р и В в регистре состояния ЕРО. Команда ЕСГ.ЕХ, в отличие от ЕМСГЕХ,
проверяет наличие произошедших и необработанных исключений и обрабатыва-
ет их до выполнения. Команда ЕСГ.ЕХ полностью эквивалентна (и на самом деле
является) \/АГТ ЕМСГЕХ.
—_—_—___
диод
Команда Назначение , | Процессор
Е8ТС\У приемник Сохранить регистр СА | 8087
ЕМЗТСМ/ приемник Сохранить регистр СВ без ожидания 8087

Команды копируют содержимое СЁ в приемник (16-битная переменная). Ко-


манда Е5ТСУ, в отличие от ЕМ5ТСУ,, проверяет наличие ‘ироизошедших и нео-
бработанных исключений и обрабатывает их до выполнения. Команда ЕЗТС\
полностью эквивалентна (и на самом деле является) \МАТТ ЕМУТСМ
801111111 ‚ Процессоры И\е! в реальном режиме
Команда | Назначение Процессор

РЫОСМ/ источник Загрузить регистр СА 8087

Копирует содержимое источника (16-битная переменная) в регистр СК. Если


один или несколько флагов исключений установлены в регистре 5ЁВ и замаски-
рованы в СК, а команда ЕГОСУ\ эти маски удалила, исключения будут обрабо-
таны перед началом выполнения следующей команды ЕРУ (кроме команд без
ожидания). Чтобы этого не происходило, обычно перед ЕЕГОС\ выполняют
команду ЕСГЕХ.

Команда Назначение р Процессор

ЕЗТЕМУ приемник Сохранить вспомогательные регистры 8087


ЕМЗТЕМУ приемник Сохранить вспомогательные регистры без ожидания 8087

Сохраняет все вспомогательные регистры ЕРУ в приемник (14 или 28 байт


в памяти, в зависимости от разрядности операндов) и маскирует все исключения,
а также сохраняет содержимое регистров СК, $5В, Т\\, ЕТ, Е,Р и последнюю
‘команду в формате, зависящем от текущей разрядности операндов и адресов
(7 двойных слов для 32-битных операндов и 7 слов для 16-битных операндов).
Нервое слово (или младшая половина первого двойного слова в 32-битном случае)
всегда содержит СК, второе слово — ЗВ, третье слово — Т\, четвертое — ЕТР. Ис-
пользование последних трех слов варьируется в зависимости от текущей разряд-
ности адресации и операндов.
о 32-битные операнды и 16-битная адресация:
двойное слово 5: биты 10-0 старшего слова— код последней команды, млад-
шее слово — селектор для ЕТР;
двойное слово 6: ЕБР (32-битный);
двойное слово 7: младшее слово содержит селектор для ЕОР;
О 32-битные операнды и 16-битная адресация:
двойное слово 5: биты 31-16 — ЕТР, биты 10-0 - код последней команды;
двойное слово 6; биты 15-0 - ЕР;
двойное слово 7: биты 31-16 — ЕОР;
О 16-битные операнды и 32-битная адресация:
слово 5: селектор для ЕТР;
слово 6: ЕОР;
слово 7: селектор для ЕОР;
О 16-битные операнды и 16-битная адресация:
слово 5: биты 15-12-— биты 19-16 20-битного ЕТР, биты 10-0 — код послед-
ней команды;
слово 6: ЕОР;
слово.7: биты 15-12 - биты 19-16 20-битного ЕШР.
Из кода последней выполненной ЕРО-команды сохраняются первые два бай-
та без префиксов и без первых пяти бит, которые одинаковы для.всех команд ЕРО,
то есть всего 11 бит. Команда ЕЗТЕМУ, в отличие от ЕМ5ТЕМУ, проверяет наличие
Числа с плавающей запятой ИГ: |2
произошедших и необработанных исключений и обрабатывает их до выполнения.
Команда Е5ТЕМУ полностью эквивалентна (и на самом деле является) УМАГТ
ЕМЗТЕМУ.
Команда Назначение | Процессор
РЫОЕММУ источник . Загрузить вспомогательные регистры 8087

Команда загружает все вспомогательные регистры ЕРО (регистры СКВ, 5В, ТУ/,
ЕТР, ЕР) из источника (область памяти в 14 или 28 байт, в зависимости от раз-
рядности операндов), сохраненные ранее командой ЕЗТЕМУ /ЕМЗТЕМУ, Если в за-
гружаемом ЗУ установлены несколько (или один) флагов исключений, которые
одновременно не замаскированы флагами СК, то эти исключения будут выполне-
ны перед следующей командой ЕРЦ (кроме команд без ожидания).

Команда Назначение Процессор


РЗАМЕ приемник Сохранить состояние ЕРИ 8087
ЕМЗАУЕ приемник Сохранить состояние ЕРИ без ожидания 8087

Сохраняет состояние ЕРУ (регистры данных и вспомогательные регистры)


в приемник (область памяти размером 94 или 108 байт, в зависимости от разряд-
ности операндов) и инициализирует ЕРО аналогично командам ЕИТ/ЕМИМТ.
Команда ЕЗАУЕ, в отличие от ЕМЗАУЕ, проверяет наличие произошедших и нео-
бработанных исключений и обрабатывает ‘их до выполнения. Она полностью эк-
вивалентна (и на самом деле является) \УАТТ ЕМЗАУЕ. Эта команда обычно ис-
пользуется операционной системой при переключении задач или программами,
которые должны передавать вызываемым процедурам чистый ЕРОИ. .

Команда Назначение . Процессор


ЕХЗАУЕ приемник Быстрое сохранение состояния ЕРУ РИ

Команда ЕХЗАУЕ сохраняет текущее состояние ЕРУО, включая все регистры,


в приемник (512-байтную область памяти с адресом, кратным 16), не проверяя на
необработанные исключения, аналогично команде ЕМЗАУЕ. Кроме того, в`отли-
чие от ЕЗАУЕ/ЕМЗАУЕ, эта команда не переинициализирует ЕРУ после сохране-
ния состояния. Она несовместима с ГОАУЕ/ЕВ$ТОК.-

Команда Назначение . Процессор


РАЗТОН источник Восстановить состояние ЕРУ | 8087

Загружает состояние ЕРУ (вспомогательные регистры и регистры данных) из


источника (область в памяти размером в 94 или 108 байт, в зависимости от раз-
рядности операндов). ‘
Команда Назначение Процессор
ЕХВЗТОВН источник Быстрое восстановление состояния ЕРУ РН
8211 |111 Процессоры т4е! в реальном. режиме
Команда ЕХВЗТОК восстанавливает текущее состояние ЕРУ, включая все ре-
гистры, из источника (512-байтной области памяти с адресом, кратным 16), кото-
рый был заполнен командой ЕХЗАУЕ.

Команда Назначение Процессор


ЕЕТ$ЗМ/ приемник Сохранить регистр $А 80287
ЕМЗТЗМ/ приемник Сохранить регистр ЗВ без ожидания 80287

Сохраняет текущее значение регистра 5К в приемник (регистр АХ или 16-бит-


ная переменная). Команда ЕЗТ5\ АХ обычно используется после команд срав-
нения и ЕРКЕМ/ЕРВЕМ1/ЕХАМ, чтобы выполнять условные переходы.

Команда Назначение | Процессор


М/АГТ Ожидание готовности ЕРУ _ 8087
РАИАГТ

Процессор проверяет, присутствуют ли необработанные и незамаскированные


и р т их 2 мау можно указывать ван
Е оне К т
—-
прерии УАТ и Е\МАИТ- разные названия для одной и той же команды.

Команда Назначение Процессор


ЕМОР , Отсутствие операции . 8087

Эта команда занимает место и время, но не выполняет никакого действия. Уста-


ревшие команды ЕРИ - ЕЕМ] (разрешить исключения, 8087), ЕО[З1 (запретить
исключения, 8087) и ЕЗЕТРМ (80287) выполняются как ЕМОР всеми более стар-
шими процессорами.

2.5. Расширение 1А ММХ


Начиная с модификации процессора Репбит Р54С, все процессоры Пие! содер-
жат расширение ММХ, предназначенное для увеличения эффективности про-
грамм, работающих с большими потоками данных (обработка изображений, звука,
видео, синтез). то есть для всех тех случаев, когда нужно выполнить несложные
операции над массивами однотипных чисел. ММХ предоставляет несколько новых
типов данных, регистров и команд, позволяющих осуществлять арифметические
и логические операции нал несколькими числами одновременно.

2.5.1, Регистры ММХ


Расширение ММХ включает в себя восемь 64-битных регистров общего поль-
зования ММО - ММУ, показанных на рис. 14.
Физически никаких новых регистров с введением ММХ не появилось, ММО —
ММ? - это в точности мантиссы восьми регистров ЕРЦ, от КО до В7. При записи
числа в регистр ММХ оно оказывается в битах 63-0 соответствующего регистра
Расширение 1А ММХ .
ЕРО, а экспонента (биты 78-64) и ее знаковый бит (бит
79) заполняются единицами. Запись числа в регистр :
ЕРО также приводит к изменению соответствующего ре-
гистра ММХ. Любая команда ММХ, кроме ЕММ5, при--
водит к тому, что поле ТОР регистра ЗВ и весь регистр
ТУ! в ЕРО обнуляются. Команда ЕММ$ заполняет ре-
гистр ТУ/ единицами. Таким. образом, нельзя одновре-
менно пользоваться командами для работы с числами
с плавающей запятойи командами ММХ, а если это
необходимо — следует применять команды ЕЗАУЕ/
ЕВУТОЕ каждый раз перед переходом от ЕРО к ММХ 63 о
и обратно (эти команды сохраняют состояние регистров Рис. 14. Регистры ММХ
ММХ точно так же, каки ЕРО).

2.5.2. Типы данных ММХ


‚ ММХ использует четыре новых типа данных:
О учетверенное слово — простое 64-битное число;
О упакованные двойные слова + два 32-битных двойных слова, упакованные
в 64-битный тип данных. Двойное слово 1 занимает биты 63-32, и двойное
слово 0 - биты 31-0;
О упакованные слова— четыре 16-битных слова, упакованные в 64-битный тип
данных. Слово 3 занимает биты 63—48, слово 0 - биты 15-0;
ОСупакованные байты - восемь байт, упакованных в 64-битный тип данных.
Байт 7 занимает биты 63—56, байт 0 -— биты 7-0. |
Команды ММХ перемещают упакованные данные в память или в обычные
регистры как целое, но выполняют арифметические и логические операции над
каждым элементом по отдельности.
Арифметические операции в ММХ могут использовать специальный способ
обработки переполнений и антипереполнений— насыщение. Если результат опе-
рации больше, чем максимальное значение для его типа данных (+127 для байта
со знаком), то результат подразумевают равным этому максимальному значению.
Если он меньше минимального значения — соответственно его считают равным
минимально допустимому значению. Например, при операциях с цветом насыще-
ние позволяет ему превращаться в чисто белый при переполнении и в чисто чер-
ный при антипереполнении; в ТО время как обычная арифметика привела бы к не-
желательной инверсии цвета.

2.5.3. Команды пересылки данных ММХ


Команда _` Назначение Процессор
МОУО приемник, источник Пересылка двойных слов ммх

Команда копирует двойное слово из источника (регистр ММХ, обычный ре-


гистр или переменная) в приемник (регистр ММХ, обычный регистр или пере-
менная, но один из операндов обязательно должен быть регистром ММХ). Если
841111 || Процессоры име! в реальном режиме
приемник - регистр ММХ, двойное слово записывается в его младшую половину
(биты 31-0), а старшая заполняется нулями. Если источник - регистр ММХ,
в приемник записывается младшее двойное слово этого регистра.

Команда Назначение Процессор

МоОУ\Уа приемник‚источник = Пересылка учетверенных слов мМхХ

Копирует учетверенное слово (64 бита) из источника (регистр ММХ или пе-
ременная) в приемник: (регистр ММХ или переменная, оба операнда не могут
быть переменными).

2.5.4. Команды преобразования типов ММХ


Команда | Назначение Процессор
РАСК$З\УВ приемник, источник Упаковка со знаковым насыщением ММХ
РАСК$$О\М приемник, источник

Команды упаковывают и насыщает слова со знаком в байты (РАСК$З\/В) или.


двойные слова со знаком в слова (РАСК$$ ОУ”). Команда РАСК$$\/В копирует
четыре слова (со знаком), находящиеся в приемнике (регистр ММХ), в 4 младших `
байта (со знаком) приемника и копирует четыре слова (со знаком) из источника
(регистр ММХ или переменная) в старшие четыре байта (со знаком) приемника.
Если значение какого-нибудь слова больше +127 (7ЕВ) или меньше -128 (80),
в байты помещаются числа +127 и -128 соответственно. Команда РАСК$$ ОУ
аналогично копирует два двойных слова из приемника в два младших слова при-
‚емника и два двойных слова из источника в два старших слова приемника. Если
значение какого-нибудь двойного слова больше +32 767 (7ЕЕЕЬ) или меньше
-32 768 (80001), в слова помещаются числа +32 767 и -32 768 соответственно.

Команда Назначение Процессор


РАСКИЗМВ приемник, источник Упаковка с беззнаковым насыщением ` `ММХ

Копирует четыре слова (со знаком), находящиеся в приемнике (регистр


ММХ), в 4 младших байта (без знака) приемника и копирует четыре слова (со
знаком) из источника (регистр ММХ или переменная) в старшие четыре байта
(без знака) приемника. Если значение какого-нибудь слова больше 255 (ОЕЕБ)
или меньше 0 (001), в байты помещаются числа 255 и 0 соответственно.

Команда Назначение | Процессор

РУМРСКНВМУ! приемник, источник Распаковка и объединение ммх


старших элементов
РУМРСКНУГО приемник, источник Распаковка и объединение ‚ММХ
старших элементов .
РУМРСКНО@ приемник, источник Распаковка и объединение ммх
старших элементов
Расширение 1А ММХ | с 85
РАМРСКНВУ/

Рис. 15. „Действие команды РУМРСКНВИ/

Команды распаковывают старшие элементы источника (регистр ммх или пе-


ременная) и приемника (регистр ММХ) и записывают их в приемник через один
(см. рис. 15).
Команда РОМРСКНВУ/ объединяет по 4 старших байта источника и приемника,
команда РОМРСКНУГ - по 2 старших слова, а команда РОМРСКНРО копирует
в приемник по одному старшему двойному слову из источника и приемника.
Если источник содержит нули, эти команды фактически переводят старшую
половину приемника из одного формата данных в другой; дополняя увеличивае-
мые элементы нулями. РОМРСКНВУ переводит упакованные байты в упакован-
ные слова, РОМРСКНУ’/О - слова в двойные слова, а РОМРСКНОО - един-
ственное старшее двойное слово приемника в учетверенное.
Команда | . Назначение Процессор
РОМРСКЕВУ/ приемник,источник . Распаковка и объединение ММХ
| младших элементов
РУМРСКЕМЮО приемник, источник Распаковка и объединение ММХ.
| младших элементов
РУМРСКЕО@ приемник‚источник Распаковка и объединение ММхХ
младших элементов

Команды распаковывают младшие элементы источника (регистр ММХ или


переменная) и приемника (регистр ММХ) и записывают их в приемник через
один аналогично предыдущим командам. Команда РОМРСКТ.ВУ/ объединяет по
4 младших байта источника и приемника, команда РОМРСКГУ объединяет по
2 младших слова, а команда РОМРСКТОО копирует в приемник по одному
младшему двойному слову из источника и приемника. Если источник содержит
только нули, эти команды, аналогично РОМРСКН*, фактически переводят млад-
шую половину приемника из одного формата данных в другой, дополняя увели-
чиваемые элементы нулями.
2.5.5. Арифметические операции ММХ
Команда Назначение Процессор
РАООВ приемник, источник "Сложение ммх
РАООМ/ приемник, источник Сложение ммх
РАБОВ приемник, источник Сложение ммх
86| |||] Процессоры Не! в реальном режиме
Команды выполняют сложение отдельных элементов данных (байтов — для
РАОБВ, слов - для РАООУ,, двойных слов — для РАОО) источника (регистр
ММХ или переменная) и соответствующих элементов приемника (регистр
ММХ). Если при сложении возникает перенос, он не влияет ни на следующие
элементы, ни на флаг переноса, а просто игнорируется (так что, например, для
РАООВ 255 + 1 = 0, если это числа без знака, или —128 + -1 = +127, если со зна-
ком).

Команда | Назначение Процессор

РАООЗВ приемник, источник Сложение с насыщением | ммх


РАОБОЗМ/ приемник, источник Сложение с насыщением мМХ

Команды выполняют сложение отдельных элементов данных (байтов — для


РАБОЗВ и слов - для РАРОЗУ/) источника (регистр ММХ или переменная)
и соответствующих элементов приемника (регистр ММХ). Если при сложении
сумма выходит за пределы байта со знаком для РАООЗВ (больше +127 или
меньше —128) или слова со знаком для РАРО$\\ (больше +32 767 или меньше
—32 768), в качестве результата используется соответствующее максимальное или
минимальное число; так что, например, для РАООЗВ -—128 + -—1 = -128.

Команда Назначение Процессор

РАООЦЗВ приемник, источник Беззнаковое сложение ммх


| . с насыщением
РАРОЦ$\У/ приемник, источник Беззнаковое сложение ММХ -
с насыщением

Команды выполняют сложение отдельных элементов данных (байтов — для


РАОРОЗВ и слов - для РАРОИЗУ/) источника (регистр ММХ или переменная)
и соответствующих элементов приемника (регистр ММХ). Если при сложении
сумма выходит за пределы байта без знака для РАОРОЗВ (больше 255 или мень-
ше 0) или слова без знака для РАООЧЗ\ (больше 65 535 или меньше 0), то в ка-
честве результата используется соответствующее максимальное или минимальное
число; так что, например, для РАРООЗВ 255 + 1 = 255.
Команда Назначение Процессор
РЗИВВ приемник, источник Вычитание ммх
РЗУВМУ/ приемник, источник Вычитание ММХ
Р$ЗУВО приемник, источник Вычитание | ММх

Команды выполняют вычитание отдельных элементов данных (байтов - для


РУОВВ, слов — для РУОВУ, двойных слов — для РЗОВО) источника (регистр
ММХ или переменная) и соответствующих элементов приемника (регистр
ММХ). Если при вычитании возникает заем, он игнорируется (так чтонапример,
для РЗОВВ -128 - 1 = +127 — применительно к числам со знаком или 0 1 = 255 -—
применительно к числам без знака).
Расширение 1А ММХ = 87
Команда Назначение Процессор
РЗУВЗВ приемник, источник Вычитание с насыщением ` ММХ .
РЗУВЗ\М приемник, источник Вычитание с насыщением ммх

Команды выполняют вычитание отдельных элементов данных (байтов — для


РУОВЗВ и слов — для РЭОВ$ У) источника (регистр ММХ или переменная) и соот-
ветствующих элементов приемника (регистр ММХ). Если при вычитании раз-
ность выходит за пределы байта или слова со знаком, в качестве результата ис-
пользуется соответствующее максимальное или минимальное число; так что,
например, для РЗОВЗВ -128 - 1 = 128.
Команда Назначение Процессор
РЗИВИЗВ приемник, источник Беззнаковое вычитание с насыщением мМхХ
РЗУВИЗМ приемник, источник . Беззнаковое вычитание с насыщением — ММХ

Команды выполняют вычитание отдельных элементов данных (байтов — для


РУОВИЗВ и слов — для РЗОВИЗУ)) источника (регистр ММХ или переменная)
и соответствующих элементов приемника (регистр ММХ). Если при вычитании
разность выходит за пределы байта или слова без знака, в качестве результата
используется соответствующее максимальное или минимальное число; так что,
например, для РЭОВОЗВ 0 -1=0..
Команда . Назначение | Процессор
РМУЕНУ/ приемник, источник Старшее умножение ммх

Команда умножает каждое из четырех слов со знаком из источника (регистр


ММХ или переменная) на соответствующее слово со знаком из приемника (ре-
гистр ММХ). Старшее слово каждого из результатов записывается в соответству-
ющую позицию приемника.
Команда . Назначение Процессор
РМИЫМ/ приемник, источник | Младшее умножение ММХ

Умножает каждое из четырех слов со знаком из источника (регистр ММХ или


переменная) на соответствующее слово со знаком из приемника (регистр ММХ).
Младшее слово каждого из результатов записывается в соответствующую пози-
цию приемника.
Команда Назначение Процессор
РМАООМГО приемник, источник Умножение и сложение | ммх

Умножает каждое из четырех слов со знаком из источника (регистр ММХ или


переменная) на соответствующее слово со знаком из приемника (регистр ММХ).
Произведения двух старших. пар слов складываются между собой, н их сумма за-
писывается в старшее двойное слово приемника. Сумма произведений двух млал-
ших пар слов записывается в младшее двойное слово.
88111111 Процессоры те! в реальном режиме
2.5.6. Команды сравнения ММХ
Команда Назначение Процессор
РСМРЕОСВ приемник, источник Проверка на равенство | ММХ
РСМРЕОСМ! приемник, источник Проверка на равенство ммх
РСМРЕОСР приемник, источник Проверка на равенство ммх

Команды сравнивают индивидуальные элементы данных (байты - в случае


РСМРЕСЬВ, слова - в случае РСМРЕОХ\, двойные слова - в случае РСМРЕОО)
источника (регистр ММХ или переменная) с элементами приемника (регистр
ММХ). Если пара сравниваемых элементов равна, соответствующий элемент при-
емника заполняется единицами, если они не равны — элемент заполняется нулями.
Команда Назначение | Процессор
РСМРСТВ приемник, источник | Сравнение ММХ
РСМРЕТМ! приемник, источник = Сравнение ммх
РСМРСТО приемник, источник _ | Сравнение мМхХ

Команды сравнивают индивидуальные элементы данных (байты - в случае


РСМРСТЬ, слова - в случае РСМРСТУ,, двойные слова — в случае РСМРСТО)
источника (регистр ММХ или переменная) с элементами приемника`(регистр
ММХ). Если элемент приемника больше, чем соответствующий элемент источ-
ника, все биты в этом элементе приемника устанавливаются в единицы. Если эле-
мент приемника меньше или равен элементу источника, он обнуляется.
,

2.5.7. Логические операции ММХ


Команда Назначение Процессор
РАМО приемник, источник Логическое И ммх

Команда выполняет побитовое «логическое И» над источником (регистр ММХ


или переменная) и приемником (регистр ММХ) и сохраняет результат в приемнике.
Каждый бит результата устанавливается в 1, если соответствующие биты в обо-
их операндах равны 1, в противном случае бит сбрасывается в 0.
Команда Назначение Процессор
РАМОМ приемник, источник Логическое НЕ-И (штрих Шеффера) ммМхХ

Выполняет побитовое «логическое НЕ» (то есть инверсию битов) над прием-
ником (регистр ММХ) и затем побитовое «логическое И» над приемником и ис-
точником (регистр ММХ или переменная). Результат сохраняется в приемнике.
Каждый бит результата устанавливается в 1. только если соответствующий бит.
источника был равен 1, а приемника - 0. иначе бит сбрасывается в 0. Эта логичес-
кая операция называется также штрихом Шеффера.

Команда Назначение Процессор


РОВ приемник, источник Логическое ИЛИ . МХ
Расширение 1А ММХ 1 О О МО ОИ ПОЕССЕЛ
Выполняет побитовое «логическое ИЛИ» над источником (регистр ММХ или
переменная) и приемником (регистр ММХ) и сохраняет результат в приемнике.
Каждый бит результата сбрасывается в 0, если соответствующие биты в обоих
операндах равны 0, в противном случае бит устанавливается в 1.
Команда Назначение < Процессор

РХОВ приемник, источник Логическое исключающее ИЛИ ммх

Выполняет побитовое «логическое исключающее ИЛИ» над источником (ре-


гистр ММХ или переменная) и приемником (регистр ММХ) и сохраняет резуль-
тат в приемнике. Каждый бит результата устанавливается в 1, если соответствую-
щие биты в обоих операндах равны, иначе бит сбрасывается в 0.

2.5.8. Сдвиговые операции ММХ


Команда Назначение Процессор

РМ приемник, источник Логический сдвиг влево ммх


Р$НЕО приемник, источник Логический сдвиг влево ммх
РЗНЯ приемник, источник Логический сдвиг влево ммх

Команды сдвигают влево биты в каждом элементе (в словах — для РЗ. РУ,
в двойных словах — для Р51.Т), во всем регистре — для РЗЕТО) приемника (ре-
гистр ММХ) на число битов, указанное в источнике (8-битное число, регистр
ММХ или переменная). При сдвиге младшие биты заполняются нулями, так что,
например, команды
р$1 м пупо, 15
р3119 тт, 31
р$119 то, 63

обнуляют регистр ММО.


Команда Назначение Процессор
РЗВИЕМ/ приемник, источник | Логический сдвиг вправо ммх
Р$ВЬО приемник, источник Логический сдвиг вправо ммх
РУВЬО приемник, источник Логический сдвиг вправо | мММхХ

Команды сдвигают вправо биты в каждом элементе (в словах —- для Р5КГ\,


в двойных словах —- для РУВГО, во всем регистре —- для РЭВТО) приемника (ре-
гистр ММХ) на число битов, указанное в источнике (8-битное число, регистр
ММХ или переменная). При сдвиге старшие биты заполняются нулями.

Команда Назначение Процессор

Р$НАМ/ приемник, источник Арифметический сдвиг вправо ммх


РЗНАО приемник, источник Арифметический сдвиг вправо ммх

Команды сдвигают вправо биты в каждом элементе (в словах — для РЭКАХ


и в двойных словах —- для РЗВАО) приемника (регистр ММХ) на число битов,
90| |||] Процессоры 1(е! в реальном режиме -
указанное в источнике (8-битное число, регистр ММХ или переменная). При
сдвиге самый старший (знаковый) бит используется для занолнения пустеющих
старших битов, так что фактически происходит знаковое деление на 2. в степени,
равной содержимому источника.

2.5.9. Команды упратТения состоянием ММХ


Команда
О|О Назначение
ооо О ООО
. Процессор
нивы
ЕММ$ Освободить регистры ММХ ммх

Если выполнялись какие-нибудь команды ММХ (кроме ЕММ5), все регист-


ры ЕРУО помечаются как занятые (в регистре ТУ). Команда ЕММ$ помечает все
регистры ЕРИ как пустые для того, чтобы после завершения работы с ММХ мож-
но было передать управление процедуре, использующей ЕРО.

2.5.10. Расширение АМБ 30


Процессоры АМО, начиная с АМР Кб ЗО, поддерживают дополнительное рас- |
ширение набора команд ММХ. В АМРЬ 3Р вводится новый тип данных - упако-
ванные 32-битные вещественные числа, определяются новые команды (начинаю-
щиеся с РР) и несколько дополнительных команд для работы с обычными
ММХ-типами данных: |
о Р/2ЕД приемникисточник — преобразовывает упакованные 32-битные целые
со знаком (двойные слова) в упакованные вещественные числа; .
о РЕ? приемник,источник — преобразовывает упакованные вещественные
в упакованные целые числа со знаком (преобразование с насыщением);
о РАУСОЗВ приемникисточник — вычисляет средние арифметические для упа-
кованных 8-битных целых чисел без знака;
ОРМОЕНКУ/ приемник‚источник — перемножает упакованные 16-битные це-
лые со знаком и сохраняет результаты как 16-битные целые в приемнике
(при переполнениях выполняется насыщение);
О РЕАСС приемник‚источник — сумма вещественных чисел в приемнике поме-
щается в младшую половину приемника, сумма вещественных чисел из ис-
точника помещается в старшую половину приемника;
о РЕАОО приемник, источник — сложение упакованных вещественных чисел;
О РЕЗОВ приемник‚источник — вычитание упакованных вещественных чисел;
О РЕ5ОВК приемник‚источник — обратное вычитание (приемник из источни-
ка) упакованных вещественных чисел;
о РЕМИЕ приемникисточник - умножение упакованных вещественных чисел.
Набор команд для быстрого вычисления по итерационным формулам:
Быстрое деление:
хи = х(2 - Бх,)
х, = РЕВСР(Ь)
х, = РЕВСРГТИЬх,)
Расширение $5Е | НА ПОИСК
х, = РЕ ВСРТ2(х,х,)
х1= РЕМОЦЬх,)
Быстрое вычисление квадратного
корня:
Х„1 = х(3 — Бх2)/2
х, -РЕ В5ОВТ(Ь)
х, -РЕ МУЦхьх,)
х, = РЕВЗОТТ(Ь,х,)
х. = РЕ ВСРИТ2(х,х,)
х„, = РЕМОТЬ,х,)
ОРЕСМРЕО приемник. источник —
проверка равенства для упакован
ственных чисел (полностью анал ных веще-
огично РСМРЕО\;
ОРЕСМРСЕ приемник, источник
— сравнение упакованных веществе
сел: если число в приемнике боль нных чи-
ше или равно числу в источнике,
биты устанавливаются в 1; все его
ОРЕСМРСТ приемник.источник —
сравнение упакованных веществе
если число в приемнике больше числ нных чисел:
а в источнике, все его биты устанавл
ваются в 1; и-
ОРЕМАХ приемник. источник —
сохраняет в приемнике максималь
дой пары сравниваемых веществен ное из каж-
ных чисел;
ОРЕМИМ приемник. источник — |
сохраняет в приемнике минима
дой пары сравниваемых веществен льн ое из каж-
ных чисел;
ОРЕММ$ - более быстрая версия
команды ЕММ$;
О РАЕРЕТСН источник — заполняе
т строку кэша [.1 из памяти по
занному источником; адресу, ука-
О РАЕЕЕТСНУ источник — заполняет строку кэша
занному источником, и помечает [.1 из памяти по адресу, ука-
как модифицированную.

2.6. Расширение $5Е


2.6.1. Регистры $5Е
Со времени процессора Репцит Ш
(Капа!) появилось новое расширен
(Згеатшя $ПМО Ежепзоп$ — пото ие $5Е
ковые $1 МО-расширения), где $1М
Гл5гасвоп — МшарЕ Паа) — общ О (Зшае
ий для 55Е и ММХ подход к обра
ботке боль-

В отличие от ММХ, это расширен


ие не использует уже существую
сы процессора, а вводит 8 новы щие ресур-
х независимых 128-битных реги
ХММО, ХММ1, ХММ2, стро в данных:
ХММЗ, ХММА, ХММ5, ХММби
решаются проблемы технологии ХММУ7. Таким образом
ММХ — не требуется команд типа
переключения режимов и можно ЕММ$ для
пользоваться другими расширениями
с 5ЗЕ. , работая
9211 || |1 Процессоры И\е! в реальном режиме
Кроме восьми регистров данных, вводится дополнительный 32-битный ре-
гистр управления/состояния МХСЗК, который используется для маскирования
исключений, выбора режимов и определения состояния флагов:
бит 0: произошло исключение 1Е
бит 1: произошло исключение РЕ
бит 2: произошло исключение 7Е
бит 3: произошло исключение ОЕ
бит 4: произошло исключение (Е
бит 5: произошло исключение РЕ
бит 6: зарезервирован (всегда 0)
бит 7: [М - маска исключения ТЕ
бит 8: РМ -— маска исключения ОЕ
бит 9: (М - маска исключения 2Е
бит 10: ОМ - маска исключения ОЕ
бит 11: ЧМ - маска исключения ОЕ
бит 12: РМ - маска исключения РЕ’
биты 14—13: ВС - управление округлением
бит 15: ЕЁ, - режим сброса в ноль (Виз -{0-гего)
биты 31-16: зарезервированы (всегда 0)
Все маскирующие биты по умолчанию (при включении процессора) устанав-
ливаются в 1, так что никакие исключения не обрабатываются.
Поле ВС определяет режим округления: 00 - к ближайшему числу, 01 - кот-
рицательной бесконечности, 10 — к положительной бесконечности, 11 — к нулю.
По умолчанию устанавливается в режим округления к ближайшему числу.
Бит Е7, включает режим сброса в ноль (по умолчанию выключен). В этом ре-
жиме команды 55Е не превращают слишком маленькое число с плавающей запя-
той в денормализованное (как этого требует стандарт ТЕЕЕ), а возвращают ноль.
Знак нуля соответствует знаку получившегося бы денормализованного числа,
и. кроме того, устанавливаются флаги РЕ и ОЕ.

2.6.2. Типы данных $55Е


Основной тип данных, с которым работают команды 5ЗЕ, — упакованные чис-
ла с нлавающей запятой одинарной точности. В одном 128-битном регистре раз-
мещаются сразу четыре таких числа - в битах 127-96 (число 3), 95-64 (число 2),
63-32 (число 1) и 31-0 (число 0). Это стандартные 32-битные числа с плавающей
запятой, используемые числовым сопроцессором. Целочисленные команды 55Е
могут работать с упакованными байтами, словами или двойными словами. Одна-
ко эти команды оперируют данными, находящимися в регистрах ММХ.

2.6.3. Команды $5$Е


Все команды 5$Е доступны из любых режимов процессора — реального, защи-
щенного и режима \86.
Расширение 55Е т 33
Команды пересылки данных
Команда Назначение . Процессор

МОМАР$ приемник, источник . Переслать выравненные упакованные числа РИ

Копирует 128 бит из источника в приемник. Каждый из аргументов может быть


либо регистром $5Е, либо переменной в памяти, но пересылки типа память-память
запрещены. Если адрес переменной некратен 16 байтам (128 битам), вызывается
исключение #СР.

Команда Назначение Процессор

МОМУР$ приемник, источник Переслать невыравненные упакованные числа _РШ

Копирует 128 бит из источника в приемник. Каждый из аргументов может быть


либо регистром 5ЗЕ, либо переменной в памяти, но пересылки типа память-память
запрещены. В тех случаях, когда легко достичь выравнивания всех данных по адре-
сам, кратным 16 байт, рекомендуется пользоваться командой МОУАРЗ, так как она

Команда Назначение Процессор


МОУНР$ приемник, источник Переслать старшие упакованные числа РИ

Копирует старшие 64 бита из источника в приемник. Младшие 64 бита прием-


ника не изменяются. Каждый из аргументов может быть либо регистром 55Е,
либо переменной в памяти, но пересылки типа память-память запрещены.

Команда Назначение Процессор

МО\МЕР$ приемник, источник Переслать младшие упакованные числа РИ

Копирует младшие 64 бита из источника в приемник. Старшие 64 бита прием-


ника не изменяются. Один из аргументов должен быть регистром 55Е, другой —
переменной в памяти. ‘

Команда Назначение , Процессор

МОУНЕР$ приемник, источник Переслать старшие упакованные числа РИ


‚ - в младшие

Копирует старшие 64 бита источника в младшие 64 бита приемника. Старшие


64 бита приемника не изменяются. И приемником, и источником могут быть толь-
ко регистры З5Е.

Команда Назначение Процессор


МОУЕНР$ приемник‚источник Переслать младшие упакованные числа РИ
в старшие
941 | ||] Процессоры Не! в реальном режиме
Копирует младшие 64 бита источника в старшие 64 бита приемника. Младшие
64 бита приемника не изменяются. И приемником, и источником могут быть толь-
ко регистры $5Е.

Команда | Назначение , Процессор

МОУМ$КР$ приемник, источник Переслать маску в переменную РИ

В приемник (32-битный регистр центрального процессора) записывается 4-бит-


ная маска, отвечающая знакам четырех вещественных чисел, находящихся в ис-
точнике (128-битный регистр 55Е). Фактически бит 0 приемника устанавливает-
ся равным биту 31 источника, бит 1 — биту 63, бит 2 - биту 95, бит 3 — биту 127,
а биты 4-31 приемника обнуляются.

Команда Назначение | Процессор

МО\У$$ приемник, источник Переслать одно вещественное число РИ

Копирует младшие 64 бита из источника в приемник. Если приемник - ре-


гистр, его старшие 96 бит обнуляются. Если приемник — переменная в памяти,
старшие 96 бит не изменяются. Каждый из аргументов может быть либо. регистром
З5Е, либо переменной в памяти, но пересылки типа память-память запрещены.
Арифметические команды
Команда Назначение Процессор
АООР$ приемник, источник . Сложение упакованных вещественных чисел - РН

Выполняет параллельное сложение четырех пар чисел с плавающей запятой,


находящихся в источнике (переменная или регистр $5Е) и приемнике (регистр
5ЪЕ). Результат записывается в приемник.

Команда ‚ Назначение Процессор


А0О$$ приемник, источник Сложение одного вещественного числа РН

Выполняет сложение нулевых (занимающих биты 31-0) чисел с плавающей за-


пятой в источнике (переменная или регистр 55Е) и приемнике (регистр $$Е). Ре-
зультат записывается в биты 31-0 приемника, биты 127-32 остаются без изменений.
Команда Назначение Процессор
ЗИВР$ приемник, источник Вычитание упакованных вещественных чисел РАЙ

Выполняет параллельное вычитание чисел с плавающей запятой, находящих-


ся в источнике (переменная или регистр 55Е), из чисел, находящихся в приемни-
ке (регистр 55Е). Результат записывается в приемник.

Команда | Назначение Процессор


$18В$$ приемник, источник Вычитание одного вещественного числа РИ
Расширение Е +
И Е
Выполняет вычитание нулевого (занимающего биты 31-0) числа с плавающей
запятой в источнике (переменная или регистр 55Е) из числа, находящегося в при-
емнике (регистр 55Е). Результат записывается в биты 31-0 приемника, биты 127-
32 остаются без изменений.
Команда Назначение . Процессор
д ЩСе
МЧЕР$ приемник, источник Умножение упакованных вещественных чисел ‘РИ

Выполняет параллельное умножение четырех пар чисел с плавающей запятой,


находящихся в источнике (переменная или регистр 35Е) и приемнике (регистр
ЗЕ). Результат записывается в приемник.
—_
Команда Назначение : Процессор -
д
МУЕ$$ приемник, источник Умножение одного вещественного числа. РИ

Выполняет умножение нулевых (занимающих биты 31-0) чисел с плавающей


запятой в источнике (переменная или регистр 55Е) и приемнике (регистр $$Е). Ре-
зультат записывается в биты 31—0 приемника, биты 127-32 остаются без изменений.
д
Команда Назначение Процессор
Ди
ОМР$ приемник, источник Деление упакованных вещественных чисел РН

Выполняет параллельное деление четырех пар чисел с плавающей запятой,


находящихся в приемнике (регистр $5Е), на числа, находящиеся в источнике (пе-
ременная или регистр $5Е). Результат записывается в приемник.
д
Команда Назначение Процессор
Ее е.
0№5$ приемник, источник Деление одного вещественного числа РИ

Выполняет деление нулевого (занимающего биты 31-0) числа с плавающей


запятой в приемнике (регистр 55Е) на нулевое число, находящееся в источнике
(переменная или регистр 5$Е). Результат записывается в биты 31-0 приемника,
биты 127- 32 остаются без`изменений.
Команда Назначение Процессор
ЗОНТР5$ приемник, источник Корень из упакованных вещественных чисел РИ

Определяет значение квадратных корней от каждого из четырех чисел с пла-


вающей запятой, находящихся в источнике (регистр $5Е или переменная), и за-
писывает их в приемник (регистр 55Е).

Команда Назначение Процессор


ЗО@АТ$5$ приемник, источник Корень из одного вещественного числа РИ!

Определяет значение квадратного корня из нулевого (занимающего биты 31—0)


числа с плавающей запятой из источника (регистр 55Е или переменная) и запи-
сывает результат в биты 31-0 приемника (регистр 55Е).
96 |111] Процессоры Ит(е! в реальном режиме
Команда . Назначение Процессор
АСРР$ приемник,источник Обратная величина для упакованных чисел ° РН

Выполняет деление единицы на каждое из четырех чисел с плавающей запя-


той, находящихся в источнике (регистр 5$Е или переменная), и записывает ре-
зультаты в приемник (регистр $5Е). Максимальное значение ошибки - 1,5Ж2-!2.

Команда Назначение Процессор


ЯСР$$ приемник, источник ‚ Обратная величина для одного числа ` РИ

Выполняет деление единицы на нулевое (занимающее биты 31-0) число с плава-


ющей запятой из источника (регистр 5$Е или переменная) и записывает результат
в биты 31-0 приемника (регистр $5Е). Максимальное значение ошибки - 1,5Х2-1.
А
Команда Назначение Процессор
АЗОНТР$ приемник‚источник. Обратный корень из упакованных чисел РИ

Определяет обратные величины: от квадратных корней (1 /з4г(()) каждого из


четырех чисел с плавающей запятой, находящихся в источнике (регистр 55Е или
переменная), и записывает их в приемник (регистр $$Е). Максимальное значе-
ние ошибки - 1,5Х2-1. .

Команда Назначение Процессор


ВЗОЛАТ$$ приемник‚,источник — Обратный корень из одного числа РИ

Определяет обратную величину от квадратного корня (1/загЕ()) нулевого чис-


ла (занимающего биты 31-0) числа с плавающей занятой из источника (регистр
5ЗЕ или переменная) и записывает результат в биты 31-0 приемника (регистр
$5Е). Максимальное значение ошибки - 1,5Х2-!2.
д
ддодооо—о—_—о—»Ъ»ЪъЬь»»_»»„»ъ»_»„
дд —
Команда Назначение Процессор
МАХР5 приемник, источник Максимум для упакованных вещественных чисел РИ!

Определяет максимальные числа с плавающей запятой в каждой из четырех


пар чисел, находящихся в источнике (переменная или регистр 55Е) и приемнике
(регистр 55Е). Результат записывается в приемник. Если источник или прием-
ник содержит не-число (ЗМАМ), оно возвращается в приемник без изменений.
При сравнении двух нулей возвращается нуль из источника. Если не-Число срав-
нивается с другим не-числом, то возвращается не-число из приемника.

Команда Назначение Процессор


МАХ$5 приемник, источник Максимум для одной пары вещественных чисел РИ

Определяет максимальные числа с плавающей запятой в нулевой паре чисел


(биты 31-0), находящихся в источнике (переменная или регистр 55Е) и прием-
нике (регистр $$Е). Результат записывается в приемник. Биты 127-32 приемника
Расширение $5$Е ` Е)
не изменяются. Если источник или приемник содержит не-число (ЗМАМ), оно
возвращается в приемник без изменений. При сравнении двух нулей возвращает- .<.
ся нуль из источника. Если не-число сравнивается с другим не-числом, возвра-
щается не-число из приемника.

Команда Назначение Процессор


д РЕ
МИМР$ приемник, источник Минимум для упакованных РИ!
вещественных чисел

Определяет минимальные числа с плавающей запятой в каждой из четырех


пар чисел, находящихся в источнике (переменная или регистр $5Е) и приемнике
(регистр 55Е). Результат записывается в приемник. Если источник или прием-
ник включает не-число (МАМ), возвращается содержимое другого не-числа из
аргументов. При сравнении двух нулей возвращается нуль из источника. Если не-
число сравнивается с. другим не-числом, возвращается не-число из источника.
д
Команда Назначение Процессор
и РЖ
ММ55$ приемник, источник Минимум для одной пары РИ
вещественных чисел

Определяет минимальные числа © плавающей запятой в нулевой паре чисел


(биты 31-0), находящихся в источнике (переменная или регистр 5ЗЕ) и прием-
нике (регистр 55Е). Результат записывается в приемник. Биты 127-32 приемни-
ка не изменяются. Если источник или приемник включает не-число (ЗМАМ), то
возвращается содержимое другого аргумента. При сравнении двух нулей возвра-
щается нуль из источника. Если не-число сравнивается с другим не-числом, воз-
вращается не-число из источника.

Команды сравнения
Команда Назначение Процессор
и т
СМРР$ приемник,источник, предикат Сравнение упакованных РИ /.
.вещественных чисел

Для каждой из четырех пар вещественных чисел, находящихся в источнике


(переменная или регистр 553Е) и приемнике (регистр $5Е), возвращает либо 0
(ложь), либо ОРЕРЕЕЕЕЕВ (истина), в зависимости от результата сравнения. Тип
сравнения определяется предикатом (число):

Предикат Проверяемое утверждение


О (еа} Приемник равен источнику
1 (и) Приемник строго меньше источника
2 (е} ” Приемник меньше или равен источнику
3 (ипога) Приемник или источник являются не-числом
4 (пеа) Приемник не равен источнику
5 (пи) ` Приемник больше или равен источнику

4 Зак. 459
981 |1 || 111 Процессоры 1т4е| в реальном режиме
Предикат Проверяемое утверждение
6 (те) | Приемник строго больше источника |
7 (ога) Ни приемник, ни источник не являются не-числом
ООО ОИ

‚ Если один из операндов - не-число, результатом сравнения является 0 для


предикатов 0, 1, 2, 7 и истина для предикатов 3, 4,5, 6.

Команда Назначение Процессор


оо0о—к—0_—О——оЫЗ
——_——_—_—_ Ш 6—68—<———————5——к———_—<—<————_—_д_оод—оо_од—д
рии

СМР5$ приемник, источник, предикат Сравнение одной пары РИ


упакованных чисел
ридер

Выполняет сравнение нулевых (занимающих биты 31-0) вещественных чисел


‘из источника и приемника аналогично команде СМРР5. Биты 127-32 приемника
не изменяются.
дцзкд_
—_ п—_жжфжииии____Щ———__—_—_
Команда Назначение ` Процессор
ООО деи
СОМ1!5$ приемик, источник ° Сравнение одной пары чисел ` РН
с установкой флагов

Выполняет сравнение нулевых (занимающих биты 31-0) вещественных чисел


из источника (переменная или регистр 55Е) и приемника (регистр $5Е) и уста-
навливает флаги 7ЕРЕ СЕ регистра ЕЕГ.АС$ в соответствии с результатом. Флаги
ОЕ $Е АЕ обнуляются. Если одно из сравниваемых чисел — не-число, все три фла-.
га (ГЕ РЕ СР) устанавливаются в 1. Если сравниваемые числа равны, то 2Е = 1,
РЕ = СЕ = 0. Если приемник меньше источника, то СЁ = 1, 7Е =РЕ = 0. Если
приемник больше источника — СЕ = 2Е = РЕ = 0.
Команда Назначение ` Процессор
1

ЦСОМ!$$ приемик, источник Сравнение одной пары неупорядоченных РШ


. чисел с установкой флагов н
ООО оо
Эта команда полностью аналогична СОМ[5$, но она приводит к исключению
=Т. если один из операндов ЗМАМ или ОМАМ; ЧСОМТ$$ только если один из
операндов — ЗМАМ.
Команды преобразования типов
щ————_А—
—_— и щ——————————ж——
Команда | Назначение Процессор _

С\УТРА2Р$ приемник, источник Преобразовать упакованные целые РИ


в вещественные
д и
идя _Щ[—-Щымы:9—к8—цкдкцж—ж—ъъ——д

Преобразует два 32-битных целых числа со знаком из источника (регистр


ММХ или 64-битная переменная) в два упакованных вещественных числа в при-
емнике (регистр $$Е). Если преобразование нельзя выполнить точно, результат
округляется в соответствии с МХСЗВ. Биты 127-64 приемника не изменяются. ;
_ ии АиАаАдрДрАик ии ———
Команда Назначение ‚Процессор
ООО
дол ьивииме
СУТР$2Р! ‘приемник, источник Преобразовать упакованные РН
вещественные в целые
Расширение $$Е 1 ОС
ПОТ:
Преобразует младшие два 32-битных вещественных числа из источника (ре-
гистр 55Е или 64-битная переменная) в два упакованных целых числа со знаком
в приемнике (регистр ММХ). Если преобразование нельзя выполнить точно, ре-
зультат округляется в соответствии с МХСЗК. Если результат больше максимально-
го 32-битного числа со знаком, возвращается целая неопределенность (800000001).
Команда Назначение Процессор

С\УТ$125$ приемник, источник Преобразовать целое в вещественное РИ

Преобразует 32-битное целое число со знаком из источника (переменная или


32-битный регистр) в вещественное число в приемнике (регистр $5Е). Если
преобразование нельзя выполнить точно, результат округляется в соответствии
с МХСЗВ. Биты 127-32 приемника не изменяются.
Команда Назначение ` Процессор

С\УТ$$2$! приемник, источник Преобразовать вещественное в целое РИ

Преобразует нулевое (младшее) вещественное число из источника (регистр


55Е или 32-битная переменная) в 32-битное целое число со знаком в. приемнике
(32-битный регистр). Если преобразование ‘нельзя выполнить точно, результат
округляется в соответствии с МХС$К. Если результат больше максимального
32-битного числа со знаком, возвращается целая неопределенность (80000000Ъ).
Команда , Назначение Процессор
дао
ыы ——А———ы—ы—щ—ощоо лили

СУТТР$2Е! приемник, источник Преобразование вещественных РИ


в целые с обрезанием

Выполняется аналогично СУТР$2РУ, но, если результат не может быть пред-


ставлен точно, он всегда округляется в сторону нуля (обрезается).
Команда Назначение Процессор

С\УТТ$$2$! приемник, источник Преобразование вещественного РИ


в целое с обрезанием

Выполняется аналогично СУТ$$2$1, но, если результат не может быть пред-


ставлен точно, он всегда округляется в сторону нуля (обрезается).
Логические операции
Команда Назначение Процессор
АМОР$ приемник, источник Логическое И для ЗЗЕ . РИ

Выполняет операцию побитового «логического И» для источника (регистр


55Е или 128-битная переменная) и приемника (регистр 55Е) и помещает ре-
зультат в приемник.
Команда Назначение Процессор
АМОМР$ приемник, источник Логическое НЕ-И для 5$Е РИ
1001 1 |||] Процессоры те! в реальном режиме
Выполняет операцию НЕ над содержимым приемника (регистр 55Е), затем
выполняет операцию И над результатом и содержимым источника (регистр 55Е
или 128-битная переменная) и записывает результат в приемник.

Команда Назначение Процессор

ОВНР$ приемник, источник Логическое ИЛИ для 55Е РИ

Выполняет операцию побитового «логического ИЛИ» для источника (регистр


З5Е или 128-битная переменная) и приемника (регистр 55Е) и помещает резуль-
тат в приемник.
Команда Назначение Процессор
иди др
ХОВР5 приемник, источник ‚ Логическое исключающее ИЛИ для 55Е РИ

Выполняет операцию побитового «логического исключающего ИЛИ» для


источника (регистр 55Е или 128-битная переменная) и приемника (регистр
$5Е) и помещает результат в приемник.

Целочисленные УМО-команды
° Помимо расширения для работы с упакованными вещественными числами в 55Е
входит расширение набора команд для работы с упакованными целыми числами,
которые размещаются в регистрах ММХ.

Команда Назначение °’ Процессор

РАМСВ приемник, источник Усреднение байтов с округлением = РИ


РАУСМ/ приемник, источник Усреднение слов с округлением ' РИ

Каждый элемент (байт или слово) источника (регистр ММХ или 64-битная
переменная) добавляется к соответствующему элементу приемника (регистр
ММХ) как беззнаковое целое. Каждый из результатов сдвигается вправо на один
бит (делится на два). Затем в старший бит каждого элемента записывается бит |
переноса от соответствующего сложения. В результате этих действий получаются
средние арифметические целых чисел со знаками.
Команда Назначение Процессор
РЕХТН\У приемник, источник, индекс Распаковать одно слово . РИ

Выделяет 16-битное слово из источника (регистр ММХ) с номером, определя-


емым как младшие два бита индекса (непосредственно заданное число), и поме-
щает его в младшую половину 32-битного регистра-приемника.
Команда Назначение Процессор

РАМЗВ\/ приемник, источник, индекс Запаковать одно слово РИ

Считывает слово из источника (16-битная переменная или 32-битный ре-


гистр, во втором случае используется младшая половина регистра) и помещает
Расширение $5Е Г О ЕТК
его в приемник (регистр ММХ) в положение, задаваемое младигими двумя бита-
ми индекса (непосредственно заданное число). Другие три слова в приемнике не
изменяются.

Команда Назначение Процессор

РМАХОВ приемник, источник Максимум для упакованных байтов | РИ

Для каждой из восьми пар упакованных байтов из источника (регистр ММХ


или 64-битная переменная) или приемника (регистр ММХ) в приемник записы-
вается максимальный байт в паре. Сравнение выполняется без учета знака.

Команда Назначение Процессор

РМАХЗМ/ приемник, источник Максимум для упакованных слов РИ

Для каждой из четырех пар упакованных слов из источника (регистр ММХ


или 64-битная переменная) или приемника (регистр ММХ) в приемник записы-
вается максимальное слово в паре. Сравнение выполняется с учетом знака.

Команда Назначение Процессор


РМИМОВ приемник, источник Минимум для упакованных байтов ‘ РИ

Для каждой из восьми пар упакованных байтов из источника (регистр ММХ


или 64-битная переменная) или приемника (регистр ММХ) в приемник записы-
вается минимальный байтв паре. Сравнение выполняется без учета знака.

Команда . Назначение Процессор

РМИМ$М! приемник, источник Минимум для упакованных слов , РИ

Для каждой из четырех пар упакованных слов из источника (регистр ММХ


или 64-битная переменная) или приемника (регистр ММХ) в приемник записы-
вается минимальное слово в паре. Сравнение выполняется с учетом знака.

Команда Назначение . Процессор

РМОУМ$КВ приемник‚источник . Считать байтовую маску - РИ

В приемнике (32-битный регистр) каждый из младших 8 бит устанавливается


равным старшему (знаковому) биту соответствующего байта источника (регистр
ММХ). Биты 31-8 приемника обнуляются.

Команда | Назначение . Процессор

РМИУЕНИМ/ приемник, источник Старшее умножение без знака РИ

Умножить упакованные беззнаковые слова из источника (регистр ММХ или


64-битная переменная) и из.приемника (регистр ММХ) и поместить старшие
16 бит 32-битного результата в соответствующее слово в приемнике.
1021 1 11| Процессоры \{е! в реальном режиме
Команда Назначение Процессор

РЗАОВМ/ приемник,источник Сумма абсолютных разностей РИ

Вычисляет абсолютные разности восьми пар байтов из источника (регистр


ММХ или 64-битная переменная) и приемника (регистр ММХ) как целых чисел
без знака, затем суммирует результаты и помещает их в младшее (нулевое) слово
в приемнике. Старшие три слова обнуляются.
Команда | Назначение . Процессор
ЗНУРМ/ приемник, источник, индекс Переставить упакованные слова РИ

Вместо каждого из четырех слов приемника (регистр ММХ) размещается слово


из источника (регистр ММХ или 64-битная переменная) с номером, указанным в со-
ответствующей паре битов индекса (непосредственно заданное 8-битное число). Так,
вместо слова 0 (биты 15-0) приемника будет записано слово из источника с номе-
ром, равным значению битов 1 и 0 индекса. Например, если индекс равен 10101010Ъ,
второе слово источника будет скопировано во все четыре слова приемника.
Команды упаковки
Команда | Назначение Процессор

ЗНУЕР$ приемник, источник, индекс Переставить упакованные вещественные РИ

Помещает в старшие два вещественных числа приемника (регистр 55Е) лю-


бые из четырех чисел, находившихся в источнике (регистр $5Е или 128-битная
переменная). В младшие два числа приемника помещает любые из четырех чи- :
сел, находившихся в приемнике. По индексу (непосредственный операнд) опре-
деляется, какие именно числа упаковываются подобным образом. Биты 1 и 0 ука-
зывают номер числа из приемника, которое будет записано в нулевую позицию
прнемника; биты 3 и 2 - номер числа из приемника, которое будет записано в пер-
вую позицию приемника. Биты 5 и 4 устанавливают номер числа из источника,
которое будет записано в третью позицию, а биты 7 и 6 - номер числа из источни-
ка, которое будет записано в четвертую позицию. | |

хоманда Назначение ° Процессор


УМРСКНР$ приемник, источник Распаковать старшие РИ
вещественные числа

В нулевую позицию приемника (регистр $$Е) записывается второе число из


приемника, в первую позицию — второе число из источника (регистр З5Е или
128-битная переменная), во вторую позицию - третье (старшее) число приемни-
ка, в третью (старшую) позицию - третье (старшее) число источника.
Команда Назначение Процессор

УМРСКЕР$ приемник,источник Распаковать младшие РИ


вещественные числа
Расширение $5Е т 103
В нулевую позицию приемника (регистр $5Е) записывается нулевое (млад-
шее) число из приемника, в первую позицию - нулевое (младшее) число из ис-
точника (регистр 5$5Е или 128-битная переменная), во вторую позицию -—первое
число приемника, в третью (старшую) позицию -— первое число источника.

Команды управления состоянием

Команда Назначение Процессор

-ОМХСЗН источник Загрузить регистр МХС$Н РИ

Помещает значение источника (32-битная переменная) в регистр управления


и состояния 55Е МХСЗК.

Команда Назначение Процессор.

ЭТМХСЗН приемник Сохранить регистр МХС$В ‚ РИ

Помещает значение регистра МХС$Ё в приемник (32-битная переменная).


Команда Назначение Процессор
-ХЗАУЕ приемник Сохранить состояние ЕРИ, ММХ, $$Е РИ

Сохраняет содержимое всех регистров ЕРО, ММХ и $5Е в приемнике (512-


байтовая область памяти).
Команда Назначение Процессор

-ХАЗТОН источник Восстановить состояние ЕРУ, ММХ, 55Е РИ

Восстанавливает содержимое всех регистров ЕРО, ММХ и 55Е из источника


{512-байтовой области памяти, заполненной командой ЕХЗАУЕ).
Формат области памяти, используемой командами ЕХЗАУЕ/ЕХВ$ТОВ для
Репнит Ш, имеет следующий вид:
байты 1—0: ЕСУ/
байты 3—2: ЕЗ\У
байты 5—4: ЕТУ
байты 7-6: ЕОР
байты 11-8: ЕТР 7
байты 13-12: ЕС$
байты 19-16: ЕОР
байты 21-20: Е0$
байты 27-24: МХСУК.
байты 41-32: $Т0 или ММО
байты 57-48: 5Т1 или ММ1
байты 73—64: $Т2 или ММ2
байты 89-80: ТЗ или ММЗ
‘байты 105-96: $Т4 или ММА
байты 121-112: $Т5 или ММ5
И О О И Процессоры
и\е! в реальном режиме
байты 137—128: $Тб или ММб
байты 153-144: $Т7 или ММ7
байты 175-160: ХММОо
байты 191—176: ХММ!
байты 207-192: ХММ2
байты 223-208: ХММЗ
байты 239-224: ХММ4
байты 255-240: ХММ5
байты 271-256: ХММ6б
байты 287-272: ХММ7
Остальные байты зарезервированы.
. Команды управления кэширование

Команда Назначение Процессор


МАЗКМОУС источник,маска Запись байтов минуя кэш , РИ

Данные из источника (регистр ММХ) записываются в память по адресу |


0$:ЕБТ (или 05:01). При этом старший бит каждого байта в маске (регистр
ММХ) определяет, записывается ли соответствующий байт источника в память
или нет. То есть бит 7 маски разрешает запись нулевого байта (битов 7-0) источ- -
ника и т. д. Если байт не записывается, соответствующий байт в памяти обнуля-_
ется. Эта команда введена для того, чтобы по возможности уменьшить загрязне-
ние кэша при работе с потоками данных, типичными для ЗЗЕ, если основным |
типом данных является байт.
Команда Назначение Процессор
МОУМТО приемник, источник Запись 64 бит минуя кэш РИ

Содержимое источника (регистр ММХ) записывается в приемник (64-битная 3


переменная в памяти), сводя к минимуму загрязнение кэша.
Команда Назначение Процессор
МОУММТР$ приемник, источник Запись 128 бит минуя кэш РИ

Содержимое источника (регистр $5Е) записывается в приемник (128-битная


переменная в памяти). сводя к минимуму загрязнение кэша.
Команда Назначение Процессор

РВЕЕЕТСНТО адрес Перенести данные в кэш ТО - РИ


РВЕЕЕТСНТ1 адрес Перенести данные в кэш Т1 РИ
. РВЕРЕТСНТ2 адрес Перенести данные в кэш Т2 РИ
РВЕЕРЕТСНМТА адрес Перенести данные в кэш МТА РИ

Эти команды перемещают данные, располагающиеся по указанному адресу, |


в кэш. При этом возможны следующие варианты:
Расширение $55Е ПО ОО СТО
ОТО - поместить данные в кэш всех уровней;
ОТ1 - пометить данные в кэш всех уровней, кроме нулевого;
ОТ2 - поместить данные в кэш всех уровней, кроме нулевого и первого;
ОМТА - поместить данные в кэш для постоянных данных. `
Реализация этих команд может отличаться для разных процессоров, и процес-
гор не обязан их выполнять — команды рассматриваются только как подсказки.
Объем данных, переносимых в кэш, также может различаться, но не должен быть
меньше 32 байт. -

Команда Назначение ° Процессор

ЭРЕМСЕ Защита записи РИ

При работе с памятью современные процессоры могут выполнить обращения


к ней совсем не так и не в том порядке, в каком они указаны в программе. Коман-
да ЗЕЕМСЕ гарантирует, что все операции записи в память, расположенные в тек-
сте программы до нее, будут выполнены раньше, чем процессор начнет выполнять
операции, помещенные в тексте программы позднее.

2.6.4. Определение поддержки $5Е


Перед тем как начинать работать с расширениями 55Е (согласно документа-
ции ие), нужно убедиться, что выполнены следующие три условия:
1. Бит 2 регистра СВО (эмуляция сопроцессора) должен быть равен нулю.
2. Бит 9 регистра СВ4 (поддержка команд ЕХЗАУЕ/ЕХВ$ТОБК) должен быть
равен 1.
3. Бит 25 регистра ЕОХ после команды СРП) (поддержка $5Е) должен быть
равен 1.

2.6.5. Исключения
Особые ситуации при выполнении команд 55Е вызывают новое системное
исключение #ХЕ (ТУТ 19), обработчик которого может прочитать содержимое
регистра МХСЪВ, чтобы определить тип исключения и выполнить соответствую-
щие действия. Кроме того, команды $5Е могут вызывать и обычные системные
исключения - #0Ш (неопределенная команда), #ММ (расширение отсутствует),
#55 (переполнение стека), #СР (общая ошибка защиты), #РЕ (ошибка странич-
ной защиты), #АС (невыровненное обращение к памяти). |
Собственные исключения, вызываемые командами $5Е и отраженные при
помощи флагов в регистре МХСЪЗЬ, - это:
ОЯТ - невыполнимая команда (вызывается перед выполнением команды);
0#1 - деление на ноль (вызывается перед выполнением команды);
9# - денормализованный операнд (вызывается перед выполнением команды):
О #0 - переполнение (вызывается после выполнения команды);
О #1 - антипереполнение (вызывается после выполнения команды);
ОЯР - потеря точности (вызывается после выполнения команды).
ТТ РТТТ

Глава 3. Директивы
и операторы ассемблера
Каждая программа на языке ассемблера помимо команд процессора содержит еще
`и специальные инструкции, указывающие самому ассемблеру, как организовы-. 1
вать различные секции программы, где располагаются данные, а где команды,
позволяющие создавать макроопределения, выбирать тип используемого процес-
сора, налаживать связи между процедурами и т. д. К сожалению, пока нет единого,
стандарта на эти команды (он существует для МХ, о чем рассказано в главе 11).
Разные ассемблеры используют различные наборы директив, но ТАЗМ и МАЗМ
(два самых популярных ассемблера для РОЗ и \Ип4о\5) поддерживают общий
набор, или, точнее, ТАЗМ поддерживает набор директив МА$М наряду с несов-
местимым собственным, известным как [4еа| Моде. Все примеры программ в кни-
ге написаны так, чтобы для их компиляции можно было воспользоваться ТАЗМ,
МАЗМ или \\А$М - еще одним популярным ассемблером, поэтому в данной гла-
ве рассмотрены те предопределенные идентификаторы, операторы и директивы,
которые поддерживаются этими тремя ассемблерами одновременно.

3.1. Структура программы


Программа на языке ассемблера состоит из строк, имеющих следующий вид:
метка команда/директива операнды ; комментарий

Причем все эти поля необязательны. Метка может быть любой комбинацией
букв английского алфавита, цифр и символов _, $, @; ?, но цифра не может быть
первым символом "метки, а символы $ и ? иногда имеют специальные значения
и обычно не рекомендуются к использованию. Большие и маленькие буквы по
умолчанию не распознаются, но различие можно включить, задав ту или иную оп-
цию в командной строке ассемблера. Во втором поле, поле команды, может рас-
полагаться команда процессора, которая транслируется в исполняемый код, или
директива, которая не приводит к появлению нового кода, а управляет работой:
самого ассемблера. В поле операндов располагаются требуемые командой или ди-
рективой операнды (то есть нельзя указать операнды и не указать команду или
директиву). И наконен, в поле комментариев, начало которого отмечается симво-
лом ; (точка с запятой), можно написать все что угодно -— текст от символа ; до
конца строки не анализируется ассемблером.
Для облегчения читаемости ассемблерных текстов принято, что метка начина-
ется на первой позиции в строке, команда - на 17-й (две табуляции), операнды —
Структура программы- о 107
на 25-й (три табуляции) и комментарии - на 41-й или 49-й. Если строка состоит
только из комментария, его начинают с первой позиции.
Если метка располагается перед командой процессора, сразу после неё всегда
ставится оператор : (двоеточие), который указывает ассемблеру, что надо создать
переменную с этим именем, содержащую адрес текущей команды:
зоте_1оор:
109$ ; Считать слово из строки.
стр ах, 7 ; Если это 7 - выйти из цикла.
]Щоорпе зоме_1оор :

Когда метка стоит перед директивой ассемблера, она обычно оказывается од-
ним из операндов этой директивы и двоеточие не ставится. Рассмотрим директи-
вы, работающие напрямую с метками и их значениями, — ТАВЕЕ, ЕОП и-=.
метка — 1абе1 тип
Директива ГАВЕГ, определяет метку и задает ее тип: ВУТЕ (байт), \МОВО
(слово), ОУГОВР (двойное слово), ЕХМОКО (6 байт), О\ОКГ (учетверенное сло-
во), ТВУТЕ (10 байт), МЕАВ (ближняя метка), ЕАВ (дальняя метка). Метка полу-
чает значение, равное адресу следующей команды или следующих данных, и тип,
указанный явно. В зависимости от типа команда’
[е№ метка,0

запишет в память байт (слово, двойное слово ит: д.), заполненный нулями, а ко-
манда
са11 метка

выполнит ближний или дальний вызов подпрограммы.


С помощью директивы Г.АВЕТ. удобно организовывать доступ к одним и тем же
данным, как к байтам, так и к словам, определив перед данными две метки с разны-
ми типами.
метка еду выражение

Директива ЕОП присваивает метке значение, которое определяется как ре-


зультат целочисленного выражения в правой части. Результатом этого выражения
может быть целое число, адрес или любая строка символов:
Тгитп еди 1
пеззаде1 еци 'Тгу ада1п$’ р
уаг2 еци 4[$1]
стр ах, сгитп ; стр ах,1
- Ч6 пмеззаде1 - ; 4 'Тгу адашт$’
оу ах, маг? ‚ шеи ах, 4[$1]
Директива ЕОТ чаще всего используется с целью введения параметров, общих
для всей программы, аналогично команде #4ейпе препроцессора языка С.
метка = выражение .
108 ГГ Директивы и операторы ассемблера
Директива = эквивалентна ЕОО, но определяемая ею метка может принимать
только целочисленные значения. Кроме того, метка, указанная этой директивой,
может быть переопределена.
Каждый ассемблер предлагает целый набор специальных предопределенных
меток — это может быть текущая дата (@дае или ??4а{е), тип процессора (@сри)
или имя того или иного сегмента программы, но единственная предопределенная
метка, поддерживаемая всеми рассматриваемыми нами ассемблерами, - $. Она
всегда соответствует текущему адресу. Например, команда
тр $
выполняет безусловный переход на саму себя, так что создается вечный цикл из
одной. команды.

3.2. Директивы распределения памяти


3.2/1. Псевдокоманды определения переменных
Псевдокоманда — это директива ассемблера, которая приводит к включению
данных или кода в программу, хотя сама-никакой команде процессора не соответ-
ствует. Псевдокоманды определения переменных указывают ассемблеру, что в со-
ответствующем Месте программы располагается переменная, устанавливают ее
тип (байт, слово, вещественное число ит. д.), задают начальное значение и ставят.
в соответствие переменной метку, которая будет использоваться для обращения
к этим данным. Псевдокоманды определения данных записываются в общем виде
следующим образом:
имя_переменной 9* ‚ Значение

где О* - одна из нижеприведенных псевдокоманд:


ОВ - определить байт;
Р\/- определить слово (2 байта);
Ор - определить двойное слово (4 байта);
ОЕ - определить 6 байт (адрес в формате 16-битный селектор: 32-битное сме-
щение);-
РО - определить учетверенное слово (8 байт);
ОТ - определить 10 байт (80-битные типы данных, используемые ЕРИ).
Поле значения может содержать одно или несколько чисел, строк символов
(взятых в одиночные или двойные кавычки), операторов ? и ОТР, разделенных
запятыми. Все установленные таким образом данные окажутся в выходном фай-
ле, а имя переменной будет соответствовать адресу первого из указанных значе-
ний. Например, набор директив
техт_з1г1пд 95 'Не11о мог19!'
питбег | Чи 7 ,
таь1е 6 1,2,3,4,5,6,7,8,
9, ОАВ, ОВ, ОСН, ООВ, ОЕВ, ОР
Т1оа*_питег 99 3.5е7
и | ! .
.
Директивы распределения памяти и: | 1 109.
}

заполняет данными 33 байта. Первые 12 байт содержат АЗСП-коды символов


строки Нео уот 41, и переменная (ехЕ_ зип указывает на первую букву в этой
строке, так что команда
оу а], тех{_$1г1п9

считает в регистр АТ. число 48В (код латинской буквы Н). Если вместо точного
значения указан знак 2, переменная считается неинициализированной и ее зна-
чение на момент запуска программы может оказаться любым. Если нужно запол-
нить участок памяти повторяющимися данными, используется специальный опе-
ратор РУР, имеющий формат счетчик ГИР (значение). Например, вот такое опре-
деление:
-а61е_512м 9м 512 4ир(?)

создает массив из 512 неинициализированных слов, на первое из которых указы-


вает переменная {ае_512\.. В качестве аргумента в операторе ОТР могут высту-
пать несколько значений, разделенных запятыми, и даже дополнительные вло-
женные операторы ОТР.

3.2.2. Структуры
Директива ТВОС позволяет определить структуру данных аналогично
структурам в языках, высокого уровня. Последовательность директив
ИМЯ ЗЕгис.
,
поля
имя епаз

где поля — любой набор псевдокоманд определения переменных или структур,.


устанавливает, но не инициализирует структуру данных, В дальнейшем для ее
создания в памяти используют имя структуры как псевдокоманду: -

метка Имя <значения>

И наконец, для чтения или записи в элемент структуры используется оператор .


(точка). Например:
ролпт ЗТгис. . ; Определение структуры.
х | 9м 0 у ; Три слова со значениями
у ` ом 0 ; по умолчанию 0, 0,0
2 ам 0 —
со1 ог 96 3 9ир(?) ` :.и три байта.
ро1пт епа5 \

сиг_ро1пе ро1пт <1,1,1,255,255, 255> ; Инициализация.

оу ах, сиг _ро1пе. х ‚ Обращение к слову “Х”.

Если была определена вложенная структура, доступ к ее элементам осуществ-


ляется через еще один оператор . (точка).
мо Директивы и операторы ассемблера
со] ог эТгис ‚; Определить структуру со1ог.
гед 95 ?
дгееп [9] 2
Ы це ЧБ
с010г епд$

ро1пт $гис
х 9м 0
у Чи 0
2 Чм 0
с1г со1ог <>
ро1пт епд$

‚ сиг_ретпт рот <>

моу сиг_ро1пе. с1г. гед, а1 ; Обращение к красной компоненте ”


| ‚ цвета точки сиг_ро1пт.

3.3. Организация программы


3,3.1. Сегменты
Каждая программа, написанная на любом языке программирования, состоит
из одного или нескольких сегментов. Обычно область памяти, в которой находят-
ся команды, называют сегментом кода, область памяти с данными — сегментом
_ данных и область памяти, отведенную под стек, — сегментом стека. Разумеется,
ассемблер позволяет изменять устройство программы как угодно— помещать дан-
ные в сегмент кода, разносить код на множество сегментов, помещать стек в один
сегмент с данными или вообще использовать один сегмент для всего.
Сегмент программы описывается директивами ЗЕСМЕКТ и ЕМО5.
_ имя_сегмента зедтепт геадоп1у' выравн. тип разряд ' класс’

имя_сегмента епаз

Имя сегмента — метка, которая будет использоваться для получения сегмент-


ного адреса, а также для комбинирования сегментов в группы.
Все пять операндов директивы ЗЕСМЕМТ необязательны.
ВЕАРОМТУ. Если этот операнд присутствует, МАЗМ выдаст сообщение об
ошибке на все команды, выполняющие запись в данный сегмент. Другие ассемб-
леры этот операнд игнорируют.
Выравнивание. Указывает ассемблеру и компоновщику, с какого адреса может
начинаться сегмент. Значения этого операнда:
о ВУТЕ - с любого адреса;
о \/ОВРЬ - с четного адреса;
оО\/ОЕО - с адреса, кратного 4;
ОРАВА - с адреса, кратного 16 (граница параграфа);
ОРАСЕ -- с адреса, кратного 256.
По умолчанию используется выравнивание по границе параграфа.
Организация программы И]
Тип. Выбирает один из возможных типов комбинирования сегментов:
что всета-
отип РОВЫС (иногда используется синоним МЕМОВКУ) означает,
вым именем, но разными классам и будут объедине-
кие сегменты с одинако
ны в один;
для сег-
Отип 5ТАСК - то же самое, что и РОВС, но должен использоваться
что при загрузке програм мы сегмент, получен ный объеди-
ментов стека, потому
|
нением всех сегментов типа 5ТАСК, будет использоваться как стек;
в один,
О сегменты типа СОММОКМ с одинаковым именем также объединяются
длина
но не последовательно, а по одному и тому же адресу, следовательно,
сегменто в,
суммарного сегмента будет равна не сумме длин объединяемых
Таким способо м
как в случае РОВЫС и $ТАСК, а длине максимального.
иногда можно формировать оверлейные программы;
по фик-
отип АТ - выражение указывает, что сегмент должен располагаться
выражен ия, исполь-
сированному абсолютному адресу 8 памяти. Результат
адресу, деленно му на 16.
зующегося в качестве операнда для АТ, равен этому
по абсолют ному адресу
Например: зевтепе а& 40} — сегмент, начинающийся
на об-
0400. Такие сегменты обычно содержат только метки, указывающие
програм ме; :
ласти памяти, которые могут потребоваться
яется
- ОРЕТУАТЕ (значение по умолчанию) - сегмент такого типа не объедин
с другими сегментами.
Раз-
Разрядность. Этот операнд может принимать значения 1$Е16 и 9$ЕЗ2.
Кб, и все команды
мер сегмента, описанного как 0 5Е16, не может превышать 64
мож-
и адреса в этом сегменте считаются 16-битными. В этих сегментах все равно
или ссылаю щиеся на
но применять команды, использующие 32-битные регистры
изменения
данные в 32-битных сегментах, но они будут использовать префикс
Сегменты
разрядности операнда или адреса и окажутся длиннее и медленнее.
в них по умолчан ию 32-бит-
0$ЕЗ2 могут занимать до 4 Гб, и все команды и адреса
ные. Если разрядность сегмента не указана, по умолчанию использ уется 0$3Е1б
при условии, что перед.МОРГЕГ. не применялась директива задания допусти мого
набора команд .386 или старше.
Класс сегмента — это любая метка, взятая в одинарные кавычки. Все сегменты
с одинаковым классом, даже сегменты типа РЕТУАТЕ, будут расположены в ис-
полняемом файле непосредственно друг за другом. о

Для обращения к любому сегменту следует сначала загрузить его сегментный


адрес (или селектор в защищенном режиме) в какой-нибудысегментный регистр.
Если в программе определено много сегментов, удобно объединить несколько сег-
ментов в группу, адресуемую с помощью одного сегментного регистра:
9гоир имя_сегмента. ..
имя _группы

Операнды этой директивы — список имен сегментов (или выражений, исполь-


зующих оператор $ЕС), которые объединяются в группу. Имя группы теперь
можно применять вместо имен сегментов для получения сегментного адреса и для
директивы АЗЗОМЕ.
1 Директивы и операторы ассемблера
аззите — регистр: связь. ..

Директива АЗЗОМЕ указывает ассемблеру, с каким сегментом или группой


сегментов связан тот или иной сегментный регистр. В качестве операнда «связь»
° могут использоваться. имена сегментов, имена групп, выражения с оператором
ЕС или слово «МОТНИМС», означающее отмену действия предыдущей А$$ОМЕ
для данного регистра. Эта директива не изменяет значений сегментных регист-
ров, а только позволяет ассемблеру проверять допустимость ссылок и самостоя-
тельно вставлять при необходимости префиксы переопределения сегментов.
Перечисленные директивы удобны для создания больших программ на ассем-
блере, состоящих из разнообразных модулей и содержащих множество сегментов. `
В повседневном программировании обычно используется ограниченный набор
простых вариантов организации программы, известных как модели памяти.
3.3.2. Модели памятии упрощенные директивы
определения сегментов |
Модели памяти задаются директивой .МОПЕГ -
.поде] модель, язык, модификатор

где модель — одно из следующих слов: | “-

оТ1МУ — код, данные и стек размещаются в одном и том же сегменте разме-


ром до 64 Кб. Эта модель памяти чаще всего используется при написании на
ассемблере небольших программ; |
о5МАЦ, - код размещается в одном сегменте, а данные и стек — в другом (для
их описания могут применяться разные сегменты, но объединенные в одну
группу). Эту модель памяти также удобно использовать для создания про-
грамм на ассемблере; |
ОСОМРАСТ - код размещается в одном сегменте, а для хранения данных мо-
гут использоваться несколько сегментов, так что для обращения к данным
требуется указывать сегмент и смещение (данные дальнего типа);
оМЕОДЦУМ - код размещается в нескольких сегментах, а все данные - в од-
ном, поэтому для доступа к данным используется только смещение, а вызо-
вы подпрограмм применяют команды дальнего вызова процедуры;
ОГАКСЕи НОСЕ - и код, и данные могут занимать несколько сегментов;
ОЕГАТ - то же, что и ТПМУ, но используются 32-битные сегменты, так что мак-
симальный размер сегмента, содержащего и данные, и код, и стек, - 4 Мб.
Язык — необязательный операнд, принимающий значения С, РАЗСАТ,, ВАЗТС,
ЕОВТВАМ, ЗУЗСА1Л, и $ЗТОСА1.1.. Если он указан, подразумевается, что проце-
дуры расчитаны на вызов из программ на соответствующем языке высокого
уровня, следовательно, если указан язык С, все имена ассемблерных процедур,
объявленных как РОВС, будут изменены так, чтобы начинаться с символа под-
черкивания, как это принято в С.
Модификатор - необязательный. операнд, принимающий значения
` МЕАВУТАСК (по умолчанию) или ЕАВЗТАСК. Во втором случае сегмент стека
не будет объединяться в одну группу с сегментами данных.
Организация программы — НА ОИ ОНИ |
После того как модель памяти установлена, вступают в силу упрощенные
директивы определения сегментов, объединяющие действия директив ЗЕСМЕМТ
и А5ЗОМЕ. Кроме того, сегменты, объявленные упрощенными директивами, не
требуется закрывать директивой ЕМО5 — они закрываются автоматически, как
только ассемблер обнаруживает новую директиву определения сегмента или ко-
нец программы.
Директива .СОШЕ описывает основной сегмент кода
.соде имя_сегмента

эквивалентно ,
_ТЕХТ зедтепЕ мог руБ11с 'С00Е’

для моделей ТПМУ, ЗМАЦ. и СОМРАСТ и


паше_ТЕХТ зецтепт нога рубле "СЕ
для моделей МЕРГОМ, НОСЕ и ГАКСЕ (ваше - имя модули, в котором описан
данный сегмент). В этих моделях директива.СОРЕ также А ®ускает необязатель-
ный операнд - имя определяемого сегмента, но все сегменты кода, описанные так
в одном и том же модуле, объединяются в один сегмент с именем МАМЕ_ТЕХТ.
.ЗТаск размер

Директива ЗТАСК описывает сегмент стека и эквивалентна директиве


ЭТАСК зедтепЕ рага. риб11с _ › зтаск'

Необязательный параметр указывает размер стека. По умолчанию он равен 1 Кб.


‚дата, _: | | | | | ,
Описывает обычный сегмент данных и соответствует директиве
_бАТА `. зедтеп{ могд риб11с. "ВАТА"

. дата? .

Описывает сегмент неинициализированных данных:


_В$$ | зедтепЕ мога риб11с 'В95'

Этот сегмент обычно не включается в программу, а располагается за концом


памяти, так что все описанные в нем переменные на момент загрузки программы
имеют неопределенные значения. Г
. соП${

Описывает сегмент неизменяемых данных:

СОМУТ зедтеп{ мога риБ11с ‘СОР

В некоторых операционных системах этот сегмент будет загружен так, что


попытка записи в него может привести к ошибке.
.Гагдата имя_сегмента
Г Директивы и операторы ассемблера
Сегмент дальних данных:
имя_сегмента зедтепт ‘рага рг1уате 'РАЯ_ОАТА”

Доступ к данным, описанным в этом сегменте, потребует загрузки сегментно-


го регистра. Если не указан операнд, в качестве имени сегмента. используется
ЕАК_ПАТА.
.Рагдата? ‘имя_сегмента р

Сегмент дальних неинициализированных данных:

имя_сегмента зедтеп{ рага рг1мате 'РАВ_В$$'

Как и в случае с ЕАВОАТА, доступ к’данным из этого сегмента потребует заг-


рузки сегментного регистра. Если имя сегмента не указано, используется ЕАК _В$$.
Во всех моделях памяти сегменты, представленные директивами .РАТА, .ОАТА?,
„СОМ$Т, .ЕАВПАТА и.ЕАКЛАТА?, а также сегмент, описанный директивой 5ТАСК,
если не был указан модификатор ЕАВЗТАСК, и сегмент .СОПЕ в модели ТПМУ ав-
томатически объединяются в группу с именем ЕТ.АТ - для модели памяти ЕГ.АТ или
ОСВОТР — для всех остальных моделей. При этом сегментный регистр 0$ (и 55,
если не было ЕАВ$ТАСК, и С$ в модели ТПМУ) настраивается. на вею эту группу,
как если бы была вынолнена команда АЗЗОМЕ. `

3.3.3. Порядок загрузки сегментов


, Обычно сегменты загружаются в память в том порядке, в котором они
описываются в тексте программы, причем, если несколько сегментов объединя-
ются в один, порядок определяется по началу первого из объединяемых сегмен-
тов. Этот порядок можно изменить с помощью одной из специальных директив.

‚ а1рпа
. _ #

Эта директива устанавливает алфавитный порядок загрузки сегментов.

.0085ед 7 для МАЗМ и МАЗМ


или ` ‚
90$5е9 ‚ для МАЗМ и ТАЗИ

Устанавливает порядок загрузки сегментов, существующий в М5 РОЗ и часто


требуемый для взаимодействия программ на ассемблере с программами на язы-
ках высокого уровня. РО$5ЕС устанавливает следующий порядок загрузки сег-
ментов:
1. Все сегменты класса 'СОПЕ'..
2. Все сегменты, не принадлежащие группе ОСКОТР и классу 'СОПЕ'.
3. Группа сегментов ОСКОТР: ^ |
— все сегменты класса 'ВЕСРАТА';
— все сегменты, кроме классов 'ВЕСОАТА', 'В$5' и'5ТАСК';
— все сегменты класса "В$5';
— все сегменты класса 'ЗТАСК..
Организация программы
.5е4
Устанавливает загрузку сегментов в том порядке, в котором они описаны в тек-
сте программы. Этот режим устанавливается по умолчанию, так что директива
.ЗЕО просто отменяет действие .АГРНА или ОО$ЗЕС.
Знание порядка загрузки сегментов необходимо, например, для вычисления
длины программы или адреса ее конца. Для этого надо знать, какой сегмент будет
загружен последним; и смещение последнего байта в нем.
3.3.4. Процедуры
Процедурой в ассемблере является все то, что в других языках называют под-
программами, функциями, процедурами и т. д. Ассемблер’ не накладывает на про-
цедуры никаких ограничений- на любой адрес программы можно передать уп-
равление командой СА! и оно вернется к вызвавшей процедуре, как только
встретится команда ВЕТ. Такая свобода выражения легко может приводить к труд-
ночитаемым программам, и в язык ассемблера были включены директивы логи-
ческого. оформления процедур.
метка | ргос язык тип У3Е5 регистры ; ТАЗМ
ИЛИ
метка р ргос тип ‘язык 15Е$ регистры —_; МАЗМ/МАЗН

гет
метка` | епар '
Все операнды РКОС необязательны.
Тип может принимать значения МЕАК и ЕАК, и если он указан, все команды
ВЕТ втеле процедуры будут заменены соответственно на ВЕТМ и ВЕТЕ По умол-
чанию подразумевается, что процедура имеет тип МЕАВ в моделях памяти ТЛМУ,
ЗМАШМ. и СОМРАСТ. | |
Операнд «язык» действует аналогично такому‹жеоперанду директивы МОРЕГ,
определяя взаимодействие процедуры с языками высокого уровня. В некоторых
ассемблерах директива РКОС позволяет также считать параметры, передаваемые
вызывающей программой. В этом случае указание языка необходимо, так как раз-
личные языки Высокого уровня используют разные способы передачи параметров.
ОЗЕ$- список регистров, значения которых изменяет процедура. Ассемблер по-
мещает в начало процедуры набор команд РОЗН, а перед командой ВЕТ- набор
команд РОР так что значения перечисленных регистров будут восстановлены.
3.3.5. Конец программы О:
епд зТтагт_1абе1

Этой директивой завершается любая программа на ассемблере. В роли необя-


зательного операнда здесь выступает метка (или выражение), определяющая ад-
рес, с которого начинается выполнение программы. Если программа состоит из
нескольких модулей, только один файл может содержать начальный адрес, так же
как в С только один файл может содержать функцию та!1():
\
| [11 Директивы и операторы ассемблера
3.3.6. Директивы задания набора допустимых команд
По умолчанию ассемблеры используют набор команд процессора 8086 и выда-
ют сообщения об ошибках, если выбирается команда, которую этот процессор не
поддерживал. Для того чтобы ассемблер разрешил использование команд, по-
явившихся в более новых процессорах, и команд расширений, предлагаются сле-
дующие директивы: |
0.8086— используется по умолчанию. Разрешены только команды 8086;
0.186 — разрешены команды 80186;
0.286 и. .286с — разрешены непривилегированные команды 80286;
О.286р - разрешены все команды 80286;
0.386 и .386с — разрешены непривилегированные команды 80386;
О.386р- разрешены все команды 80386; |
0.486 и .486с — разрешены непривилегированные команды 80486;
0.486р— разрешены все команды 80486; —
0.586 и .586с — разрешены непривилегированные команды Р5 (Репиит);
0.586р — разрешены все команды Р5 (РепИйит); |
0.686 — разрешены непривилегированные команды Рб (Репйита Рго, Репиат П);
О.686р — разрешены все команды Рб (Репиит Рго, Репйит П);
о.8087 — разрешены команды МРХ 8087;
0.287 — разрешены команды МРХ 80287;
0.387 — разрешены команды МРХ 80387;
0.487 — разрешены команды ЕРО 80486;
0.587 — разрешены команды ЕРО 80586;
о.ММХ - разрешены команды ГА ММ;
о.КЗО - разрешены команды АМО ЗО.
Не все ассемблеры поддерживают каждую директиву, например МАЗМ и \УАЗМ
‘не поддерживают .487 и .587, так как их действие не отличается.от .387. Естествен-
но, ассемблеры, вышедшие до появления последних процессоров и расширений,
нев состоянии выполнять соответствующие им команды.
Если присутствует директива .386 или выше, ассемблер \\МА$М всегда опреде-
ляет все сегменты как 32-битные при условии, что не указан явно операнд 05Е16;
МАЗМ и ТАЗМ действуют так же, только если директива задания набора команд
указана перед директивой .то4е].

3.3.7. Директивы управления программным счетчиком


Программный счетчик — внутренняя переменная ассемблера, равная смещению
текущей команды или данных относительно начала сегмента. Для преобразова-
ния меток в адреса используется именно значение этого счетчика. Значением
счетчика можно управлять с помощью следующих директив.
[2] выражение
\

Организация программы ИТ.


Устанавливает значение программного счетчика. Директива ОКС с ‘операндом
100р обязательно используется при написании файлов типа СОМ, которые заг-
ружаются в память после блока параметров размером 1001.
еуеп

Директива ЕУЕМ делает текущее значение счетчика кратным двум, вставляя -


команду МОР если оно было нечетным. Это увеличивает/скорость работы про-
граммы, так как для доступа к слову, начинающемуся с нечетного адреса, процес-
сор должен считать два слова из памяти. Если при описании сегмента не исполь-
зовалось выравнивание типа ВУТЕ, счетчик в начале сегмента всегда четный.
а119п значение `

Округляет значение программного счетчика др кратного указанному значе-


нию. Оно может быть любым четным числом. Если счетчик некратен указанному
числу, эта директива вставляет необходимое количество команд МОР.

3.3.8. Глобальные объявления


руб11с язык метка... ; Для ТАЗМ и МАЗМ.
или —.. у
рчб11с метка язык... ; Для МАМ.

Метка, объявленная директивой РОВС, становится доступной для других


модулей программы. Так, можно объявлять имена процедур, переменные и кон-
станты, определенные директивой ЕОТ..Необязательный операнд языка (С,
РАЗСАТ., ВА$1С, ЕОВТВАМ, $У5$САШ. или ЗТОСАШ..) указывает, что метка
будет вызываться из модуля, написанного на соответствующем языке, и при не-
обходимости изменяет ее (например, добавляет_ перед первым символом метки).
сот расст язык метка: тип... <; Для ТАЗМ.
сом язык ‘расст метка: тип... ; Для ТАЗМ.
сот расст метка:тип язык. ; Для МАЗМ.

Директива СОММ описывает бщую переменную. Такие переменные доступ-


ны из всех модулей, и их размещение в программе определяется на этапе компо-
новки. Обязательные аргументы директивы СОММ- метка (собственно имя об-
щей переменной) и тип (ВУТЕ, ОВО, О\/ОБВО, Е\/ОКО, ОМОВО, ТВУТЕ или
имя структуры). Необязательный операнд «расстояние» (МЕАК или ЕАБ) указыва-
ет, находится ли переменная в группе сегментов ОСКОТР (ближняя переменная,
для доступа достаточно смещения) или вне этих сегментов (дальняя переменная,
для доступа потребуется сегментный адрес). Для моделей памяти ТПМУ, ЗМАН.
и СОМРАСТ по умолчанию значение этого операнда принимается за МЕАК. И на-
конец, операнд «язык» действует аналогично такому же операнду для РОВЫС.
ехфтгп — язык метка: тип... ; Для МАЗМ и ТАЗМ.
ехЕгп метка:тип язык... ‚ ; Для МАЗМ.
й Директивы и.‘операторы ассемблера
описывает метку, определенную в другом модуле (с помощью РОВЫС). Тип
(ВУТЕ, ОКО, О\ОКРО, Е\/ОВО, ОМОВЬ, ТВУТЕ, имя структуры, ЕАК,
МЕАК, АВ$) должен соответствовать типу метки в том модуле, где ана была уста-
новлена (тип АВ$ используется для констант из других модулей, определенных
директивой ЕОП). Необязательный операнд языка действует так же, как и для
директивы РИВШС.
91а] язык метка: тип... ; Для МАЗМ и ТАМ, ^
91 оБа1 | метка:тип язык...; Для МАЗМ.

Директива СТОВАТ. действует, как РОВС и ЕХТЕМ одновременно. Когда


указанная метка находится в этом же модуле, она становится доступной для дру-
гих модулей, как если бы выполнилась директива РОВЫС. Если метка не описа-
на — она считается внешней извыполняется действие, аналогичное действию ди-
рективы ЕХТКМ.

3.3.9. Условное-ассемблирование
В большинстве языков программирования присутствуют средства, позволяю-
щие игнорировать тот или иной участок программы в зависимости от вылолне-
ния условий, например: в языке С это осуществляется командами препроцессора
- #1, #Иеё, и\т4еР и т. д. Ассемблер тоже : предоставляет такую возможность.
1 выражение

епазЕ -

Если значение выражения - ноль (ложь), весь участок программы между [Е


и ЕММЛЕ игнорируется. Директива Е может также сочетаться с ЕГЗЕ и ЕГЗЕГЕ:
ра выражение

е15е

епа1Е

Если значение выражения - ноль, ассемблируется участок программы от Е.Е


до ЕМОТЕ в противном случае - от ТЕ до ЕТЗЕ. .
17. —_. выражение!

е1зе1 выражение?

е15е1Р выражениеЗ

6156

епа1+

Так, если, например, выражение 2 не равно нулю, будет ассемблироваться учас-


ток программы между первой и второй директивой ЕГЗЕТЕ Если все три выражения
Организация программы . -. НИ О ОИС
равны нулю, ассемблируется фрагмент от ЕТ.ЗЕ до ЕМОТЕ Данная структура ди-
ректив может использоваться в частном случае аналогично операторам 5% св /
сазе языков высокого уровня, если выражения — проверки некоторой константы
на равенство.
Кроме общих директив ПЕ и ЕТЗЕЕ ассемблеры поддерживают набор специ-
альных`команд, каждая из которых проверяет специальное условие:
ОТЕ/ЕТЗЕТЕ1- если ассемблер выполняет первый проход ассемблирования; `
ЯТЕ2/ЕТ.$ЗЕТЕ2 - если ассемблер выполняет второй проход ассемблирования
(часто не работает на современных ассемблерах); -
ОТЕЕ выражение/ЕТЗЕТЕЕ выражение- если выражение равно нулю (ложно) _
ОТЕРЕЕ метка/ЕТ.ЗЕТЕОЕЕ метка - всли метка опрёделена;
ОТЕМОЕЕ метка/ЕТ.ЗЕТЕМОЕЕ метка - если метка не определена;
ОТЕВ <аргумент>/ЕТ.ЗЕ!ЕВ <аргумент>- если значение аргумента- пробел
(эти и все следующие директивы используются в макроопределениях для
проверки параметров);
ОТЕМВ <аргумент>/ЕГЗЕТЕМВ <аргумент> - если значение аргумента — не
пробел (используется в макроопределениях для проверки переданных пара-
метров);
ОТЕБГЕ <арг1>, <арг?> /ЕТ.ЗЕТЕРТЕ <арг1>,<арг2> - если аргументы отли-
чаются (с различием больших и маленьких букв);
оГЕОГЕ <арг1>,<арг2>/ЕГЗЕТЕОТЕ1 <арг1>,<арг2>-—если ‘аргументы отли-
чаются (без различия больших и маленьких букв);
О1ЕШМ <арг1>,<арг2>/ЕТЗЕТЕТОМ <арг1>,<арг2> - если аргументы одина-
ковы (с различием больших и маленьких букв);
О1ЕОМ! <арг1>,<арг2> /ЕТЗЕТЕТОМГ <арг1>,<арг2>— если аргументы оди-
‘наковы (без различия больших и маленьких букв).
Иногда директивы условного ассемблирования используются для того, чтобы
прервать ассемблирование программы, если обнаружилась какая-нибудь ошибка.
Для таких случаев предназначены директивы условной генерации ошибок. °
И $ 941 65535 ; Если адрес. вышел за пределы сегмента.
‚егг :
еп

Встретив директиву ЕЕК, ассемблер прекратит работу с сообщением об. ошиб-


ке. Аналогично командам условного ассемблирования существуют модификации
команды ЕЕК:
‚‹ 9.ЕКЕ1 - ошибка при первом проходе ассемблирования;
о.ЕВК2 - ошибка при втором проходе ассемблирования;
о.ЕВВЕ выражение — ошибка, если выражение равно нулю (ложно);
9.ЕВВМА выражение - ошибка, если выражение не равно нулю (истинно);
о.ЕВКОЕЕ метка — ошибка, если метка определена;
о.ЕВЕМПЕЕ метка — ошибка, если метка не определена;
о.ЕВЕВ <аргумент> - ошибка, если аргумент пуст (эта и все следующие ди-
рективы используются в макроопределениях для проверки параметров);
1
121
==»р 1111 Ш Директивы и операторы ассемблера
о.ЕКАМВ <аргумент> — ошибка, если аргумент не пуст;
о.ЕВЕЬТЕ <арг1>,<арг2> - ошибка, если аргументы различны;
о.ЕВКОГТЕ <арг1>,<арг2>— ошибка, если аргументы отличаются (сравнение
не различает большие и маленькие буквы);
с.ЕВКТОМ <арг1>,<арг2> — ошибка, если аргументы совпадают;
о.ЕКЕТОМ! <арг1>,<арг2> - ошибка, если аргументы совпадают (сравнение
не различает большие и маленькие буквы).

3.4. Выражения
Мы уже упоминали выражения при описании многих директив ассемблера.
Выражение- это набор чисел, меток или строк, связанных друг с другом оператора-
ми. Например: 2 + 2 — выражение, состоящее из двух чисел (2 и 2) и оператора +.
Каждое выражение имеет значение, которое определяется как результат действия
операторов. Так, значение выражения 2 + 2 - число 4. Все выражения вычисля-
ются в ходе ассемблирования программы, следовательно, в полученном коде ис-
пользуются только значения.
Оператор <> (угловые скобки). Часть выражения, заключенная в угловые
скобки, не вычисляется, а применяется как строка символов, например:
теззаде1 еди _ ° «Рообаг>
Оператор {) (круглые скобки). Часть выражения, заключенная в круглые скоб-
ки, вычисляется в первую очередь.
тоу 21, 2*(3+4) ; МОУ а1, 14

Арифметические операторы: + (плюс), - (минус), * (умножение), / (целочис-


ленное деление), МОП {остаток от деления). Они выполняют соответствующие
арифметические действия,
поу — а1.90 под 7 ‚ ПоУ а1,6
‘Кроме того, к арифметическим операторам относится унарный минус - минус,
который ставят перед отрицательным числом.
Логические операторы: АМО (И), МОТ (НЕ), ОВ (ИЛИ), ХОБ (исключающее
ИЛИ), 5НЕ (сдвиг влево), ЗНК (сдвиг вправо). Эти операторы выполняют соот-
ветствующие логические действия.
мо\ ах, 12345 АМО 43218 ; тоу ах, 02201
Операторы сравнения: ЕО (равно), СЕ (больше или равно), СТ (больше), ГЕ
(меньше или равно), Г.Т (меньше), МЕ (не равно). Результат действия каждого из этих
операторов -- единица, если условие выполняется, и ноль - &сли не выполняется.
.еггп2 $ 9% 65535 | | ; Если адрес больше 64 Кб - ошибка.

Операторы адресации:
о$ЕС выражение — сегментный адрес;
о ОЕЕРЪЕТ выражение — смещение;
аТН!$ тин - текущий адрес (МАЗМ и ТА$М);
Выражения
Отип РТК выражение - переопределение типа; . ,
ОГАКСЕ выражение - 32-битное смещение (ТАЗМ и \АЗМ),;.
‚Э$МАШ. выражение - 16-битное смещение (ТАЗМ и \МА$М); `
о5НОКТ выражение - 8-битное смещение.
ЗЕС и ОЕЕЗЕТ возвращают соответствующую часть адреса своего аргумента:
поу 9х, оЁЁзет пзд ; Занести в ОХ ‘смещение переменной пз9.

ТНГ$ создает операнд, адресом которого является текущее значение счетчика:


моу а1, 111$ Буте-1 | ; Занести в АХ последний байт кода
у ; предыдущей команды.

РТК создает аргумент, адресом которого является значение выражения; а тип


указан явно: |
оу Чиога рег [$1],0 ; Записать 4 байта нулей по адресу 05:51.

ГАВСЕ, 5МАЦ. и $НОКВТ используются с командами передачи управления,


если возникают двусмысленности при косвенных переходах:
тр ]Лагде дмогд рег 019_а09гезз
: Переменная 019_а49гезз содержит 32-битное смещение:
Эр $та1] дмог@ ртг о19_а99гез$
Переменная 014_а@4гез$ содержит 16-битный сегментный адрес
и 16-битное смещение.
тр ПОГ ЗПогЕ_1аЪе1 _ ; Метка зпогт_1абе] находится
ближе, чем +128/-127 байт от этой команды, так что можно
использовать короткую форму команды МР. , й

Другие операторы:
О. (точка) — ссылка на элемент структуры; ° '
О: (двоеточие) — переопределение сегмента;
9 Оутловые скобки) — косвенная адресация;
О? - неинициализированное значение;
О число РОР (значение) — повторяющееся значение.
Эти пять операторов описаны ранее, когда говорилось в`е?руктурах данных,
методах адресации и псевдокомандах определения данных.
`

ТЕМСТН метка - число элементов данных


таб1е [1 0.1,2,3,4,5,6,7 `; Определить таблицу; из 8 слов.
таб1е_соийт = 1епоти табле `_ ; табе_соипе =. 8
ЗЕ метка - размер данных
табЛе_з12е = 312е ха ]е ; табе_з12е = 16

3.5. Макроопределения
Одно из самых мощных языковых средств ассемблера — макроопределения.
Макроопределением (или макросом) называется участок программы, которому
присвоено имя и который ассемблируется всякий раз, когда ассемблер встречает
11 Директивы и операторы ассемблера
ы.
Макрос начинается
это имя в тексте программ директивой МАСКО и заканчи-
- вается ЕМОМ. Например; пусть описано макроопределениеВех2азси, переводя-
щее шестнадцатеричное число, находящееся в регистре АТ, в АЗСП-код соответ-
ствующей шестнадцатеричной цифры:
Вех2а3с11 масго
стр а], 10
$66 а1, 69®
да$
епдт

Сейчас в программе можно использовать слово Вех2азсй, как если бы это было
имя команды, и ассемблер заменит каждое такое слово на три команды, содер-`
жащиеся в макроопределении. Разумеется, можно оформить этот же участок кода
в виде процедуры и вызывать его командой САМ. - если процедура вызывается
болыше одного раза, этот вариант программы займет меньше места, но вариант
с макроопределением станет выполняться быстрее, так как в нем не будет лиш-
них команд САЦ. и ВЕТ. Однако скорость выподнения — неглавное преимуще-
ство макросов. В отличие от процедур макроопределения могут вызываться
с параметрами, следовательно, в зависимости от ситуации, включаемый код бу-
дет немного различаться, например:
з_моу тасго гед1зтег1, гед1 тега
риз! ° гед1зфег1
` рор гед15Тег2
епат

Теперь можно. использовать $_МОУ вместо команды МОУ для того, чтобы
скопировать значение из одного сегментного регистра в другой. , |
Следующее важное средство, использую щееся в макроопре делениях, — дирек-
тивы условного ассемблирования. Например: напишем макрос, выполияющий:
умножение регистра АХ на число, причем, если множитель — степень двойки, то
умножение будет выполняться более быстрой командой сдвига влево.
Таз{_ми]1 пасго пипрег
и питбег ед 2 .
$11 ах, 1 ; Умножение на 2. : .
е1зе1Г' питбег е4 4° |
$81 ах, 2 ; Умножение на 4.
е1зе1Р' пишбег ед 8 —
$11 ах, 3 ; Умножение на 8.
... ; Аналогично вплоть до:
е13е17' питьег ед 32768
$11 ах, 15 ; Умножение на 2*.
е}зе | . ы
мо ах, питбег ‚ Умножение на число, не являющееся
_ пи} 9х `_; степенью двойки. .
епо1!`
епдт
Макроопределения. 2 НА ОО ИНЕТЕ
Можно, конечно, усложнить этот макрос, применяя особые свойства команды `
ГЕА и ее комбинации, сдвиги и сложения, однако в нынешнем виде он чрезмерно
громаздкий. Проблема решается с помощью третьего срёдства, постоянно исполь-
зующегося в макросах, — блоков повторений. `

3.5.1. Блоки повторений


Простейший блок повторений ВЕРТ (не поддерживается УАЗ М) выполняет.
ассемблирование участка программы заданное число раз. Например, если требу-
ется создать массив байтов, проинициализированный значениями от 0 до ОРЕК,
это можно сделать путем повтора псевдокоманды ОВ следующим образом:
зехпитбег =0 |
зехта1е ]абе] Буе ; Имя массива.
герт 256 | : ; Начало блока.
[6 пехпитбег ; Эти две строки ассемблируются
=ехпишБег = Вехпитбег+1 ; 256 раз.
епдт

Блоки повторений, так же как макроопределения, могут вызываться с парамет-


рами. Для этого используются директивы 1ВР и [ВРС:
1гр параметр, <значение1 , значение?...> ,

ейдт

1грс параметр, строка

епат

Блок, описанный директивой [ЕР будет вызываться столько раз, сколько зна-
чений указано в списке (в угловых скобках), и при каждом повторении будет оп-
ределена метка с именем параметр, равная очередному значению из слиска. На-
пример, следующий блок повторений сохранит в стек регистры АХ, ВХ, СХирхХ:
1гр гед, <ах, 5х, сх, Чх>
риузй гед
епдм

Директива {ВРС (РОВС в У\А$М) описывает блок; который выполняется


столько раз, сколько символов. содержит указанная строка, и при каждом повто-
рении будет определена метка с именем параметр, равная очередному символу
из строки. Если строка содержит пробелы или другие символы, отличные от раз-
решенных для меток, она должна быть заключена в угловые скобки: Например,
следующий блок задает строку в памяти, располагая после каждого символа стро-
‚ ки атрибут ОЕЪ (белый символ на черном фоне), так что этустроку впоследствии
можно будет скопировать прямо в видеопамять.
1грс спагастег, <строка’_символов>
46 '&спагастег&’, ОЕВ
епдт
_ПЕЕМИИНИИИНИИН! ——Директивы и операторы ассемблера
В этом примере используются амперсанды, чтобы вместо параметра сБагасбег
было подставлено его значение даже внутри кавычек. Амперсанд — это один из
макрооператоров — специальных операторов, которые действуют только внутри
макроопределений и блоков повторений.

3.5.2. Макрооператоры
Макрооператор & (амперсанд) нужен для того, чтобы параметр, переданный
в качестве операнда макроопределению или блоку повторений, заменялся значе-
нием до обработки строки ассемблером. Так, например, следующий макрос выпол-
нит команду РОЗН ЕАХ, если его вызвать как РОЗНКЕС А:
ризпгед. тасго 1е{ег
ризй ° её1етег&х
епат | |

Иногда можно использовать только один амперсанд— в начале параметра, если


не возникает неоднозначностей. Например, если передается номер, а требуется
создать набор переменных с именами, оканчивающимися этим номером:

1гр питьег, <1,2,3, 4>


тза&питбег К°) ?
епт ^

Макрооператор <> (угловые скобки) действует так, что весь текст, заключен-
ный в эти скобки, рассматривается как текстовая строка, даже если он содержит
пробелы или другие разделители. Как мы уже видели, этот макрооператор ис-
пользуется при передаче текстовых строк в качестве параметров для макросов.
Другое частое применение угловых скобок - передача списка параметров вложен-
ному макроопределению или блоку повторений.
Макрооператор 1 (восклицательный знак) используется аналогично угловым
скобкам, но действует только на один следующий символ, так что, если этот сим-
вол — запятая или угловая скобка, он все равно будет передан макросу как часть
параметра.
Макрооператор % (процент) указывает, что находящийся за ним текст являет-
ся выражением и должен быть вычислен. Обычно это требуется для того, чтобы
передавать в качестве параметра в макрос не само: выражение, а его результат.
Макрооператор;; (две точки с запятой)— начало макрокоммеитария. В отли-
чие от обычных комментариев текст макрокомментария не попадает в листинг
и в текст программы при подстановке макроса. Это сэкономит память при ассем-
блировании программы с большим количеством макроопределений.

3.5.3. Другие директивы, используемые в макроопределениях


Директива ЕХТМ (не поддерживается \МА$М) выполняет преждевременный _
выход из макроопределения или блока повторений. Например, следующее ма-
кроопределение не выполнит никаких действий, то есть не будет расширено в ко-
манды процессора, если параметр не указан:
Другие директивы
ризпгед масго гед
116 <гед>
ех1 {т
епо1Е
ризй гед
епат

ГОСАТ, метка... - перечисляет метки, которые будут применяться внутри мак-


роопределения, чтобы не возникало ошибки «метка уже определена» при исполь-
зовании макроса более одного раза или если`та же метка присутствует в основном
тексте программы (в \/АЗМ директива ГОСАТ,. позволяет использовать макрос
с метками несколько раз, но не разрешает применять меткус тем же именем в про-
грамме). Операнд для ГОСАТ, - метка или список меток, которые будут исполь-
зоваться в макросе.
РОВСЕ имя_макроса — отменяет определенный ранее макрос (не поддержива-
ется \МА$М). Эта директива часто применяется сразу после ПМСГОПЕ, включив-
шей в текст программы файл с большим количеством готовых макроопределений.

3.6. Другие директивы


3.6.1. Управление файлами
ПУСГОПЕ имя_файла — директива, вставляющая в текст программы текст
файла аналогично команде препроцессора С #тси4е. Обычно используется для`
включения файлов, содержащих определения констант, структур и макросов.
ПУСГОБЕНВ имя_файла - директива, указывающая компоновщику имя до-.
полнительной библиотеки или объектного файла, который потребуется при со-
ставлении данной программы. Например, если используются вызовы процедур
или обращение к данным, определенным в других модулях. Использование этой
директивы позволяет не указывать имена дополнительных библиотек при вызове
компоновщика.

3.6.2. Управление листингом


Обычно ассемблёры, помимо создания объектного файла, предоставляют воз-
можность создания листинга программы (ТА$М /Т. - для ТАЗМ, ш] /Е! - для
МАЗМ). Листинг — это файл, содержащий текст ассемблерной программы, код
каждой ассемблированной команды, список определенных меток, перекрестных
ссылок, сегментов и групп. Формат файла листинга отличается для разных ассем-
блеров, и директивы управления форматом этого файла также сильно различа-
ются, но несколько наиболее общих директив все- таки поддерживаются ‹всеми
тремя ассемблерами, рассмотренными в этой книге.
ОТГТГЕ текст — ‘определяет заголовок листинга. Заголовок появляется в на-
чале каждой страницы; |
9 5ОВТТ!, текст - определяет подзаголовок листинга. Подзаголовок появля-
ется на следующей строке после заголовка;
РНИ
ТИ И Директивы и операторы ассемблера _

ОРАСЕ высота,ширина - устанавливает размеры страниц листинга (высота


10-255, ширина 59-255). Директива РАСЕ без аргументов начинает новую
страницу, директива РАСЕ + начинает новую секцию, и нумерация страниц
ведется с самого начала;
ОМАМЕ текст- определяет имя модуля программы. Если МАМЕ не указан,
в качестве имени используются первые 6 символов из ТТТЕЕ; если нет ни
МАМЕ, ни ТГТГЕ, за имя берется название файла;
о.ХЫ$Т - отменить выдачу листинга; |
о.М$Т- разрешить выдачу листинга;
с.бАГ1. - запретить листинг макроопределений;
о:5ЕСОМО - запретить листинг неассемблированных условных блоков;
о.ГЕСОМЮ- разрешить листинг неассемблированных условных блоков;
о .ТЕСОЮЮ - изменить режим листинга условных блоков на противоположный;
@.СКВЕЕ - разрешить листинг нерекрестных ссылок;
о.ХСКЕЕ- запретить листинг перекрестных ссылок.

3.6.3. Комментарии
Кроме обычных комментариев, начинающихся с символа; {точка с запятой)
‘и заканчивающихся в конце строки, возможны большие блоки комментариев,
‘описываемых специальной директивой СОММЕМТ.
соттепт @
любой текст
@

Операнд для СОММЕКМТ- любой символ, который будет считаться концом


комментария. Весь участок текста, вплоть до следующего появления этого симво-
ла, ассемблером полностью игнорируется.
.

Глава 4. Основы программирования


для М$ 00$ о
Программа, написанная на ассемблере, так же как и программа, написанная на лю-
бом другом языке программирования, выполняется не сама по себе, а при помощи
операционной системы, Операционная система выделяет области памяти для про-
граммы, загружает ее, передает ее управление и обеспечивает взаимодействие про-
граммы с устройствами ввода-вывода, файловыми системами и другими программа-
ми (разумеется, кроме тех случаев, когда эта программа сама является операционной
системой или ее частью). Способы взаимодействия программы с внешним миром
различны для разных операционных систем, поэтому программа, написанная для
\УИпдо\з, не будет работать в РО$, а программа для.Гпих — в 501а115/х86, хотя все
указанные системы могут работать на одном и том же компьютере.
Самая простая и распространенная операционная система для компьютеров,
основанных на процессорах 11, - ОО$ (дисковая операционная система). Она
распространяется как сама.по себе несколькими производителями — М1сгозой
(М$ 20$), 1ВМ (РС-РО$), МоуеЙ (Моуе! РО$), Саега (Ореп РО5) и др., так
и в виде части систем М1сгозой УЛп4о\ 95 и старше. ОО$ предоставляет програм-
мам полную свободу действий, никак не ограничивая доступ к памяти и внешним
устройствам, позволяя им самим управлять процессором и распределением памяти.
По этой причине система лучше всего подходит для того, чтобы основательно
познакомиться с устройством компьютера и возможностями программы ня ассем-
блере, но которые часто скрываются компиляторами с языков высокого уровня
и более совершенными операционными системами.
Итак, чтобы программа выполнилась любой ОС, она должна быть скомпилиро-
вана в исполняемый файл. Основные два формата исполняемых файлов в РО$ —
СОМ иЕ}ХЕ. Файлы типа СОМ содержат только скомпилированный код без ка-
кой-либо дополнительной информации о программе. Весь код, данные и стек та-
кой программы располагаются в одном сегменте и не могут превышать 64 Кб.
Файлы типа ЕХЕ содержат заголовок, где описывается размер файла, требуемый
объем памяти, спиеок команд .в программе, использующих абсолютные адреса,
которые зависят от расположения программы в памяти,и т. д. ЕХЕ-файл может
иметь любой размер. Формат ЕХЕ также используется для исполняемых файлов
в различных версиях РО5-расширителей и УЯпдо\хз, но с большими изменениями.

@® Несмотря на то что`файлам типа СОМ принято давать расширение ‚сот,


а файлам типа ЕХЕ - ‚ехе, ОО$ не использует расширения для определе-
ния типа файла. Первые два байта заголовка ЕХЕ-файла - символы «М2»
ЮЗИИШИИШИИИИИИ | Основы программирования для М$`00$
| или «2М», и если файл начинается с них и длиннее некоторого порогового
значения, отличающегося в разных версиях ОО$5, он загружается как ЕХЕЁ,
если нет - как СОМ.

Кроме обычных исполняемых программ ОО$ может загружать драйверы уст-


ройств — специальные программы, используемые для упрощения доступа к вне-
шним устройствам. Например,‘ драйвер устройства Г.РТ, входящий в 1О.5У$, по-
зволяет посылать тексты на печать из ОО5 простым копированием файла в ГРТ,
а драйвер КАМО]$К.$У$ разрешает выделить область памяти и обращаться к ней,
как к диску. Написание драйверов значительно сложнее, чем написание обычных
программ (см. далее). ”

4.1. Программа типа СОМ


Традиционно первая программа для освоения нового языка программирования —
программа, выводящая на экран текст Не{о уог4!. Не будет исключением и эта
книга, поскольку такая программа всегда являлась удобной отправной точкой для
дальнейшего освоения языка.
Итак, наберите в любом текстовом редакторе, который может записывать файлы
как обычный текст (например: ЕОТТ.СОМ в 2О$5, встроенный редактор в Мопоп
Сотитанаег или аналогичной программе, МОТЕРАО в УЙпдо\5), следующий текст:
; 1е110-1.аэт '
; Выводит на экран сообщение ”Не]1о Мог14!” и завершается.
.1о9е] ^ {1пу ; Модель памяти, используемая для СОМ.
.соде ‚; Начало сегмента кода.
огд 1001 ; Начальное значение счетчика - 1001.
ЗТагт: моу- ап, 9 и о” ; Номер функции 005 - в АН.
. : ОУ 9х, оРРзеЕ теззаде ‚ Адрес строки - в ВХ.
11 21 | ; Вызов системной функции 90$.
ге . ; Завершение СОМ-программы.
пеззаде [ее] “Не11о ма! ", ООН, АВ, ' $' ; Строка для вывода.
епа эТаге ‚ Конец программы.

и сохраните его как файл ВеПо-1.азт. Можно также использовать готовый файл
с этим именем. (Все программы, рассмотренные в этой книге как примеры, вы мо-
жете найти в. Пцегпеё по адресу: //м
Вр: лум Чти К,ги.)
‚ Для превращения программы в исполняемый файл сначала надо вызвать ас-
семблер, чтобы скомпилировать ее в объектный файл с именем ВеПо-1.05}, набрав
в командной строке следующую команду:
Для ТАЗМ:
Тазт Не110-1.азт

Для МАЗМ:
т] /с 1е]1о-1.азм

Для \А$М:
имазт пе110-1.азт
Программа типа СОМ. И ПВН ИО ПОИОИНЕР]
С ассемблерными программами также можно работать из интегрированных
сред разработки, как обычно поступают с языками высокого уровня. Но в них, как
правило, удобнее создавать. ассемблерные процедуры, вызываемые из ‘программ
на языке, для которого предназначена среда, а создание полноценных программ
на ассемблере требует некоторой перенастройки. -
Формат объектных файлов, применяе мых всеми тремя рассматриваемыми ас-
семблерами по умолчанию (ОМЕ-формат), совпадает, так что можно пользоватЬ-
ся ассемблером из одного пакета и компоновщиком из другого.
Для ТАЗМ:
пк /Е /х пе110-1.05) . .

Для МАЗМ (команда ШиК должна вызывать 16-битную версию ИМКЕХЕ):


ак Не110-1.063,,М№%,,, |
ехе261п Не110-1.ехе пе110-1. сот

Для \МАЗМ:
мик Ре ве110-1.05] Тоги 00$ С0М

Теперь получился файл НЕГО-1.СОМ размером 23 байта. Если его выпол-


нить, на экране появится строка Нейо \\о!@! и программа завершится. ,
Рассмотрим исходный текст программы , чтобы понять, как она работает.
Первая строка определяет модель памяти ТПМУ, в которой сегменты кода, дан-
ных и стека объединены. Эта модель предназначена для создания файлов типа СОМ.
Директива .СОПЕ начинает сегмент кода, который в нашем случае также дол-
жен содержать и данные.
ОВС 1001 устанавливает значение программного счетчика в 1001, потому что
при загрузке СОМ-файла в память РОЗ занимает первые 256 байт (1001) бло-
ком данных Р$Р и располагает код программы только после этого блока. Все про-
граммы, которые компилируются в файлы типа СОМ, должны начинаться с этой
директивы. _
Метка ЗТАВТ располагается перед первой командой в программе и будет исполь-
зоваться в директиве ЕМО, чтобы указать, с какой команды начинается программа.
Команда МОУ АН,9 помещает число 9 в регистр АН - номер функции РО$ «вы-
вод строки». |
Команда МОУ ОХ, ОЕЕЗЕТ МЕЗЗАСЕ помещает в регистр РХ смещение мет-
_ки МЕЗЗАСЕ относительно начала сегмента данных, который в нашем случае
совпадает с сегментом кода. ,
Команда ПМТ 21В вызывает системную функцию РОЗ. Эта команда — основ-
ное средство взаимодействия программ с операционной системой. В нашем при-
мере вызывается функция РОЗ номер 9 — вывести строку на экран. Эта функция
выводит строку от начала, адрес которото задается в регистрах О$:Х, до первого
встреченного символа $. При запуске СОМ-файла регистр 25 автоматически за-.
гружается сегментным адресом программы, а регистр ОХ был подготовлен пре-
дыдущей командой. И | .
Команда ВЕТ используется обычно для возвращен ия из процедуры . 005 вы-
зывает СОМ-программы так, что команда ВЕТ корректно завершает программу.

5 Зак. 459
|} Основы программирования для М$ 20$

@& РО5 при вызове-СОМ. -файла помещает в стек сегментный адрес программы
и ноль, так что ВЕТ передает управление на нулевой адрес текущего сегмен-
та, то есть на первый байт Р5Р. Там находится код команды 1МТ 201, кото-
рая и используется для возвращения управления в РО$. Можно сразу закан-`
чивать программу командой МТ 20%, хотя это длиннее на 1 байт.

Следующая строка программы НЕГО-1.А$М определяет строку данных, со-


держащую текст НеПо \о! 41, управляющий символ А$СИ возврат каретки с ко-
дом ОО, управляющий символ АЗСИ перевод строки с кодом ОАВ и символ $,
завершающий строку. Эти два управляющих символа переводят курсор на пер-
вую позицию следующей строки точно так же, как в строках на языке С действует
последовательность \п.
И наконец, директива ЕМО завершает программу, одновременно указывая, с ка-
кой метки должно начинаться ее выполнение.

4,2. Программа типа ЕХЕ


ЕХЕ-программы немного сложнее в исполнении, но для них отсутствует огра-
ничение размера в 64 Кб, так что все достаточно большие программы используют
именно этот формат. Конечно, ассемблер позволяет уместить и в.64 Кб весьма
сложные и большие алгоритмы, а все данные хранить в отдельных файлах, но ог-
раничение размера все равно очень серьезно, и даже чисто ассемблерные програм-
мы могут с ним сталкиваться. .
; 1е110-2.азм
; Выводит на’ экран сообщение “Не]110 №14!” и завершается.
.по4е1 та! ; Модель памяти, используемая для ЕХЕ.
‚ЗТаск 1008 ; Сегмент стека ‘размером в 256 байт.
. соде . | '
Зфаг{: поу ах, ОбАОУР ; Сегментный адрес строки меззаде
тоу 93, ах ‚ помещается в 0$.
мо 9х, оРзет меззаде
оу ав, 9 .
111 218 ; Функция 00$ “вывод. строки”.
тому ах, 4С00Н |
11 218. ; Функция 005 “завершить программу“.
. дата |
пеззаде а “Не!10 Мог19!”,
00В, АН, '$'
епд этаге

В этом примере определяются трисегмента — сегмент стека директивой ЗТАСК


. размером в 256 байт; сегмент кода, начинающийся с директивы СООЕ; и сегмент
данных, начинающийся с .ОАТА и включающий строку, При запуске ЕХЕ-програм-
мы регистр 0$ уже не содержит адреса сегмента со строкой теззаяе (он указывает
на сегмент с блоком данных Р$Р), а для вызова используемой функции 2О$ этот
регистр должен иметь сегментный адрес строки. Команда МОУ АХ,ОСКВОТР за-
` гружаетв АХ сегментный адрес группы сегментов данных ОСКОЧР а МОУ О$,АХ
Программа типа ЕХЕ с \ ООС
копирует его в 0$. Для ассемблеров МАЗМ и ТАЗМ вместо ОСКОТР можно ис-
пользовать предопределенную метку @4аца, но единственная модель памяти, в ко-
торой группа сегментов данных называется иначе,—ЕГАТ (ей мы пока пользовать-
ся не будем). И наконец, программы типа ЕХЕ должны завершаться системным
вызовом РО$ 4СЪ: в регистр АН помещается значение 4СЪ, в регистр АГ.— код воз-
врата (в данном примере код возврата 0 и регистры АН и А!. загружаются одной
командой МОУ АХ,4С00Ъ), после чего вызывается прерывание 21.

Компиляция Нео-2.азт.
Для ТАЗМ:
тазт Ве110-2. азт
нак Их ве110-2.00)
Размер получаемого файла ео-2.ехе — 559 байт.
Для МАЗМ:
21 /с 1е110-2. азм
ик ве110-2.06}
Размер получаемого файла ВеПо-2.ехе — 545 байт.
Для \А$М:
«азт Пе110-2. азт |
«ик Ее 1пе110-2.06] Рогт 60$
Размер получаемого файла Вео-2.ехе - 81 байт: ,
Расхождения в размерах файлов вызваны различными соглашениями о вырав-
нивании сегментов программы по умолчанию. Почти все примеры программ для
РО$ в этой книге рассчитаны на компиляцию в СОМ-файлы, так как идеология
работы с памятью в них во многом. совпадает с идеологией, используемой при
программировании под расширители РО$, ЭРМ! и УЛпдо\.

4.3. Вывод на экран в текстовом режиме


4.3. Средства 205, = ,
На примере первой ассемблерной программы мы уже познакомились с одним
из способов вывода текста на-экран— вызовом функции РО$ 09}. Это далеко не
единственный способ вывода текста —- ОО5 предоставляет для этого несколько
функций. у -

Функция 2О$ 021: Записать символ в ЗТРОТТ с проверкой на Сы1-ВгеаК


Вход: АН= 025
ОГ, = АЗСП-код символа
Выход: Никакого, согласно документации, но на самом деле: .
АГ. = код последнего записанного символа (равен ОТ, кроме случая,
когда ОГ.= 09} (табуляция), тогда-в АТ возвращается 201).
Данная функция обрабатывает некоторые управляющие символы: при выводе
символа. ВЕГ. (071) появляется звуковой сигнал, посредством В$ (088) курсор
. КЕРЗИШШШИШИШИИИ Основы программирования для М$ 20$
`перемещается влево на одну позицию, символ НТ (091) используется для замены
на несколько пробелов, символ Г.Е (ОАБ) — для перевода курсора на одну пози-
цию вниз, а СВ (0) - для перехода на начало текущей строки.
Если в ходе работы этой функции была нажата комбинация клавиш СЫ1-
Вгеак, вызывается прерывание 23}, которое по умолчанию осуществляет выход
из программы.
Например, напишем программу, выводящую на экран все АЗСП-символы,
16 строк по 16 символов в строке.
; 9030и{1.азм
‚ Выводит на экран все АЗСТТ-символы

.0де1 {1пу
. соде у
0г9 100Н ; Начало СОМ-файла.
зФагт:
по\ сх; 256 Вывести 256 символов.
оу 91,0 Первый символ - с кодом 00.
тоу ав, 2 Номер функции 00$ “вывод символа“.
- 6100р: 111 218 Вызов 00$. -. ,
1пс 91 ; Увеличение ОЁ на 1`- следующий символ,.
тезт -91, ОЕ ; Если 01 не кратен 16, р
7072 соп1пче_1оор ; продолжить цикл.
| ризй 9х ! ; Иначе: сохранить текущий символ,
тому „. 91,001 ‚ вывести СВ,
117 21н . ` ”
оу 91, ОАЙ ; вывести (Е, / `
ит 2 :
рор 9х — ‚ восстановить текущий символ,
соп1пие_1оор:
1оор с1оор ‚ продолжить цикл.
гет ; Завершение СОМ-файла.
епд зтаге °
Это программа типа СОМ, и компилироваться она должна точно так же, как
ВеПо-1.азт из раздела 4.1. Здесь с помощью команды ГООР оформляется цикл,
выполняющийся 256 раз (значение регистра СХ в начале цикла). Регистр Г]. со-
держит код символа, который равен нулю в начале цикла и увеличивается каж-
дый раз на 1 командой ПМС РТ. Если значение ОТ. сразу после увеличения на 1
кратно 16, оно временно сохраняется в стеке и на экран выводятея символы СК
и ГЕ выполняющие переход на начало новой строки. Проверка осуществляется
командой ТЕЗТ ОГ.0ЕВ - результат операции АМЮ над ОТ. и 0ЕВ= 0, только есди
младшие четыре бита ОТ. равны нулю, что и соответствует кратности шестнаднахи.
Все функции 2О$ вывода на экран используют устройство 5ТРОТТ, стандар-
тный вывод. Это позволяет перенаправлять вывод программы в файл или на стан-
дартный ввод другой программы. Например, если написать в командной строке
1е110-1.сот > Пе110-1. оч{
Вывод на экран в текстовом режиме _ МММ
то на экране ничего не появится, а в текущей директории появится файл Бео-
1.01, содержащий строку Нео \Уой1. Точно так же, если написать

3030и%11.сот > 40$0и11.0и1т

то в файле 4озоц1 оц окажутся все символы АЗСИ, причем символы ВЕГ.и В$ не


будут интерпретироваться и запишутся в файл как есть. Символы СВ. и [Е тоже
запишутся как есть, но поскольку они отмечают конец строки, редакторы и про-
смотрщики текстовых файлов будут разрывать первую строку символов.
Функция 205 061: Записать символ в ЗТРОТТ без проверки на СЫ1-ВгеаК
Вход: АН = 06 |
ОГ. = АЗСП-код символа (кроме ОЕЕБ)
Выход: Никакого, согласно документации, но на самом деле:
АГ. = код записанного символа (копия ПОГ.)
Эта функция не обрабатывает управляющие символы (СК, ГЕ НТ и В5$ вы-
полняют свои функции при выводе на экран, но сохраняются при перенаправле-
нии вывода в файл) и не проверяет нажатие СЫ1-ВгеаК. Можно заменить МОУ
АН,2 командой МОУ АН,6 в программе 403011 .азт и перекомпилировать этот
пример, чтобы получить более полную таблицу символов.
Функция 205 09#: Записать строку в ЭТООТТ с проверкой на СЫ]-ВгеаК
Вход: АН = 09 |
05$:ОХ = адрес строки, заканчивающейся символом $ (248)
Выход: Никакого, согласно документации, но на самом деле:
АЦ = 2АЬ (код последнего символа)
Действие этой функции полностью аналогично действию функции 02, но вы-
водится не один символ, а целая строка, как в программах Вео-1азт и ВеПо-2.азт.
Функция 2О5 401: Записать в файл или устройство
Вход: АН = 40,
ВХ = 1 для ЗТООТТ или 2 для 5ТРЕВК ,
05:0Х= адрес начала строки |
СХ= длина строки
Выход: СЕ= 0,
АХ = число записанных байтов
Эта функция предназначена для записи в файл, но, если в регистр ВХ поместить
число 1, функция 401 будет выводить данные на ЗТРОТТ, а если ВХ = 2 - на уст-
ройство ЗТОЕКК. Оно всегда выводит данные на экран ий не перенаправляется
в файлы. На РО$ 40 основаны используемые в С функции стандартного вывода —
фактически функция С ри65() просто вызывает это прерывание, помещая свой
первый аргумент в ВХ, адрес строки (второй, аргумент)— в О5:ОХ и длину- в СХ.
; 9030012. аз
‚ Выводит на экран строку "Эта функция может вывозить знак $”,
; используя вывод в 'ЭТОЕВВ, так что ее нельзя перенаправить в файл.
ЕЕГИИИИИИИ Основы программирования для М$ 205
.по4е1 Т1пу
. соде |
0гд 1000 ; Начало СОМ-файла.
этаге: °
мо ан, 401 ‚ Номер функции 00$. ‘
том ‚ бх,2 ; Устройство УТОЕВВ. |
то\у 9х, оРРзет `теззавде | ; 05:0Х - адрес строки.
Юм сх, теззаде_1епдтп ; СХ - длина строки. '
ии 218 -
ге ; Завершение СОМ-файла.
меззаде 94 — "Эта. функция может выводить знак $”
теззаде_1]елдт! = $-теззаде ; Длина строки = текущий’ адрес минус,
| ; адрес начала строки.
епд таг

Если скомпилировать эту программу и запустить ее командой


9030112. сот > 903012. ит

то сообщение появится на экране, а файл 405$0и%2.0щ окажется пустым.


И наконец, последняя функция ОО$ вывода на экран — недокументированное
прерывание 29},
1№Т 297: Быстрый вывод символа на экран
Вход: — АГ. = АЗСИ-код символа
В большинстве случаев ПМТ 291 немедленно вызывает функцию В1О$ «вы-
вод символа на экран в режиме телетайпа», поэтому никаких преимуществ, кро-
ме экономии байтов при написании как можно более коротких программ, она не
имеет. |

4.3.2. Средства В!О$ `-


Функции 2О$ вывода на экран позволяют перенаправлять вывод.
= В файл, но
не дают возможности вывести текст в любую позицию экрана и не разрешают из-
менить цвет текста. РОЗ предполагает, что для более тонкой работы с экраном
программы должны использоваться видеофункции ВГО$. ВТО$5 (базовая система
ввода-вывода) - это набор программ, расположенных. в постоянной памяти ком-
пьютера, которые выполняют его загрузку сразу после включения и обеспечива-
ют доступ к отдельным устройствам, в частности к видеоадаптеру. Все функции
видеосервиса В1О$ вызываются через прерывание 10%. Рассмотрим функции, ко-
торые могут быть полезны для вывода текстов на экран.
Выбор видеорежима
ВГО$ позволяет нереключать экран в различные текстовые и графические
режимы. Режимы отличаются друг от друга разрешением (для графических) и ко-
личеством строк и столбцов (для текстовых), а также количеством возможных
цветов.
Вывод на экран в текстовом режиме т: 1 135.
ГУТ 10Р, АН = 008: Установить видеорежим
Вход: —АН= 00
А!.= номер режима в младших 7 битах
Вызов этой функции приводит к тому, что экран переводится в выбранный
режим. Если старший бит АТ. не установлен в 1, экран очищается. Номера тексто-
вых режимов - 0, 1, 2, Зи7. 0 и 1 — 16-цветные режимы 40х25 (с 25 строками по
40 символов в строке), 2 и 3 - 16-цветные режимы 80х25, 7 — монохромный ре-
жим 80х25. Мы не будем пока рассматривать графические режимы, хотя функ-
ции вывода текста на экран РО$ и В1О5 могут работать и в них. Существуют и дру-
гие текстовые режимы с более высоким разрешением (80х43, 80х60, 132х50 и т. д.),
но их номера для вызова через эту функцию отличаются для разных видеоадапте-
ров (например, режим 61В - 132х50 для Ситиз 5320 и 132х29 для Сепоа 6400).
Однако, если видеоадаптер поддерживает стандарт УЕЗА В1О0$ Ежеп@оп, в режи-
мы с высоким разрешением можно переключаться, используя функцию АЕБ. .
ГУТ 108, АН = 4Е, АЕ = 028: Установить видеорежим ЗирегУСА
Вход: АХ = 4Е02Ь
ВХ - номер режима в младших 13 битах
Если бит 15 регистра ВХ установлен в 1, видеопамять не очищается. Тексто-
вые режимы, которые можно вызвать с использованием этой функции: 80х60 (ре-
жим 108), 132х25 (109Ъ), 132х43 (10АЪ), 132х50 (10ВВ), 132х60 (10СЬ).
Видеорежим, используемый в РО$ по умолчанию, - текстовый режим 3.
Управление положением курсора
Т№Т 104, АН = 028: Установить положение курсора
Вход: АН = 026
ВН = номер страницы
ОН = строка ‘'
ОТ. = столбец
С помощью этой функции можно установить курсор в любую позицию экра-
на, и дальнейший вывод текста будет происходить из этой позиции. Отсчет номе-
ра строки и столбца ведется от верхнего левого угла экрана (символ в левой вер-
хней позиции имеет координаты 0, 0). Номера страниц 0-3 (для режимов 2 и 3)
и 0-7 (для режимов 0и 1) соответствуют области памяти, содержимое которой
в данный момент отображается на экране. Можно вывести текст в неактивную
в настоящий момент страницу, а затем переключиться на нее, чтобы изображение
изменилось мгновенно. |
ИМТ 10, АН - 031: Считать положение и размер курсора
Вход: АН = 03Ь
ВН = номер страницы
Выход: ОН, ПГ. = строка и столбец текущей позиции курсора
СН, СИ.= первая и последняя строки курсора
8111111 Основы программирования для М$ 2О$
Возвращает текущее состояние курсора на выбранной странице (каждая стра-
ница использует собственный независимый курсор).
Вывод символов на экран
Каждый символ на экране описывается двумя байтами — АЗСИ-кодом симво-
ла‘и байтом атрибута, указывающим цвет символа и фона, а также является ли
символ мигающим.
Атрибут символа
обит 7: символ мигает (по умолчанию) или фон яркого цвета (если его дей-
ствие было переопределено видеофункцией 101);
обиты 6-4: цвет фона;
О бит 3: символ яркого цвета (по умолчанию) или фон мигает (если его дей-
ствие было переопределено видеофункцией 111);
обиты 2-0: цвет символа.
„Цвета кодируются в битах, как показано в табл. 18.
МТ 101, АН = 08й;: Считать символ и атрибут символа в текущей позиции курсора
Вход: АН = 086
ВН =‘номер страницы
Выход: АН = атрибут символа
АТ, = АЗСП-код символа

ГМТ 10%, АН = 09#: Вывести символ с заданным атрибутом на экран


Вход: АН= 096 —
ВН = номер страницы
АТ. = АЗСП-код символа
ВИ. = атрибут символа. | .
СХ = число повторений символа
С помощью этой функции можно вывести на экран любой символ, включая
даже символы СК и ГЕ которые обычно интерпретируются как конец строки.
В графических режимах СХ не должен превышать число позиций, оставшееся до
правого края экрана.
ПМТ 101, АН = ОА: Вывести символ с текущим атрибутом на экран
Вхоя: (АН= ОА
ВН = номер страницы:
АТ. = АЗСП-код символа
СХ = число повторений символа
и

Эта функция также выводит любой символ на экран, но в качестве атрибута


символа используется атрибут, который имел символ, находившийся ранее в дан-
НОЙ ПОЗИЦИИ. р.
Вывод на экран в текстовом режиме _
Таблица 18. Атрибуты символов -

триб
0005 Черный Темно-серый ,
001 Синий Светло-синий
0105 Зеленый Светло-зеленый
01 16” -| Голубой Светло-голубой
1005 Красный у | Светло-красный
1015 Пуряурный Светло-пурпурный
1106 |Коричневый Желтый
1116 Светло-серый Белый

[МТ 101, АН = ОЕЁ: Вывести символ в режиме телетайпа


Вход: АН= 0ЕБ
ВН = номер страницы
АЕ = АЗСП-код символа
Символы СК. (00), Т.Е (0АВ), ВЕГ. (7) интерпретируются как управляющие
символы. Если текст при записи выходит за пределы нижней строки, экран про-
кручивается вверх. В качестве атрибута используется атрибут символа, находив-
щегося в данной позиции.
ТМТ ТОЙ, АН = 138: Вывести строку символов с заданными атрибутами
Вход: АН = 136
АТ. = режим вывода:
бит 0: переместить курсор-з конец, строки после вывода
бит 1: строка содержит не только символы, но и атрибуты, так что
каждый символ описывается двумя байтами: АЗСП-код
‘и атрибут я
биты 2-7: зарезервированы
СХ= длина строки (только число символов)
ВТ. = атрибут, если строка содержит только символы `
ОН, ПТ, = строка и столбец, начиная с которых будет выводиться строка
‚ ЕЗ:ВР = адрес начала строки в памяти
Функция 13Ъ выводит на экран строку символов, интерпретируя управляю-
щие символы СВ. (ООВ), Е.Е (0АБ), В$ (08) и ВЕТ. (07). Если строка подготовлена
в формате символ‚атрибут - гораздо быстрее просто скопировать ее в видеопа- ^
мять, о чем рассказано в следующей главе.
Воспользуемся теперь функциями В1О$5, чтобы усовершенствовать программу
РОЗОТЛ1 и вывести на экран все 256 символов, включая даже символы перевода
строки. Кроме того, для лучшей читаемости таблицы после каждого символа бу-
дет выводиться пробел.
ЕЕ ООО ОБИ ИИИ "|Основы программирования для М$ 00$
Ь1050ит.азт
‚ Выводит на экран все АЗСГ=символь без исключения.
,

.то4е1 Т1тпу
. соде
ог9 1008 ; Начало СОМ-файла.
5тагт;
_ № = ах, 00038
11 108 ; Видеорежим 3 (очистка экрана
‚ ; и установка курсора в. 0, 0).
моу 9х, 0 ; ОНи 01 будут использоваться
; для хранения положения курсора.
; Начальное положение - 0,0.
тоу 31,256 ; $Г будет счетчиком цикла.
поу а1,0 ; „Первый символ - с кодом 008
оу ап, 9 °; Номер видеофункции “вывод символа с атрибутом“
ше сх, 1 : Выводится один символ за раз.
пом Ь1, 000111116 ‚ Атрибут символа - белый на синем.

-с1оор:
1 108 ; Вывести символ на экран
рузй ах - ; Сохранить текущий символ и номер функции.
|
ед ан, 2 | ; Номер видеофункции 2 -
; изменить положение курсора.
Тис 9] ` | ; Увеличить текущий столбец на 1.
1 тон : Переместить курсор
том ах, 09201 ‚ АН = 09, А = 201 (АЗСТ]Т-код пробела)
17 ‚ 108 ; Вывести пробел,
тому ай, 2 ; Номер видеофункции2.
1пс 91 - ; Увеличить столбец на 1.
пт 10. ; Переместить курсор.
рор ах ; Восстановить номер функции в аб
: И текущий символ в а].
1пс а] ; Увеличить АЁ на 1 - следующий символ.
тезт а1, ОРВ ‚ Если АЁ не кратен 16,
82 ° сопЕ1пие_1оор
| ‚ продолжить цикл.`
ризв ах ; Иначе - сохранить номер функции
| ; и текущий символ. |
мо ап, 2 ‚ Номер видеофункции 2.
1пс ЧИ . ; Увеличить номер. строки на 1.
оу 91,0 ; Столбец = 0.
Ти. 101 ‚ Установить курсор на начало следующей строки.
рор ‚ ах | ‚ Восстановить номер видеофункции `
‚ И текущий символ.

соп1пие_10оор:
` дес $1 °; Уменьшить 5Т на 1.
. ‚ Если он не стал нулем - продолжить.
712 с1оор ; СХ используется внутри цикла,
Ра
Вывод на экран в текстовом режиме ТТ|! | 139.
; так что нельзя применить команду Е00Р
; для его организации.
гет ; Завершение СОМ-файла.
епа таг

Так как функция 09Ь выводит символ в позиции курсора, но не перемещает


сам курсор, это приходится делать каждый раз специально.
Функции ВТО$ удобны для переключения и настройки видеорежимов, но ча-
сто оказывается, что вывод текста на экран гораздо быстрее и проще ВЫПОЛНЯТЬ
обычным копированием изображения в видеопамять.

4.3.3. Прямая работа с видеопамятью


Все, что изображено на мониторе - и графика, и текст, одновременно присут-
ствует в памяти, встроенной в видеоадаптер. Чтобы изображение появилось на мо-
ниторе, оно должно быть записано в память видеоадаптера. Для этой цели отво-
` длится специальная область памяти, начинающаяся с абсолютного адреса
988001:0000Ъ (для текстовых режимов) и заканчивающаяся 0В800Ъ:0ЕЕЕЕЬ. Все,
что программы пишут в эту область памяти, немедленно пересылается в память
видеоадаптера. В текстовых режимах для хранения каждого изображенного сим-
вола используются два байта: байт с АЗСП-кодом символа и байт с его атрибутом,
так что по адресу 0В8001:0000№ лежит байт с кодом символа, находящимся в вер-
хнем левом углу экрана; по адресу 0В800}:0001Ь расположен атрибут этого сим-
вола; по адресу 0В8001:00028 - код второго символа в верхней строке экрана ит. д.,
Таким образом, любая программа может вывести текст на экран простой ко-
мандой пересылки данных, не прибегая ни к каким специальным функциям РОЗ
или ВОЗ. ,
91гоцт. аз
Выводит на экран все АЗСТТ-символы без исключения,
используя прямой вывод на экран.
*
.104е]1 11пу
. соде
. 386 ; Будет использоваться регистр ЕАХ
| ; и команда’ $1050. .
ого = 1008 ; Начало СОМ-файла..
этагт: .

оу ах, 00038
111 101 ; Видеорежим 3 (очистка экрана).
с14 ‚ ; Обработка строк в прямом направлении.
‚ Подготовка данных для вывода на экран;
` МОУ еах, 1Е201Е00В ; первый символ 00 с атрибутом ЛЕВ,
‚ затем пробел (208) с атрибутом ЛЕВ
оу ьх, ОЕ201 ; Пробел с атрибутом ОЕВ.
оу сх, 255 ` :; Число символов минус 1.
поу 91, оГЕзет стаще ; ЕЗ:ОГ - начало таблицы,
71
ОИ ОЮИИЮЮ ИЩИ" Основы программирования для М$ 20$
с1оор:
$10$4 | : Записать символ и пробел в таблицу стае.
1пс а1 <; АЁ содержит следующий символ.
тезт сх, ОРВ ; Если СХ не кратен 16,
912 соп{1пие_1оор ; продолжить цикл.
рип сх ‚ ; Иначе: сохранить. значение счетчика.
том сх, 80-32 `; Число оставшихся до конца строки символов:
хсп9. — ах, 5х
гер $05 ; Заполнить остаток строки пробелами
; с атрибутом ОЕ.
хсН9 5х, ах ; Восстановить значение ЕАХ.
рор сх °; Восстановить значение счетчика.
соп{1пие_10ор:
1оор с1оор

Зто$9 - .: Записать последний (256-й) символ и пробел.

‚ собственно вывод на экран


том ах, 088001 ‚; Сегментный адрес видеопамяти.
оу е5, ах
хог. | 91, 91 ‚ ОТ = 0, адрес начала видеопамяти в ЕЗ:0Т.
то\ 31, ОГРзет стаб1е ; Адрес таблицы в 05:51,
[9 СХ, 15*80+32 _; 15 строк по 80 символов, последняя строка - 32.
° гер ПОУ$М ; Скопировать таблицу сфаб]е в видеопамять.
гет ; Завершение СОМ-файла.

стаб1е: | ; Данные для вывода на экран начинаются сразу


| ; за концом файла. В ЕХЕ-файле такие данные
\ ; определяют в’сегменте дата?
епд зТагт

В указанной программе при подготовке данных для копирования в видеопа-


мять учитывалось следующее: в архитектуре [п\е! при записи слова (или двойно-
го слова) в память старший байт располагается по старшему адресу. Так что при
записи в память двойного слова 1Е201Е00Ь сначала записывается самый "млад-
ший байт 006 (АЗСП-код текущего символа), потом 1ЕЬ, используемый в этом
примере атрибут, далее 20] (код пробела) и лишь затем, по самому старшему ад-
ресу, — самый старший байт, 1ЕВ, атрибут для этого пробела. Кроме того, в дан-
ном примере использовались некоторые 32-битные команды (МОУ и $ТОЗО).
Ими можно пользоваться из 16-битной программы (разумеется, если процессор
80386 и выше), но не стоит этим злоупотреблять, потому что каждая из команд
оказывается длиннее на 1 байт и выполняется дольше на 1 такт.

4.4. Ввод с клавиатуры


4.4.1. Средства 2О$
Как и в случае вывода на экран, РО$ предоставляет набор функций для чте-
ния данных с клавиатуры, которые используют сфандартное устройство ввода
Ввод склавиатуры © - _ ПИ
ЗТЬОГМУ, так что в качестве источника а данных можно применить файл или стан-
дартный вывод другой программы.
Функция 2О$ ДАЙ: Считать строку символов изз ТОМ в буфер
Вход: АН = ОАБ =
О5:0Х= адрес буфера ‹ |
Выход: Буфер содержит введенную строку
Для вызова этой функции надо подготовить буфер, первый байт которого за-
ключает в себе максимальное число символов для ввода (1254), а содержимое,
гсли оно задано, может использоваться как подсказка для ввода. При наборе стро-
ки обрабатываются клавиши ЕЁ$с, ЕЗ, Е5, В$, Си1-С/СЫ1-ВгеаК и т. д., как при
наборе команд 2О$ (то есть Езс начинает ввод сначала, ЕЗ восстанавливает под-
сказку для ввода, Еб запоминает текущую строку как подсказку, ВасКзрасе стира-
ет предыдущий символ). После нажатия клавиши Ещег строка (включая послед-
ний символ СВ (001)) записывается в буфер, начиная с третьего байта. Во второй
байт записывается длина реально введенной строки без учета последнего СК.
Рассмотрим пример программы, выполняющей преобразование десятичного
числа в шестнадцатеричное. | `
905111. азя
Переводит десятичное число в шестнадцатеричное.

‚то9е1 1пу ,
. соде
.286 ; Для команды зВг а1,4.
ого 100Н ; Начало СОМ-файла.
зтаге:
тому Чх, отРзе{ теззаде1
му ав,9
111 211 ; Вывести приглашение,ко вводу теззаде1.
мо\у 9х, оРРзеф Бийтег
по\ ан, оАВ |
ТИ 21и ; Считать строку символов В буфер.
моу 9х, оРЕзеф сг1Р
моу ап, 9 \
1 2 . : Перевод строки. |

Перевод числа в АЗСТТ-формате из буфера в бинарное число в АХ.


хог 91, 91 :- 01 = 0 - номер- байта в буфере.
хог ах, ах : АХ = 0 - текущее значение результата.
оу с1, 61епдей
хог св, сп `
хог ох, 6х
том $1, сх ; 51 - длина буфера
оу с1, 10 °; СЁ.= 10, множитель для МУ.
азс2Ннех: | |
поу _ 1, Буе рёг Бсоптепи$[9+]
зуб Ь1,'0’ “ : Цифра = код цифры - Код символа “0”.
ЕЪЖНИИШИИИИ | Основы программирования для М$ 20$
35 ‚ азс_еггог ; Если код символа был меньше, чем код “0”,
стр 51,9 ; или больше, чем “9”, |
Эа азс_еггог ; выйти из программы с сообщением об ошибке.
ты] ° сх : ; Иначе: умножить текущий результат на 10,
294 ах, 6х ‚; добавить к нему новую цифру, —
115 91 ; увеличить счетчик.
стр. 91, $1 . ; Если счетчик+1 меньше числа символов -
Ч азс2пех ‚ продолжить (счетчик ведет отсчет от 0).

; Вывод на экран строки теззаде2. .


рызи ах - ; Сохранить результат преобразования.
ем ап,9
моу 9х, оЕЕзет теззаде2
111 218.
рор ах

; Вывод на экран числа из’ регистра АХ.


ризН ах
хсНа ай, а1 ; Поместить в АЁ старший байт.
са11 ре1п{_а1 ; Вывести его на экран.
рор ах ; Восстановить в АЁ младший байт.
са11 рг1п{_а1 Вывести его на экран.
я
гет ‚ Завершение СОМ-файла.

азс_еггог: '
Те Чх’отРзет егг_пз9
пом ап,3
111 218 ‚ Вывести сообщение об ошибке
гет ‚ и завершить программу

‚ Процедура рг1пт_а1.
‚ Выводит на экран число в регистре АЁ
; В шестнадцатеричном формате,.
; модифицирует значения регистров АХ и 0%.

рг1п{_а1:
оу ЧИ, а]
апд дн, ОИ ; ОН - младшие 4 бита.
ЗПГ 21,4 ; АЁ - старшие.
са11 реп пе ‚ Вывести старшую цифру.
пом а], ЧИ ‚ Теперь АЕ содержит младшие 4’ бита.
рг1п{_п161е: ° ; Процедура вывода 4 бит (шестнадцатеричной цифры)
стр. а1, 10 | ; Три команды, переводящие цифру в АЁ
$ЬЬ, а], 69 ‚ в соответствующий АЗСТТ-код.
да$ ; (см. описание команды 0А$)

тоу 91, а1 ; Код символа в 01.


оу ан,2 ‚ Номер функции 00$ в АН.
11 218 ; Вывод символа.
гет ; Этот ВЕТ работает два раза - один раз
‚ для возврата из процедуры ргтп®_п16е,
Ввод склавиатуры — Е
; вызванной для старшей цифры,
; и второй раз - для возврата из рг1п_а1.

теззаде1 [+] "Десятичное число: $"


теззаде2 |] “Шестнадцатеричное число: $”
эгг_1$9 95 "Ошибка ввода“
с _ 65 00, ОАВ, `$`
зи Рег` Ч. 6 : Максимальный размер буфера ввода.
э1епоеи [9] ? ‚ Размер буфера после считывания.
эсолтепх$: ‚ ; Содержимое буфера располагается за
‚ концом СОМ-файла.
епд зфагт

Функция ОАВ предоставляет удобный, но ограниченный способ ввода данных.


Чаше всего используют функции посимвольного ввода, позволяющие контроли-
ые
ровать отображение символов на экране, реакцию программы на функциональн
— |
и управляющие клавиши и т. д.
ой на
Функция 205 О1Ё: Считать символ из УТОИУ с эхом, ожиданием и проверк
Се1-ВгеаК
Вход: АН = 01В
Выход: АТ, = АЗСИ-код символа или 0. Если АГ.= 0, второй вызов этой функ-
ции возвратит в АТ. расширенный АЗСН-код символа.
ото-
При чтении с. помощью этой функции введенный символ автоматически
что'его можно пе-
бражается на экране (посылается в устройство ЗТРОЧТТ - так
ется команда
ренаправить в файл). При нажатии СЫ1-С или С@1-ВгеаК выполня
символу
ПМТ 23Ь. Если нажата клавиша, не соответствующая какому-нибудь
ается 0
(стрелки, функциональные клавиши Таз, Ое| ит. д.), то в АЁ возвращ
АЗСП-код
и функцию надо вызвать еще один раз, чтобы получить расширенный
(см. приложение 1).
в АГ.
В трех следующих вариантах этой функции код символа‘ возвращается
по такому же принципу. | |
проверкой
Функция 0О$ 088: Считать символ из ЗТЬО!М без эха, с ожиданием и
на Си1-ВгеаК
Вход: `АН = 08
Выход: АТ. = код символа /
без провер-
Функция 205 078: Считать символ из ЗТОТМ без эха, с ожиданием и
ки на Си]-Вгеак ‚,
Вход: АН = 07.
Выход: АГ. = код символа
без провер-
Функция 2О$ 06Е: Считать символ из УТОК без эха, без ожидания и
ки на С]-ВгеаК | |
Вход: АН = 066
От. = ОРЕВ
№! Основы программирования для М$ 20$
Выход: 7Ё = 1, если не была нажата клавиша, и АГ, = 00
СЕ = 0, если клавиша была нажата. В этом случае АТ. = код символа

Кроме перечисленных могут потребоваться и некоторые служебные функции


РО$ для работы с клавиатурой.
Функция РО$ ОВР: Проверить состояние клавиатуры
Вход: АН = ОВЬ
Выход: АГ. = 0, если не была нажата клавиша .
АТ, = ОБЕВ, если была нажата клавиша
Данную функцию удобно использовать перед функциями 01, 07 и 08, чтобы не
ждать нажатия клавиши. Кроме ТОГО, ВЫЗОВ указанной функции позволяет про- !
верить, не считывая символ с клавиатуры, была ли нажата комбинация клавиш
СЫ1- ВгеаК; если это произошло, выполнится прерывание 238.
Функция 20$ ОСЁ: Очистить буфер и считать символ
Вход: _ АН = ОСЬ.
АТ. = Номер функции ОО® (01, ов,07, 08, ОАБ)
Выход: Зависит от вызванной функции

Функция ОСБ очищает буфер клавиатуры, так что следующая функция чте-
ния символа будет ждать ввода с клавиатуры, а не использовать нажатый ранее
иеще не обработанный символ. Например, именно эта функция используется для
считывания ответа на вопрос «Уверен ли пользователь в том, что он хочет отфор-
матировать диск?». .
Функции посимвольного ввода без эха можно использовать для интерактив-
ного управления программой, как в следующем примере.
‚ 903112. азт
; Изображает пентамино Е, которое можно перемещать по экрану клавишами
; управления курсором и вращать клавишами Х и 2. Выход из программы - Езс.

]1пе_]епаей = 3 ‚ Число символов в строке изображения.


питбег_оР_111е$ = 3 ; Число строк.

„тоде? пу
. соде .
огд 1008 ; Начало СОМ-файла.
Эфагт: -
с1а ‚; Будут использоваться команды
; строковой обработки. |
пом ° ах, 088001 — ‚ Адрес начала текстовой `видеопамяти -
моу ез, ах ; в Е.
оу ах, 00031
111 308 - ; Текстовый режим 03 (80х25).
моу ай, 021 ‚ Установить курсор
тоу В, 0 .
по\у ЧН, 26 | ; на строку 26, то есть за пределы экрана.
Ввод с клавиатуры 25
поу 31,1
171 108 ; Леперь курсора на экране нет.

са11 иурдате_зсгееп ; Вывести изображение.

; Основной цикл опроса клавиатуры.


па1п_]оор:
моу ап, 08 ® ; Считать символ с клавиатуры
1 218 ; без эха, с ожиданием, с проверкой на (т Вгеак.
тезт а1,а1 ; Если АЁ = 0,
ра еАЗСТТ_ептегед ; введен символ расширенного АЗСТТ.
стр а], 1ВВ ; Иначе: если введен символ 1ВВ (Е$с),
)е Кеу_Е5С ; выйти из программы.
‚ стр а], '2' ; Если введен символ 2,
де Кеу 7. ; перейти на его обработчик.
стр а], ‘7’ ; То же для 2.
де Кеу_2
стр а], ’Х’ ; Если введен символ Х,
3е кеу_Х | ; перейти на его обработчик.
стр а1,°х’ ; То же для х..
де Кеу_Х
тр ЗПОГЕ ма1п_10ор ; Считать следующую клавишу.
ЗАЗСТТ_ептегед: ; Был введен расширенный АЗСТТ-символ.
111 218 ; Получить его код (повторный вызов функции). .
стр а1, 481 ; Стрелка вверх. |
де Кеу_ПР
стр - а], 50в . Стрелка вниз.
]е кеу_о0им .
стр а1, 48 ; Стрелка влево.
3е Кеу ЕЕЕТ
стр а1, 408 ; Стрелка вправо.
де Кеу ВТЕНТ
Этр звогЕ та1п_1оор ; Считать ‘следующую клавишу.

Обработчики нажатий ‘клавиш.

«еу_ЕЗС: ; ЕС‘ |
гет ; Завершить СОМ-программу.
„зу ЦР: ; Стрелка вверх.
` сир Буфе ртг эТаге_гом ‚0 ; Если изображение на Верхнем
; краю экрана,
па ма1п_1оор ; считать следующую клавишу.
дес Буфе рег этагЕ_гом ; Иначе - уменьшить номер строки,
са11 ирдате_зсгееп ; вывести новое изображение
тр ЗПогЕ ма1п_1оор .; и считать следующую клавишу.

«2у_О0\М: ; Стрелка вниз.


стр уфе руг зтагЕ_гом, 25- пиабег _оР_11пез ; Если
; изображение на нижнем краю экрана,
Эль па1п_1оор ‚ считать следующую клавишу.
ШЕИ! Основы программирования для.М$ 205
тс Буте рфг зтагтгом ; Иначе - увеличить номер строки,
са11 ирдате_зсгееп ; вывести новое изображение
Этр ЗПогЕ та1п_1оор ; и считать следующую клавишу.

Кеу_ГЕЕТ: : Стрелка влево.


стр Буде р\г зтаг®_с01;0 ; Если изображение на левом краю экрана,
фпа па1п_1оор : считать следующую клавишу.
дес буте руг зФагЕ_со1 ;‚ Иначе - уменьшить номер столбца,
са11 ирдате_зсгееп ; вывести новое изображение
Эр пог та?1п_}оор ; и считать следующую клавишу.

Кеу_ВТЕНТ: ‹ Стрелка вправо.


стр руде руг зтаг®_со1, 80- ле_1епоти ; Если
‚ изображение на правом краю экрана,
16 па1п_100р = ; считать следующую клавишу.
- ис Буфе рёг зтТаге_со1 ; Иначе - увеличить номер столбца,
са] ирдате_зсгееп ; вывести новое изображение
р эВогф ма1п_1оор ; и считать следующую клавишу.

Кеу_2: - ; Клавиша 2 (вращение влево).


поу , ах, сиггеп{_зсгееп ; Считать номер текущего изображения
(значения 0, 1, 2, 3),
9е6 ‘ах : уменьшить его на 1.
плз Кеу_2_ок ; Если получился -1 (поменялся знак),
моу ах, 3 ; АХ =3.
Кеу_2_ ок:
вом сиггепт_зсгееп, ах ; Записать номер обратно,
са ирдате_зсгееп ; вывести новое изображение
тр ма1п_1оор ; и считать следующую клавишу.
кеу_Х: ; Клавиша Х (вращение вправо).
’” МОУ ах, сиггеп{_зсгееп ; Считать номер текущего изображения
(значения 0, 1, 2; 3),
1пс ах ; увеличить его на 1., `
стр ‚ах; 4 ; Если номер стал равен. 4,
ле `кеу_Х_ок
хог ах, ах ‚ АХ = 0.
Кеу_Х_ок: `
то сиуггел{ _зсгеел, ах ; Записать номер обратно,
са11 ирдафе_зсгееп ; вывести новое изображение
Этр та1п_1оор ; и считать следующую клавишу.

‚ Процедура ирдате_зсгееп. \

; Очищает экран и выводит текущее. изображение.


; Модифицирует значения. регистров АХ, ВХ, СХ, 0х, 5Т, ОГ..
урдате_всгееп:
том сх, 25*80 Число символов.
на экране.
моу ах, ОЕ20Н . Символ 208 (пробел) с атрибутом ОЕП
(белый на черном).
^хог 91,91 ЕЗ:0Т = начало видеопамяти.
`гер З10зи Очистить экран.
Ввод с клавиатуры И | | 1147}
му Ьх, сиггепт _зсгееп ; Номер текущего изображенйя в ВХ.
$Н] х, 1 : Умножить: на 2, так как зсгееп$ - массив слов.
моу $1, эсгееп$ [6х] ; Поместить в ВХ смещение начала |
текущего изображения из массива зсгеепз.
моу ах, зтаг{_гом ; Вычислить адрес начала
ми] гои_1епахв ; изображения в видеопамяти:
- 299 ах, зтаг{_со1 ; {строка х 80 + столбец) х 2.
$81 ах,1
оу 31, ах ; ЕЗ:0Т - начало изображения в видеопамяти.
поу ай, ог Используемый атрибут - бельй на’ черном.
оу ‚ ах, пимбег_оР_11пе$ ; Число строк’в изображении.
зору_11пез;
моу сх, 11пе_1епотй . „Число символов В строке.
сору_1: 109$6 Считать АЗСТТ-код в А|,
5103м записать его в. видеопамять
(АЕ - АЗСТТ, АН - атрибут).
16ор сору_1 ; Вывести так все символы в строке.
ад3 91, (80-11 пе_Тепдти „2; Перевести ОГ на начало
следующей строки экрана.
дес 9х . Если строки не закончились -
12 сору_11пез ; вывести следующую.

гет Конец процедуры ирдахе_зсгееп.


Изображение пентамино Е.
зсгеей1 [8] ” ХХ" ‹; Выводимое изображение.
Ге] "Хх" ,
_ 95 "Хх"

эсгееп2 6 "х“ ; Поворот на 90 градусов вправо.


|] "ХХХ" |
06 "ХХ

эсгееп3 а6 х ; Поворот-на 180 градусов.


а хх .
5 "Хх"

зсгееп4 49 Ь "Х. ; Поворот на 90 градусов влево.


|] "ХХХ" |
. {е]*) "х”
Массив, содержащий адреса всех вариантов изображения.
$сгееп$ м ‚ эсгееп1, зсгееп2, зсгееп3 , зсгееп4
сиггеп*_зсгееп м 0 _ ; Текущий. вариант изображения.
этагЕ_гом 9м 10 ; Текущая верхняя строка изображения.
зфаг+_с01 9\ 37 ; Текущий левый столбец. |
гом_1епдеи [8] 80 .; Длина строки экрана для команды МИ.

епа зТагт
. "у .
В этом примере для вывода на экран используется прямое копирование в ви-
деопамять, так как вызов функции ВТО$ вывода строки (ТМТ 101, АН = 13Ъ)
ТИМ Основы программирования для М$ 20$
прокручивает экран вверх на одну строку при выводе символа в нижнем правом
углу экрана. |

4.4.2. Средства В10$ ,

Так же как и для вывода на экран, ВТО$ предоставляет болыне возможностей


по сравнению с ОО$ для считывания данных и управления клавиатурой. Напри-
мер, функциями РО нельзя определить нажатие комбинаций клавиш типа С&]-
АЕ-Епбег или нажатие двух клавиш ЗЫ одновременно, ОО$ не может определить
момент отпускания нажатой клавиши, и наконец, в ОО$ нет аналога функции С
ипвесЬ(), помещающей символ в буфер клавиатуры, как если бы его ввел пользова-
тель. Все это можно осуществить, используя различные функции прерывания 16В
и операции с байтами состояния клавиатуры.
МТ 164, АН = 0, 10й, 201: Чтение символа с ожиданием
Вход: АН = 001 (83/84-Кеу), 10 (101/102-Кеу), 208 (122-кеу)
Выход: АТ. = АЗСН-код символа, 0 или префикс скан-кода
АН = скан-код нажатой клавиши или расширенный АЗСП-код

Каждой клавише на клавиатуре соответствует тах называемый скан-код (см. при-


ложение 1), соответствующий только этой клавише. Этот код посылается клави-
атурой при каждом нажатии и отпускании клавиши и обрабатывается ВТО$ (об-
работчиком прерывания ПМТ 9). Прерывание 16} дает возможность получить код
нажатия, не перехватывая этот обработчик. Если нажатой клавише соответствует
А$СП-символ, то в АН возвращается код этого символа, а в АГ, - скан-код клави-
ши. Если нажатой клавише соответствует расширенный АЗСП-код, в АЁ возвра-
щается префикс скан-кода (например, ОЕОВ для серых клавиш) или 0, если пре-
фикса нет, ав АН - расширенный АЗСП-код. Функция 00Ё обрабатывает только
комбинации, использующие клавиши`84-клавишной клавиатуры; 10Ъ обрабаты-
вает все 101-105-клавишные комбинации; 206 — 122-клавишные. Тип клавиату-
ры можно определить с помощью функции 09 прерывания 16В, если она поддер-
живается В1О$ (поддерживается ли эта функция, можно узнать с помощью
функции ОСОБ прерывания 15%).
МТ 164, АН = 1, 111, 218: Проверка символа
° Вход: АН= 018 (83/84-Кеу), 11 (101/102-Кеу), 21 (122- Кеу)
Выход: СЕ = 1, если буфер пуст
7Е = 0, если в буфере присутствует символ, тогда.
АГ. = АЗСП-код символа, 0 или префикс скан-кода
АН = скан-код нажатой клавиши или расширенный АЗСП-код
Символ остается в буфере клавиатуры, хотя некоторые ВТО$ удаляют символ
из буфера при обработке функции 01, если он соответствует расширенному
АЗСП-коду, отсутствующему на1 84--клавишных клавиатурах. , \
Ввод с клавиатуры = _ т |.
МТ 161, АН = 05й: Поместить символ в буфер клавиатуры
Вход: АН = 05,
СН = скан-код в
СГ.= АЗСП-код.
Выход: АГ.= 00, если операция выполнена успешно
АТ.= 01$, если буфер клавиатуры переполнен
АН модифицируется многими В1О$
Обычно вместо скан-кода в СН. можно поместить 0, если функция, которая
будет выполнять чтение из буфера, использует именно АЗСП-код. Например,
следующая программа при запуске из РО5 вызывает команду ОГВ (но при запус-
ке из некоторых оболочек, например ЕАК, этого не произойдет).
; ипдетсй. азт |
; заносит в буфер клавиатуры команду ОТВ так, чтобы она выполнилась сразу. после
; Завершения программы . ` `

.тоде1 11пу
. соде
0г9 1008 ; СОМ-файл
этаге: ,
. тому с1,'9°’ ; С. = АЗС -код буквы “9”
са]11 упоетси .
МОУ с1,'1' ; АЗС -код буквы “1” в
са11 ипоетсв
му с1,'г’ ; АЗСТТ-код ‘буквы “г”
- Аса11 упдетси |
/ МОУ с1,001 ; перевод строки
упоетсн: | |
моу ап, 5 ; АН = номер функции
моу сп, 0 ; СН =О0 (скан-код неважен)
111 161 ; поместить символ в буфер
гет ; завершить программу
епд Уфагт

МТ 16Ё, АН= 02%, 121, 228: Считать состояние клавиатуры


Вход: АН= 02} (83/84-Кеу), 126 (101/102-Кеу), 22Ь (122-Кеу)
Выход: АЕ= байт состояния клавиатуры 1
АН= байт состояния клавиатуры 2 (только для функций 12 и 225)

Байт состояния клавиатуры 1 (этот байт всегда расположен в памяти по адресу


0000Ъ:0417Ъ или 00401:0017Ъ): `
бит 7: 11$ включена
бит 6: СарзТосК включена
бит 5: МишГосК включена р
бит 4: ЗсгоШосК включена .
ЕТО Основы программирования для М5 205
бит 3: АЕ нажата (любая А! для функции 02, часто только левая АЁ
для 125/22)
бит 2: СЫ1 нажата (любая С@Т)
бит 1: Левая ЗЫЙ нажата
бит 0: Правая ЗЫЁ нажата {

Байт состояния клавиатуры 2 (этот байт всегда расположен в памяти по адресу


0000$:0418Ь или 0040}:0018В): |
бит 7: $у$Вд нажата
‘бит 6: СарзТосК нажата
бит 5: МитГосК нажата
бит 4: ЗсгоШосК нажата
бит 3: Правая АЁ нажата
бит 2: Правая СЫ] нажата
бит 1: Левая АК нажата
бит 0: Левая СЫ] нажата
'Оба байта постоянно располагаются в памяти, так что вместо вызова прерыва-
ния часто удобнее просто считывать значения напрямую. Более того, в эти байты
можно записывать новые значения, и ВГО$ соответствующим образом изменит
состояние клавиатуры: -
; по1оск. азм
; Самая короткая программа’ для выключения МитЬоск, СарзЁоск и $сго114оск.
; Запускать без параметров.
‚104е1 лу |
. боде , .
ог9 1008 ; СОМ-файл. АХ при запуске СОМ-файла
; без параметров в командой строке
| ; всегда равен 0.
эТтагт:
тоиу - 05,ах ; Так что теперь 0$ =
оу Буе г 45:04171, а1 ; байт состояния клавиатуры 1 = 0.
гет ; Выход из программы.
епа ЗТагт

Разумеется, в реальных программах, которые будет запускать кто-то, кроме


автора, так делать нельзя, и первой командой дожна быть хог ах‚ах.
Помимо этих двух байт ВГО$ хранит в своей области данных и весь клавиа-
турный буфер, к которому также можно обращаться напрямую. Буфер занимает
16 слов с 0В:041ЕЁ по 0Б:043
0} включительно, причем по адресу 0Б:041АВ лежит
адрес (ближний) начала буфера, то есть адрес, по которому располагается следу-
ющий введенный символ, а по адресу 0В:041СЬ находится адрес конца буфера, так
что если эти два адреса равны, буфер пуст. Буфер действует как кольцо: если на-
чало буфера — 043СЬ, а конец - 04201, то в буфере расположены три символа по
адресам 043СЬ, 041ЕВ и 0420Ъ, Каждый символ хранится в виде слова — того же
самого, которое возвращает функция 101 прерывания ПМТ 16$Ъ. В некоторых слу-
чаях (если) буфер размещается по другим адресам, тогда адрес его начала хранится
Графические видеорежимы | И ОИПИ ПСТ
в области данных ВГО$ по адресу 0480Ъ, а конца — по адресу 04825. Прямой дос-
туп к буферу клавиатуры лишь немногим быстрее, чем вызов соответствующих
функций В1О$, и для приложений, требующих максимальной скорости, таких как
игры или демо-программы, используют управление клавиатурой на уровне пор-
тов ввода-вывода.

4.5. Графические видеорежимы


4.5.1, Работа сУбА-режимами
Функция 00 прерывания ВТО$ 101 позволяет переключаться не только в тек-
стовые режимы, использовавшиеся в предыдущих главах, но и в некоторые гра-
фические. Эти' видеорежимы стандартны и поддерживаются всеми видеоадапте-
рами (начиная с УСА), см. табл. 19..

Таблица 19. Основные графические режимы УСА

118 _ 640х480
121 640х480
320х200

Существуют еще несколько видеорежимов, использовавшихся более старыми


зидеоадаптерами ССА и ЕСА (с номерами от 4 до 101).
ВТО$ также предоставляет видеофункции чтения и записи точки на экране
з графических режимах, но эти функции настолько медленно исполняются, что
никогда не применяются в реальных программах. .

ТУТ 101 АН= ОСЁ: Вывести точку на экран


Вход: АН= 0СЬ
ВН - номер видеоётраницы (игнорируется для режима 13}, поддержи-
вающего только одну страницу)
ОХ = номер строки
СХ = номер столбца
АГ; = номер цвета (для режимов 108 и АВ, если старший бит 1, номер
цвета точки на экране будет результатом операции «исключаю-
щее ИЛИ»)
Выход: Никакого
ТУТ 108 АН = ОЕ: Считать точку с экрана
Вход АН= 00Ь
ВН -= номер видеостраницы (игнорируется для режима 138, поддержи-
вающего только одну страницу).
ОХ = номер строки
\
СХ = номер столбца
Выход: АГ. = номер цвета
СРАМИШИШШИЕ!\— Основы программирования для М$ 20$
.
Попробуем тем не менее воспользоваться средствами ВТО$З для вывода на эк-
ран. Следующая программа переводит экран в графический режим 13 (320х200),
заселяет его точками случайным образом, после чего эти точки эволюционируют _
согласно законам алгоритма «Жизнь»: если у точки меньше двух или больше трех
соседей, она погибает, а если у пустой позиции есть три соседа, в ней появляется
новая точка. Мы будем использовать очень простой, но неоптимальный способ ре-
ализации этого алгоритма: сначала для каждой точки вычисляется число соседей,
затем каждая точка преобразуется в соответствии с полученным числом соседей,
после чего каждая точка выводится на экран. |
; 11е610$.азм
. Игра “Жизнь” на поле 320%200, использующая вывод на экран средствами 8105.

.0е] $та11
„зтаск 1008: ; Явное задание стека - для ЕХЕ-программ.
‹ . соде
. 186 : Для команд 311 а1,4 и $1г а1,4.
зтагг:
ризй РАВ_855. ‹ Сегментный адрес буфера в 0$.
рор 9$

; Заполнение массива ячеек псевдослучайными значениями.


хог ах, ах у
Лпе ЧАН ; Функция АН =`0 ТМГ 1АВ: получить текущее
; время.
; ОХ теперь содержит число’ секунд!
:. прошедших с момента включения. ‘компьютера,
; которое используется как начальное значение
. ‚ р Г@нератора случайных чисел.
тоу 91, 320*200+1 ; Максимальный номер ячейки.
111] _битгЕег: |
11] 9х, 4ЕЗ 58 ; Простой генератор случайных чисел
1пс ах ; из двух команд.
оу ах, Чх ‚ Текущее случайное число копируется в АХ,
ЗВг ах, 15 . от него оставляется только. один бит,
оу руте рег [91],а1 ; и в массив копируется 00, если ячейка
. . пуста; и 01, если заселена.
Фес . 91 ; Следующая ячейка. .
17 РИ БитРег ` ; Продолжить цикл, если ОТ не стал равен нулю.

тоу ах, 00131 ; Графический режим 320х200, 256 цветов.


171 108

; Основной цикл.

пем_сус1е:

; Шаг 1: для каждой ячейки вычисляется число соседей


: И записывается в старшие 4 бита этой ячейки.

оу 91, 320*200+1 ; Максимальный номер ячейки.


*

Графические видеорежимы т 1538


зтер_1:
оу а1, Буте ртг [91+1]. В А. вычисляется сумма
а09 а], Буте рег [91-1] значений восьми соседних ячеек,
ава а], Буте рег [91+319] при этом в младших четырех
ава а1, Буте ртг [941-319) битах накапливается число
ада а], Буте рег [91+320] ; соседей.
ада а1 , Буте рег; [91-320]
ад9 а1, Буте рег: [91+321]
а99 а], буте рег [91-321]
$11 а1, 4 Теперь старшие четыре бита АЁ - число
соседей текущей ячейки.
ог футе руг [91],а1 Поместить их в старшие четыре бита \
текущей ячейки
дес 41 , Следующая ячейка.
9172 Зфер_1 Продолжить цикл, если ОТ не стал равен нулю.

: Шаг 2: изменение состояния ячеек в соответствии с полученными в шаге 1


: значениями числа соседей.

- ЮУ 91,320*+200+1 Максимальный номер ячейки.


Е] 1р_сус1е:
тоу а}, руте рег [91] Считать ячейку из массива.
ИГ а1,4 АЁ = число соседей.
стр а],3 Если число соседей = 3,
де Бей ячейка заселяется.
стр а1,2 Если число соседей = 2,
де Ес сопЕ1пие ячейка не изменяется.
Буте ртг [911,0 Иначе - ячейка погибает.
зНоге Р_с_ сойт1тие
ги:
в Буте рег [91],1
Е с сопЕ1пие:
апд русе рег [91], ОР® # ; Обнулить число соседей в старших
битах ячейки.
дес 91 Следующая ячейка.
312 Е 1р_сус?е

Вывод массива на экран средствами В10$.,

том $1,320*200+1 Максимальный номер ‘ячейки.


том сх, 319 Максимальный номер столбца.
`` МОУ ах, 199 Максимальный ‘номер строки.
291 зр1ау:
| ОУ а], буте рег [31], Цвет точки (00 - черный, 01.- синий).
ав, осв Номер видеофункции в АН.
108 Вывести точку на экран.
51 Следующая ячейка.
сх Следующий номер столбца.
291зр]1ау. ;- Если столбцы не закончились - продолжить.
'СЕТИМИИИИИЕ | Основы программирования для М5 00$
мо\у сх, 319 ; Иначе: снова максимальный номер столбца в СХ
дес 9х ; и следующий номер строки в ОХ.
31$ 2015р1ау . Если и строки закончились - выход из цикла.

оу ап, 1 | : Если не нажата клавиша -


101 168 :
2 пем_сус1е ; следующий шаг’ жизни.

оу ах, 00038 ; Восстановить текстовый режим


пт 101
моу ах, 46000 ° . ‹ и завершить программу.
1% 211 ) :

‚ Тагдата? ‚ Сегмент дальних неинициализированных данных


[6 320»200+1 дир(?) ; содержит массив ячеек.
епа ЗТагт

Этот фрагмент оформлен как ЕХЕ-программа, потому что применяется мас-


сив, близкий по размерам к сегменту, и если разместить его в одном сегменте
с СОМ-программой, стек, растущий от самых старших адресов, может затереть
область данных. В нашем примере стек не используется, но он нужен обработчи-
ку прерывания ВТОЗ 101.
Скорость работы указанной программы — в среднем 200 тактов процессора
Репиипь на точку (измерения выполнены с помощью команды ВОТОЬС, см. раз-
дел 10.2), то есть всего 16 поколений в секунду для Репиит-200 (200 миллионов
тактов в секунду разделить на 200 тактов на точку и на 320%200 точек). Разумеет-
ся, используемый алгоритм крайне нерационален и кажется очевидным, что его
оптимизация приведет к значительному выигрышу во времени. Но если измерить
скорость выполнения каждого из трех циклов, то окажется, что первый цикл вы-
полняется в среднем за 20,5 такта на точку, второй - за 13, а третий - за 170,5!
Исправить эту ситуацию весьма просто — достаточно отказаться от видеофунк-
ций В10$ для работы с графикой и перейти кпрямому копированию в видеопамять.
В видеорежиме 13В каждый байт в области памяти, начинающейся
с адреса 0А000В:0000, соответствует одной точке на экране, а значение, которое
может принимать этот байт (0-255), — номеру цвета этой точки. (Цвета, которые
соотносятся с данными номерами, могут быть перепрограммированы с помощью
видеофункции 10Ъ ВТОЗ.) В видеорежимах 118 и 12} каждыйбит . соответствует
одной точке на экране, так что простым копированием в видеопамять можно по”
лучить только черно-белое изображение (для вывода цветного изображения .
в режиме 12Ь необходимо перепрограммировать видеоадаптер; об этом см. в раз-
деле 5.10.4).
В нашем примере для хранения информации о каждой ячейке также использу-
ется один байт, следовательно, для вывода данных на экран в режиме 13В достаточ-
но выполнить простое копирование. Переименуем программу ГЛЕЕВ1О$.АЗМ
в ЛЕЕБГВ. А$М, заменив цикл вывода на экран от команды
оу $1, 320*200+1 -
Графические видеорежимы _
до второй команды
#
]пз 2415р]ау

следующим фрагментом кода:


ризн ОАОООН ; Сегиентный адрес видеопамяти
рор е$ , ; в Е.
воу сх, 320*200 ; Максимальный номер’ точки
моу 31, сх ; в видеопамяти - 320х200,
моу 31, сх . ; а. в массиве -
фпс $1 ; 320х200 + 1.
. гер моУЗЬ, : Выполнить копирование в видеопамять,

Теперь программа обрабатывает одну точку приблизительно за 61,5 такта про-


цессора Репцит, что дает. 51` поколение в секунду на Репиит-200. Кроме того,
сейчас эту программу можно переписать в виде СОМ-файла, так как и код, и мас-
сив, и стек точно умещаются в одном сегменте размером 64 Кб. Такая СОМ-про-
грамма (ЛЕЕСОМ.АЗМ) займет 143 байта.
Оптимизация программы «Жизнь» — хорошее упражнение ДлЯ программиро-
вания на ассемблере.`В 1997 году проводился конкурс на самую короткую и на
самую быструю программу, выполняющую в точности то же, что и наш пример, —
заполнение экрана случайными точками, их эволюция и выход по нажатию лю-
бой клавиши. Самой короткой тогда оказалась программа размером в 72 байта,
которая с тех пор была усовершенствована до 64 байт (ее скорость 52. такта на
точку), а самая быстрая из 16-битных программ тратит на каждую точку в сред-
нем всего 6 тактов процессора Репйии и имеет размер 689 байт. В ней состояния
ячеек описываются отдельными битами массива, а для их обработки используют-
ся команды логических операций над целыми словами, поэтому одна команда
обслуживает сразу 16 точек. Применение 32-битных команд с тем же алгоритмом
позволяет ускорить программу до 4,5 такта на точку.

4.5.2, Работа с $5УбА-режимами


В режиме УСА 320х200 с 256 цветами для отображения видеопамяти на ос-
новное адресное пространство используется 64 000 байт, располагающихся с ад-
реса 0А000Ъ:0000Ъ. Дальнейшее увеличение разрешения или числа цветов при-
водит к тому, что объем видеопамяти превышает максимальные границы сегмента
в реальном режиме (65 535 байт), а затем и размер участка адресного простран-
ства, отводимого для видеопамяти (160 Кб, от 0А000Б:00001 до 0В8006:0ЕЕЕЕВ.
С адреса 0С800Ъ:0000Ъ начинается область КОМ В10$5). Чтобы вывести изобра-
жение, используются два механизма — переключение банков видеопамяти для ре-
ального режима и ГЕВ (линейный кадровый буфер) для защищенного.
Во втором случае видеопамять отображается на непрерывный кусок адресного
пространства, но начинающегося не с 0А0000}, а с какого-нибудь другого адреса, так
чтобы весь массив видеопамяти, который может занимать несколько мегабайтов,
отобразился в одну непрерывную область. В защищенном режиме максимальный
156111111] Основы программирования для М5 205
ией этого
размер сегмента составляет 4 Гб, поэтому никаких сложностей с адресац
только если видеоад аптер
буфера не возникает. Буфер ГЕВ можно использовать,
поддерживает спецификацию УВЕ 2.0 (см. пример в разделе 6.4).
копирова-
В реальном режиме вывод на экран осуществляется по-прежнему
ющийся с адреса
нием. данных в 64-килобайтный сегмент, обычно начина
Чтобы
04А000\:0000Ъ, но эта область памяти соответствует только части экрана.
ю перемеще-
вывести изображение в другую часть экрана, нужно вызвать функци
изменяющую
ния окна (или, что то же самое, переключения банка видеопамяти),
Например, в режи-
область видеопамяти, которой соответствует сегмент 04000Ъ.
307 200 байт для хранени я всего видеоизоб-
ме 640%480 с 256 цветами требуется
приводит к за-
ражения. Заполнение сегмента 040001:0000% - 0А000Ъ:ОЕЕЕЕЬ
1/5 экрана, перемещение окна А на позицию 1 (или
краске приблизительно
- к закраске
переключение на банк 1) и повторное заполнение этой же области
подфункцией 05
следующей 1/5 экрана и т. д. Перемещение окна осуществляется
ру, адрес кото-
видеофункции 4ЕВ или передачей управления прямо на процеду
рой можно получить, активизировав подфун кцию 01, как будет показано ниже.
овать сразу два таких 64-килобайт-
Некоторые видеорежимы позволяют использ
ь 128 Кб данных, не вызывая
ных окна, окно А и окно В, так что можно записат
прерывания.
24- и 32-
Стандартные графические режимы $УСА могут быть 4-, 8-, 15-, 16-,
битными. |
4-битные режимы (16 цветов)
УСА -
012Ъ: 640х480 (64 Кб)
\УЕЗА УВЕ 1.0.
1028: 800х600 (256 Кб)
104Ъ: 1024х768 (384 Кб)
106Ъ: 1280х1024 (768 Кб)
Каждый пиксел описывается одним битом, для вывода цветного изображения
ывода (раз-
требуется программирование видеоадаптера на уровне портов ввода-в
дел 5.10.4). й |

8-битные режимы (256 цветов)


УСА |
013Ъ: 320х200 (64 Кб)
УВЕ 1.0
1008: 640х400 (256 Кб)
101Ъ: 640х480 (320 Кб)
103: 800х600 (512 Кб)
105Ъ: 1024х768 (768 Кб)
107}: 1280х1024 (1,3 Мб)
УВЕ 2.0
1201: 1600х1200 (1,9 Мб).
Графические видеорежимы _ 157
Каждый пиксел описывается ровно одним байтом. Значение байта — номер
цвета из палитры, значения цветов. которой можно изменять, например вызывая
подфункцию 09В видеофункции 4ЕК.
15-битные режимы (32 К цветов)
УВЕ 1.2 |
100: 320х200 (128 Кб)
1106: 640х480 (768 Кб)
1135: 800х600 (1 Мб)
1161: 1024х768 (1,5 Мб)
1191: 1280х1024 (2,5 Мб)
УВЕ 2.0
1218: 1600х1200 (3,8 Мб) |
Каждый пиксел описывается ровно одним словом (16 бит), в котором биты 0-#
содержат значение синей компоненты цвета, биты 5-9 — зеленой, а биты 10-14 —
красной. Бит 15 не используется. В у
16-битные режимы (64 К цветов)
УВЕ 1.2 | |
10Е1: 320х200 (128 Кб)
1116: 640х480 (768 Кб)
114Ь: 800х600 (1 Мб)
1175: 1024х768 (1,5 Мб)
11АБ: 12801024 (2,5 Мб)
УВЕ 2.0 .
1225: 1600х1200 (3,8 Мб) о.
Так же как и в 15-битных режимах, каждый пиксел описывается ровно одним
словом. Обычно биты 0—4 (5 бит) содержат значение синей компоненты, биты 5-10
(6 бит) - зеленой, а биты 11-15 (5 бит) - красной. В нестандартных режимах
число битов, отводимое для каждого цвета, может отличаться, так что при их ис-
пользовании следует вызвать подфункцию 01 видеофункции 4ЕВ и получить ин-
‚ формацию о видеорежиме, включающую битовые маски и битовые смещения для
цветов.
24-битные и 32-битные режимы (16 М цветов)
УВЕ 1.2
10ЕЬ: 320х200 (192 Кб) : ,
1125: 640х480 (1 Мб)
115Ь: 800х600 (1,4 Мб)
1186: 1024768 (2,3 Мб)
11ВЬ: 1280х1024 (3,7 Мб) |
В режимах с 24-битным и 32-битным цветом каждому пикселу на экране соот-
ветствуют три байта и одно двойное слово (4 байта). Если видеорежим использу-
-т модель памяти 6 (Пигесе Сог), то младший байт (байт 0) содержит значение
:инего цвета, байт 1 содержит значение зеленого, байт 2 — значение красного,
ЕЕРВИВИШИИИИИ | Основы программирования
‘для М5 205
а байт 3 — в 32-битных режимах резервный и используется либо для выравнива-
` ния, либо содержит значение для альфа-канала. Некоторые видеорежимы могут
со-
использовать не Оиесе Со|от, а УЦУ (модель памяти 7) — здесь младший байт
ответствует насыщенности красного, байт 1 — насыщенности синего, а байт 2-—
яркости. р
° Видеоада птер может поддерживать и собственные нестандартные видеорежи-_
мы. Список их номеров можно получить, вызвав подфункцию 00р, а получить
информацию о режиме по его номеру - вызвав подфункцию 018 видеофункции
АЕБ. Более того, для стандартных режимов также следует вызывать подфункцию
01Ъ, чтобы проверить реальную доступность режима (например, режим может
т
быть в списке, но не поддерживаться из-за нехватки памяти). УВЕ 2.0 разрешае
видеоадаптерам не поддерживать никаких стандарт ных режимов вообще.

[МТ 108 АН = 4Ё, АГ. = 00: Получить общую 5УСА-информацию


Вход: АХ = 4Е00Ь |
Е$:0] = адрес буфера (512 байт)
Выход: АТ, = 4ЕВ, если функция поддерживается
_ АН =01, если произошла ошибка
° АН = 00, если данные получены и записаны в буфер
„Буфер для общей ЗУСА-информации:
+001: 4 байта- будет содержать УЕЗА после вызова прерывания, чтобы получить
поля, начиная с 148, здесь надо предварительно записать строку
УВЕ?
+04Ъ: слово — номер версии УВЕ в двоично-десятичном формате (01028 — для
1.2, 02005 - для 2.0) .
+06}: 4 байта- адрес строки-идентификатора производителя
_. —
+0АВ: 4 байта- флаги:
бит 0: АЦП поддержива ет 8-бит ные цвето вые компо ненты (см. подфун-
кцию 081)
бит 1: видеоадаптер несовместим с УСА
бит 2: АЦП можно программировать только при обратном ходе луча
бит 3: поддерживается спецификация аппаратного ускорения графики
УВЕЛАЕ 1.0
бит 4: требуется вызов ЕпаЫеО\кесёАссез; перед использованием ГЕВ
бит 5: поддерживается аппаратный указатель мыши
бит 6: поддерживается аппаратный сНррт8
бит 7: поддерживается аппаратный ВЁВЕ
биты 8-31 зарезервированы | ,
(массив
+0ЕБ: 4 байта — адрес списка номеров поддерживаемых видеорежимов
слов, последнее слово = ОЕЕЕЕБ, после которого‘обычно следует
список нестандартных режимов, также заканчивающийся сло-
вом ОБЕЕЕВ) | |
+12.: слово — объем видеопамяти в 64-килобайтных блоках
+14Ъ: слово — внутренняя версия данной реализации УВЕ
Графические видеорежимы == МНЕ
+165: 4 байта - адрес строки с названием производителя
+1АБ: 4 байта - адрес строки с названием видеоадаптера
+1ЕЪ: 4 байта -— адрес строки с версией видеоадаптера |
+225: слово —- версия УВЕ/АЕ (ВС, то есть 0100Ъ для 1.0)
+245: 4 байта - адрес списка номеров режимов, поддерживающих аппаратное
_ ускорение (если бит поддержки УВЕ/АЕ установленв 1)
+28: 216 байт — зарезервировано УЕЗА _
+1006:256 байт — зарезервировано для внутренних данных УВЕ. Так, например,
в эту область копируются строки с названиями производителя, .
видеоадаптера, версии и т. д. ”
МТ 108 АН = 4ЁР, АЕ = 01: Получить информацию о режиме
Вход:. АХ- 4ЕР1Ь ` | |
<

СХ - номер 5УСА-режима (бит 14 соответствует использованию ГЕВ,


бит 13— аппаратному ускорению) о
ЕЗ:ОТ - адрес буфера для информации о режиме (256 байт)
Выход: АГ, = 4ЕВ, если функция поддерживается
АН - 013, если произошла ошибка
АН = 00}, если данные получены и записаны в буфер
Буфер для информации о ЗУСА-режиме:
+00Ъ: слово — атрибуты режима:
бит 0: режим присутствует
бит 1: дополнительная информация (смещения 12% — 1ЕБ) присутству-
ет (для УВЕ 2.0 эта информация обязательна и бит всегда ‘уста-
‘новлен)
. бит 2: поддерживается вывод текста на экран средствами ВО$
бит 3: режим цветной | -)
бит 4: режим графический
бит 5: режим несовместим с УСА
бит 6; переключение банков не поддерживается
бит 7: ГЕВ не поддерживается |
бит 8: не определен |
бит 9: (для УВЕ/АЕ) приложения должны вызвать
ЕпаеОггес4Ассезз, прежде чем переключать банки
+025: байт - атрибуты окна А:
бит 1: окно существует
бит 2: чтение из окна разрешено
бит 3: запись в окно разрешена
+03Ъ: байт -— атрибуты окна В
+045: слово — гранулярность окна — число килобайтов, которому всегда кратен
адрес начала окна в видеопамяти (обычно 64)
+06Ъ: слово — рамер окна в килобайтах (обычно 64)
+081: слово — сегментный адрес окна-А (обычно 0А000В)
+0АЪ: слово — сегментный адрес окна В
КОЗНИНИИИНИИ | Основы программирования для М$ 005
+

+0СЬ: 4 байта — адрес процедуры перемещения окна (аналог подфункции 05Ъ, но


выполняется быстрее)
‚ +105: слово — число целых байтов в логической строке
+12Ь; слово’ — ширина в пикселах (для графики) или символах (для текста)
+148: слово — высота в пикселах {для графики) или символах (для текста)
+161: байт - высота символов в пикселах
+176: байт — ширина символов в пикселах
+181: байт — число плоскостей памяти (4 — для 16-цветных режимов, 1 — для
обычных, число переключений банков, требуемое для доступа ко
всем битам (4 или 8),- для модели памяти 5)
+195: байт - число битов на пиксел
+1АЪ: байт - число банков для режимов, в которых строки группируются в бан-
ки (2 — для ССА, 4 - для НСС)
+1ВЬ: байт — модель памяти: |
00Ъ -— текст
016 - ССА-графика
02. - НСС-графика
0ЗЬ - ЕСА-графика (16 цветов)
04%:-УСА-графика (256 цветов в одной плоскости)
05Ъ—Режим Х (256 цветов в разных плоскостях)
06Ъ - ВСВ (15-битные и выше)
07. - УЦУ
08Ь — ОЕВ — зарезервированы УЕЗА
106— ЕЁЕВ- нестандартные модели
)
+1 СЪ: байт— размер банка в килобайтах (8—для ССА и НСС, 0 - для остальных
+10Ъ: байт- число видеостраниц.
+1ЕЬ: байт — зарезервирован'
+1ЕЪ: байт - битовая маска красной компоненты
+20Ъ: байт — первый бит красной компоненты
+21}: байт - битовая маска зеленой компоненты
+221: байт - первый бит зеленой компоненты
+238: байт — битовая маска синей компоненты `
+245: байт — первый бит синей компоненты
` +258: байт— битовая маска зарезервированной компоненты
+261: байт- первый бит зарезервированной компоненты
+27Ъ: байт- бит 0: поддерживается перепрограммирование цветов (подфункция 09
бит 1: приложение может использовать биты в. зарезервированной
компоненте
+285: 4 байта-физический адрес начала ГЕВ
+2СЬ: 4 байта — смещение от начала ЕЁЕВ, указывающее на первый байт после
конца участка памяти, отображающейся на эйране
+301: слово— размер памяти в Г.ЕВ, не отображающейся на экране, в килобайтах
+325: 206 байт — зарезервировано
Графические видеорежимъы:. .

ГМТ 10Р АН = 4Е}, АГ. = 02: Установить режим


Вход: АХ = 4Е02Ь ..
ВХ= номер режима:
биты 0-6: собственно номер режима `
бит 7: видеопамять не очищается при. установке режима, если все
следующие биты — нули
бит 8: стандартный УВЕ ЗУСА-режим
бит 9: нестандартный $УСА-режим
биты 10-12: зарезервированы |
бит 13: режим использует аппаратное ускорение
бит 14: режим использует СЕВ ,
бит 15: видеопамять не очищается при установке режима.
Кроме того, специальный номер режима 81ЕЕЬ соответствует доступу ко всей
видеопамяти и может использоваться для сохранения ее содержимого.
Выход: АГ. = 4ЕЬ, если функция поддерживается
АН = 00, если режим установлен
АН= 01 или 02, если произошла ошибка
ГУТ 10Ё АН= 4, АГ= 03: Узнать номер текущего видеорежима
Вход: АХ =4РОЗЬ
Выход: АГ.ЕВ,
= если функция поддерживается
ВХ = номер режима
МТ 10Е АН= 4ЕВ АГ.= 05: Перемещение окна (переключение банка видеопамяти)
Вход: АХ= 405
ВН= 00 - установить окно
ВН = 01 - считать окно
ВЕ,= 00 - окно А
ВТ.= 01 - окно В
ОХ -адрес окна в единицах гранулярности (номер банка), если ВН =0
Выход: АТ,= 4ЕВ, если функция поддерживается
ОХ= адрес окна в единицах гранулярности (номер банка), если ВН:=1
АН= 03, если функция была вызвана в режиме, использующем ГЕВ
Всегда предпочтительнее переключать банки прямым дальним вызовом проце-
дуры, адрес которой возвращается подфункцией 01Ь в блоке информации о видео-
режиме. Все параметры передаются в процедуру точно так же, как ив подфункцию
05Б, но содержимое регистров АХ и ОХ по возвращении не определено. —
ГУТ 108 АН= 4Ё} АЕ= 07: Установка начала изображения
Вход: АХ= 4Е07Ь
+
ВН= 00
ВУ.- 00 — считать начало изображения
‚ ВИ.= 80В- установить начало изображения (в УВЕ 2.0 автоматически
выполняется при следующем обратном ходе луча)

% Зак. 459
| Основы программирования для М5 205. |
СХ = первый изображаемый пиксел в строке (для ВГ. = 80В)`
.Х = первая изображаемая строка (для В1. = 801)
Выход: АГ.= 4ЕВ, если функция поддерживается
АН = 01, если произошла ошибка `
АН = 00, если функция выполнилась успешно
ВН = 00 (для ВИ. = 00)
СХ = первый изображаемый пиксел в строке (для ВТ. = 00)
ОХ = первая изображаемая строка (для ВТ. = 00)
С помощью этой функции можно выполнять как плавный сдвиг экрана, пере-
мещая начало изображения на одну строку за один раз,так и быстрый показ двух
разных изображений, изменяя одно, пока на экране находится другое, — своего
рода эффект плавной анимации.
авт
; 3Сго1]13. |
‚ Изображает в разрешении 1024х768х64К окрашенный конус, который можно |
; плавно перемешать по экрану стрелками вверх и вниз.

.104е1 \1пу
.собе. . .
. 386 В ; Используется команда $ПгГ@.
ог9 100% ‚ СОМ-файл.
таг: . . .
моу ах, 4ЕО1В ; Получить информацию о видеорежиме.
моу сх, 1161 - ; 1024х768х64К
тоу 91, оРРзет мбе_тоде_Би!ГТег
1 . 108
‚ Здесь для простоты опущена проверка наличия режима.
оу ах, 47021 | ‚ Установить. режим.
оу ьх, 1161 |
10 108 | | | .
ризй мог рАг [УБе_поде_рБиЁТег+8] |
рор е$ ра Поместить в Е5 адрес начала видеопамяти
, . (обычно А000П).
с19

‹ Вывод конуса На экран.

оу сх, -1 ; Начальное значение цвета (белый).


моу $1, 100 :; Начальный радиус.
оу фх, 300 ; Номер столбца.
воу ах, 200 ; Номер строки.
ма1п_1оор: ‘
11с $1 ‚ Увеличить радиус круга на 1.
1пс ах у | ; Увеличить номер строки.
фпс Ьх ; Увеличить номер столбца.
са11 фаз®_с1гс]е ; Нарисовать круг:
ИБ р сх, 00001000001000016 - ‚ Изменить цвет.
стр 81,350 ; Если еще не нарисовано 350 кругов,
Графические видеорежимы
36 ма1п_}юор ; продолжить.
хог сх, сх ; Иначе: выбрать черный ‚цвет,
са11 Тазт_с1гс1е ; нарисовать последний круг.

‚ Плавное перемещение изображения по экрану с помощью функции 4Р07В.

хог Ьх, 6х ; ВХ = 0 - установить начало экрана.


хоГ 9х,9х ; Номер строки = 0. .
; Номер столбца в СХ уже ноль.
та1п_100р_2:
тоу ах, 4РО7Н
11 10н ; Переместить начало экрана.
оу ап,7 ; Считать нажатую клавишу с ожиданием, без эха
ат 21н ; и без проверки на Суг1-Вгеак.
Тезт а], а] | ; Если это обычная клавиша -
12 ех1{ -1о0ор_2 ; завершить программу.
111 218 ;. Иначе: получить расширенный АЗСТТ-код.
стр а1, 50Н ‚ Если это стрелка вниз
е Кеу_Чомп
сир а1, 481 ; или вверх - вызвать обработчик. |
де Кеу_ир
2х11_100р_2: ; Иначе - завершить программу.
моу ах,3 „; Текстовый режим.
111 108
гет ; Завершить СОМ-программу.

#2у домп: ; Обработчик нажатия стрелки вниз.


дес 9х ‚ Уменьшить номер строки начала экрана.
1$ та1п_]оор_2 ; Если’ знак не изменился - продолжить цикл.
; Иначе (если номер был 0, а стал -1) -
; увеличить номер строки. у
ч2у_ир: ; Обработчик нажатия стрелки вверх.
19с 9х ; Увеличить номер строки начала экрана.
лир эПогЕ ма1п_100р:2

Процедура вывода точки на экран в -16-битном видеорежиме.


Вход: ОХ = номер строки, ВХ = номер столбца, Еб = 040001, СХ = цвет.
Модифицирует АХ.
р.1р1хе1166:
ризй ах
ризй 91
хог 91,91
эго 91, 9х, 6 ; 01 номер строки х 1024 тод 65 536.
$Вг дх,5 ; ОХ = номер строки / 1024 х 2.

9х, сиггепт _Бапк ‚ Если номер банка для выводимой точки
рапк_ м1 Тсв ‚ отличается то текущего - переключить банки.
Зи 1{СНед:
а9д 91, 5х ‚ ‘Добавить к ОТ номер столбца.
ах, сх ‚ Цвет в АХ.
св Основы программирования для. М5 005
$11 91,1 ; ОТ = ОГ х 2, так как адресация идет в словах.
$103 ; Вывести точку на экран.-
‚рор 91 . ; Восстановить регистры.
рор 9х у
гет
Бапк_ змс: ; Переключение банка.
ризв 5х р
_хог ьх, 5х ; ВХ = 0 -> установить начало экрана.
моу сиггепт_Балк,9х ; Сохранить новый номер. текущего банка.
са11 ного рег [\Бе_тоде_БиЕег+0Сп] : Переключить банк.
рор 5х р
‚ тр пог эм Еспед

‚ Алгоритм рисования круга, используя только сложение, вычитание и сдвиги


' (упрощенный алгоритм промежуточной точки).
; Вход: 51 = радиус, СХ = цвет, АХ = номер столбца центра. круга.
; ВХ = номер строки центра круга модифицирует ОТ, 0Х. |
Тазт_с1гс1е: `
ризй $1 пре
ризп ах =
ризй ох
хог ° 91, 91 | . ОТ - относительная Х-координата текущей точки.
‚бес “а т ' (51 - относительная У-координата, начальное
тоу ах, 1 ‚ значение - радиус).
зи6 ах, 31 Г :.АХ - наклон (начальное значение 1-Радиус).
©1гс1е_1оор:
1пс 91 ‚ Следующий Х (начальное значение - 0).
стр 91, 31 | ; Цикл продолжается, пока Х < У.
за ех1*_та1п_1оор |
рор 6х ; ВХ =.номер строки центра. круга.
рор 9х ; ОХ = номер столбца центра круга.
ризп 9х
рузВ 5х
ризй ах о : Сохранить АХ (риутрфхе116Ь его изменяет).
аа Бх, 91 ‚ Вывод восьми точек на окружности:
ада Хх, $1
са11 руфр1хе1 166 ‚ центр_Х + Х, центрУ + \,
зи ЧХ, $1
зиБ 9х, 51 |
са11 ри р1хе116Ь : ; ‘центр_Х + Х, центр
У ’- \,
ЗУБ х,:91
.ЗиБ Ьх, 91 2. : р
‚ ва11 ритр1хе1166 ‚ центр_Х - Х, центр_\ -. У\,,
ааа. ах, $1.
ада 9х, 51 |
са1] ритр1хе1 166 ‚ центр_Х - Х, центр_\У + \,
$6 Чх, $1
‘ааа 9х,91
\

Графические видеорежимы ` И 165


а99 Ьх,91
ав 5х,51
са11 ритр1хе1 166 ; ‘центр_Х + \, центрУ + Х,
зиБ дх,91
ЗиЬ 9х, ’ |
са11 ритр1хе116ь ; центр_Х + Х,- центр_\ - Х,
$и6 Ьх, $1
$46 Ьх,$1
са] 1 рифр1хе1 166 ; центр_Х - \, центр_\ - Х,
ада Чх,91
а99 Чх,91
са1] ритр1хе1 166 ; центр_Х - \, центр_У + Х.
рор ах

тет . ах, ах -_. ; Если наклон: положительный,


$ 31ор_педа{1уе В -
пом 9х, 91
$и6 9х, $1
$1] ах, 1 ,
1пс 9х
ада ах, 9х ‚<; наклон = наклон + 2(Х - У). +1,
дес $1 С У=У-Т
тр с1гс1е_]оор
$1ор_педа*1уе: ; Если наклон’ отрицательный,
мо 9х, 91.
ЗН ах, 1
1пс . ах
ада ах, ах | ‚ наклон = наклон + 2Х + 1,
Эр с1гс1е_10оор ; и У не изменяется.
ех1{_та1п_Тоор:
‚ рор Ьх
рор ах
рор $1 |
гет

сиггепт_Бапк дм 0 ; Номер текущего банка. .


уре_моде_Би{Рег: ° р Начало буфера данных ©’ видеорежиме.
епа зТаг+ |

В этом примере для наглядности отсутствуют необходимые проверки на под-


держку УВЕ (все прерывания должны возвращать 4ЕВ в АГ.), на поддержку ви-
деорежима (атрибут видеорежима в первом байте буфера, заполняемого подфун-
кцией 02) или на объем видеопамяти (должно быть как минимум 2 Мб) и на
другие ошибки (все прерывания должны возвращать 0 в АН). ,
Для вывода точки на экран используется выражение типа’
номер_банка = номер_строки х байт_в-строке / байт_в_банке
смещение = номер_строки х байт_в_строке №00 байт_в_банке
+

м6! Основы программирования для М$ 00$.


Но так как и число байтов в строке; и число байтов в банке являются степеня-
ми двойки, умножение, деление и вычисление остатка от деления можно заменить
более быстрыми операциями сдвига, как это сделано в процедуре риёрихе!1 6Ъ.
Переключение банков всегда отнимает значительное время, так что по возмож-
ности программированием для ЗУСА-режимов лучше всего заниматься в 32-бит-
ном режиме с линейным кадровым буфером, например используя ОО5$-расшири-
тели, как показано в разделе 6.4.

4.6. Работа ‹ мышью.


Все общение с мышью в РО$ выполняется через прерывание ЗЗВ, обработчик
которого устанавливает драйвер мыши, загружаемый обычно при запуске сис-
темы. Современные драйверы поддерживают около 60 функций, позволяющих
настраивать разрешение мыши, профили ускорений, виртуальные координаты,
дополнительные обработчики событий и т. п. Большинство этих функций требу-
ются редко, сейчас рассмотрим основные.
МТ 331, АХ = 0: Инициализация мыши
Вход: АХ = 0000.
`Выход: АХ= 00001, если мышь или драйвер мыши не установлены
АХ = ОЕ, если драйвер и мышь установлены
ВХ = число кнопок:
0002 или ОЕЕЕЕН - две
0003 — три
9000— другое количество |
Выполняется аппаратный и программный сброс мыши и драйвера.
[№Т 334, АХ = 1: Показать курсор
Вход: АХ = 0001
ПМТ 33, АХ = 2: Спрятать курсор
Вход: АХ = 0002. |
Драйвер мыши поддерживает внутренний счетчик, управляющий видимостью
курсора мыши. Функция 2 уменьшает значение счетчика на единицу, а функция 1
увеличивает его, но`только до значения 0. Если значение счетчика — отрицатель-
ное число, он спрятан, если ноль— показан. Это,позволяет процедурам, использу-
ЮЩиМ прямой вывод в видеопамять, вызывать функцию 2 в самом начале и 1 в са-
Мом конце, не заботясь о том, в каком состоянии был курсор мыши у вызвавшей .
эту процедуру программы.
Т№Т 33, АХ = 3: Определить состояние мыши
Вход: АХ= 0003
Выход: ВХ = состояние кнопок:
бит 0: нажата левая кнопка
бит 1: нажата правая. кнопка
бит 2: нажата средняя кнопка
Работа с мышью
СХ = Х-координата,
Ъх =- У-кобрдината.
Возвращаемые координаты совпадают с координатами пикселов соответству-
ющей точки на экране в большинстве графических режимов, кроме 04, 05, ООВ,
1ЗБ, где Х-координату мыши нужно разделить на 2, чтобы получить номер стол-
бца соответствующей точки на экране. В текстовых режимах обе координаты надо
разделить на 8 для получения номера строки и столбца соответственно.
В большинстве случаев эта функция не используется в программах, так как для
того, чтобы реагировать на нажатие кнопки или перемещение мыши в заданную
область, требуется вызывать это прерывание постоянно, что приводит к трате
процессорного времени. Функции 5 (определить положение курсора при после-
нем нажатии. кнопки), 6 (определить положение курсора при последнем отпус-
‚ хании кнопки) и ОВЬ (определить расстояние, пройденное мышью) могут помочь
оптимизировать работу программы, самостоятельно «следящей» за всеми пере-
‚ хвижениями мыши, но гораздо эффективнее указать драйверу контролировать ее
передвижения (чем он, собственно, и занимается постоянно) и передавать управ-
ление в программу, как только выполнится заранее определенное условие, напри-
мер пользователь нажмет на левую кнопку мыши. Такой сервис обеспечивает
функция ОСЬ- установить обработчик событий.
ГУТ 33}, АХ = ОСВ: Установить обработчик событий
Вход: АХ = 000СЬ | р
ЕЗОХ = адрес обработчика
СХ = условие вызова
бит 0: любое перемещение мыши
бит 1: нажатие левой кнопки
бит 2: отпускание левой кнопки
бит 3: нажатие правой кнопки
бит 4: отпускание правой кнопки о №
бит 5: нажатие ередней кнопки °’ .
бит 6: отпускание средней кнопки
СХ = 00006 - отменить обработчик
Обработчик событий должен быть оформлен, как дальняя процедура. (то есть
завершаться командой ВЕТЕ). На. входе в процедуру обрабтчика АХ содержит.
условие вызова, ВХ -— состояние кнопок, СХ, ОХ- Х- и У-координаты курсора,
51, ОЕ - счетчики последнего перемещения по горизонтали и вертикали (едини-
пы измерения для этих счетчиков — мики, 1/200 дюйма), 0$ — сегмент данных.
драйвера мыши. Перед завершением программы установленный обработчик со- .
бытий должен быть обязательно удален (вызов функции ОСВ с СХ= 0), так как.
иначе при первом же выполнении условия управление будет передано по адресу
в памяти, с которого начинался обработчик.
Функция ОСВ используется так часто, что у нее появилось несколько мдифи-
каций— функция 14$, дающая возможность установить одновременно три обра-
ботчика с разными условиями,и функция 18}, также позволяющая установить
№1! Основы программирования для М$ 005
три обработчика и включающая в условие вызова состояние клавиш ЗЫ, СЫ]
и А. Воспользуемся обычной функцией ОСЬ, чтобы написать простую програм-
му для рисования.
; точзедг.
азт
; Рисует на экране прямые линии, оканчивающиеся в позициях, которые указываются мышью.

.1оде1 лу
. соде
ого 1008 СОМ-файл.
. 186 Для команды эйг сх,3.
эТагт:
моу ах, 12Н
Ти 1оН Видеорежим 640х480.
ие ах.0 Инициализировать мышь.
111 338
моу ах,1 Показать курсор. мыши.
11 ЗЗВ

оу ах, 00008 Установить обработчик событий мыши.


моу сх, 00028 Событие - нажатие левой: кнопки.
оу „9х, оРРзет папа]ег ЕЗ:0Х - адрес обработчика.
11 338

моу ан,0 Ожидание нажатия любой клавиши.


- 10 161
пом. ах, 000Си
поу. сх, 00008 Удалить обработчик событий мыши.
11. ЗЗИ
оу ах,3 Текстовый режим.
111 10Н
гет Конец программы.
; Обработчик событий мыши: при первом нажатии выводит точку на экран,
; при каждом дальнейшем вызове проводит. прямую линию от предыдущей
‚; Точки к текущей.

папа] ег: :
ризп 0А0О0В
рор е5 ЕЗ - начало видеопамяти.
и
ризй 65
_ рор 9$ 0$ - сегмент кода и данных этой программы.
рузп сх СХ (Х-координата) и ОХ. (У-координата)
ризп 9х потребуются в конце.

оу ах,2 Спрятать курсор мыши перед`выводом на экран.


11 33”

| стр. мог рег ргем1оиз_Х,-1 Если это первый вызов,


]е 13 роте только вывести точку.
са]11 ]1пе_ргезеппат Иначе -. провести прямую.
Работа с мышью Вода
ыыы 169
ех{_папд ег:
рор ах Восстановить СХ и БХ
рор сх
поу ргем10и$_Х,сх и запомнить их как предыдущие
тоу ргеу1оиз_У,
дх координаты.

том ах,1 Показать курсор мыши.


17т. ЗЗА

гетЕ Выход из обработчика - команда ВЕТЕ.


Грот:
са11 ритр1хе116 Вывод одной точки (при первом вызове).
тр эПОГЕ ех1{_пап
ег
Процедура рисования прямой линии с использованием алгоритма Брезенхама.
Вход: СХ, ОХ -Х, \У конечной точки,
ргеу10и$_Х, ргем1ои$_У - Х, у начальной точки.

-:пе_Ьгезеппаю:
У ах, сх
зи ах, ргеу10и$_Х АХ = длина проекции прямой на ось Х.
]пз 9х_роз Если АХ отрицательный -
пед ах сменить его знак, причем
оу мог@ рЕг Х_1псгетепт, 1 координата Х при выводе
тр ЗВогЕ 9х_пед прямой будет расти.
:'_00$: МОУ мога рфг Х_1псгетепт,-1 Иначе - уменьшаться.
пед: моу Ьх, 9х
$и6 Ьх, ргеу1оиз_У ВХ = длина проекции прямой.на ось У.
]п$ Чу_роз Если ВХ отрицательный -
пед Ьх сменить его знак, причем
оу мог4 рег У_1псгемепт,1 координата У при выводе /
тр ЗПогЕ Чу_пед прямой .будет расти.
т. роз: поу мог руг \У_1псгетепт,-1 Иначе - уменьшаться.

$11 Удвоить значения проекций,


501 чтобы избежать работы с полуцелыми числами.
са11 ° рур1хе11ь Вывести первую точку (прямая рисуется от
СХ,ОХ к ргем1оиз_Х, ргем1оиз_\).
стр ах, ох Если проекция на ось Х больше, чем на У,
]па х_1е_ду
оу 91, ах ОТ будет указывать, в какую сторону мы
Аг 91,1 Отклонились от идеальной прямой.
пед 91 Оптимальное начальное значение ОТ:
` ааа 91,6х ОТ = 2 + ау - 9х
= 7е:
стр сх, мог рфг ргем1оиз_Х Основной цикл выполняется,
де ех1{_Бгез пока Х не станет равно ргеуфои$_Х.
стр 91,0 Если ОТ > 0,
71 Ггаст110
и

№! Основы программирования
для М$ 005$
ада дх, мог раг У 1псгетепт ; перейти к следующему У
зи6 91, ах ‚ и уменьшить 0Т на 2 * 9х.
Ёгаст1 10: у
а93 сх, мога рфг Х_1псгетепе ; Следующий Х (на каждом шаге).
а94 91, 5х ; Увеличить ОТ на 2 + ду.
‚ са1 1 ритр1хе1 1. ; Вывести точку.
ар эпогЕ сус1е ; Продолжить цикл.

9х_]е_ду: | ; Если проекция на ось У больше, чем на Х.


мо 91, 6х
$Иг 91,1
лед | ` ; Оптимальное начальное значение ОТ:
ад9 $1, ах : Т=2+дх - ду.
сус1е2: ` | .
стр дх,мога рёг ргеуфоиз_У `°_; Основной цикл выполняется,
]е ех1{_Бгез ; пока У не станет равным ргеу1ои$_У.
‘стр 91,0 ; Если ОГ > 0, `
71 {гаст1102
ава сх, мога рег Х_1псгетепе $; перейти к следующему Х
$0 вх: | ; и уменьшить ОТ на 2 * ду:
Ггаст1102: ... В: , и
а99 “ дх, мога рег У_1тсгетепЕ ; Следующий У (на каждом шаге).
а99 ° 91, ах ‚ Увеличить ОТ на 2 * ду,
са11 рир1хе116 - ; вывести точку,
тр зНогЕ сус1е2 °_; продолжить цикл.
ех11_6гез:
гет ‚ Конец процедуры.

; Процедура вывода точки на’экран в режиме, использующем один бит для


; хранения одного пиксела. ` :
ОХ = строка, СХ = столбец. .
; Все регистры сохраняются. > . /

ритрухетль:
ризва = . ; Сохранить регистры.
хог Ьх, 6х .
пом ах, 4х ; АХ = номер строки.
1ти ах, ах, 80 ; АХ = номер строки х число байтов в строке.
ризН сх | _
‘8Вг сх, 3 | “СХ = номер байта в строке. `
ава ах, сх -:! АХ = номер байта`в видеопамяти:
‚ 0 91, ах ; Йоместить его в. ЭТ и ОТ для команд": ^
бу , 51,91 .`. 4 строковой обработки. .

‘рор хо СХ снова содержит номер столбца.


° ПУ `ьх, 0080 | |
ава сх.078''° ^- =: Последние три бита ‘СХ =
.: .: обтаток от деления на 8 = ‘номер бита в байте
В _: ‘считая справа налево. ; ‘
и узВг. > 6х; по; Теперь в ВЕ установленгв 1нужный бит.
Другие устройства
1048 е$: буте рег зоме.:Дабе1 ; АЁ = байт из видеопамяти.
ог ах, Бх ; Установить выводимый бит в 1,
; Чтобы стереть пиксел с экрана, эту команду ОВ можно заменить на
; Е вх
; апа ах, Бх
или лучше инициализировать ВХ не числом 00801, а числом ЕЕР7ЕА и использовать
только апа
то ; И вернуть байт на место.
рора | ; Восстановить регистры.
гет | ; Конец.

огеу10и$_Х [6 т -1 ; Предыдущая Х-координата.


ргеу104$_\ м -1 ‚ Предыдущая У-координата.
\_1псгетепт дм -1 . ; Направление изменения У.
Х_1псгетепте м . -1 | ; Направление изменения Х.
зоте_1абе]: ; Метка, используемая для переопределения
; сегмента-источника для 1049$ с 0$ на Е$.
епд этагт
й

Алгоритм Брезенхама, использованный в нашей программе, Является самым


распространенным алгоритмом рисования прямой. Существуют, конечно, и более
эффективные, например алгоритм Цаолинь Ву, работающий по принципу конеч-
ного автомата, но алгоритм Брезенхама стал стандартом де-факто.

Реализовать этот алгоритм можно гораздо быстрее при помощи самомо-


дифицирующегося кода, то есть после проверки на направление прямой в на-
чале алгоритма вписать прямо в дальнейший текст программы команды
Л№С СХ, БЕС СХ, 1№МС ОХ и РЕС ОХ вместо команд сложения этих регис-
тров с переменными Х_тстетете и У_тстететё. Самомодифицирующийся
код часто применяется при программировании для ОО$5, но в большинстве
многозадачных систем текст программы загружается в область памяти,
защищенную от записи, вот почему в последнее время зона : применения это-
го подхода становится ограниченной.

4.7. Другие устройства _


4.7.1. Системный таймер
Начиная с ВМ АТ, персональные компьютеры содержат два устройства для
управления процессами — часы реального времени (ЕТС) и собственно систем-
ный таймер. Часы реального времени получают питание от аккумулятора на ма-
теринской плате и работают даже тогда, когда компьютер выключен. Это устрой-
ство можно применять для определения/установки текущих даты и времени,
установки будильника с целью выполнения каких-либо действий и для вызова
прерывания 1ВО8 (1МТ 4АБ) каждую миллисекунду. Системный таймер исполь-
зуется одновременно для управления контроллером прямого доступа к памяти,
для управления динамиком и как генератор импульсов, вызывающий прерывание
ГВО0 (ПМТ 8) 18,2 раза в секунду, Таймер предоставляет богатые возможности
МЕ Основы программирования для М$ 00$
для препрограммирования на уровне портов ввода-вывода, но на уровне 2О$
и ВТО$ часы реального времени и системный таймер используются только как
средство определения/установки текущего времени и ‘организации задержек,
Функция РО$ 2Ай: Определить дату
Вход: АН = 2АЁ -
Выход: СХ = год (1980-2099)
ОН= месяц
ГГ.= день
. АГ = день недели (0 — воскресенье, 1- понедельник. .)
Функция 20$ 2С#: Определить время
Вход: АН = 2СЬ
Выход: СН = час
СТ. = минута
ОН = секунда
ОТ, = сотая доля секунды
Эта функция использует системный таймер, поэтому время изменяется толь-
ко 18,2 раза в.секунду и число в 01. увеличивается сразу на 5 или 6.
Функция 2О$ 28В!: Установить дату
Вход: АН =2ВЬ
СХ = год (1980— 2099)
ОН = месяц
ОТ.= день
Выход: АН= РЕВ, если введена несуществующая дата; АН = 00}, если дата
установлена
Функция 0О$ 201: Установить время
Вход АН = 20
СН = час
СТ. = минута
ОН = секунда
ОТ. = сотая доля секунды
Выход: АТ.= ЕЁЬ, если введено несуществующее время, и АЕ.= 00, если время
установлено
Функции 2ВВ и 20 устанавливают одновременно как внутренние часы РО5,
которые управляются системным таймером и обновляются 18,2 раза в секунду,
так и часы. реального времени. ВТО$ позволяет управлять часами напрямую.
Т№Т ЛАЙ АН = 04#: Определить дату ВТС
Вход: АН= 046
Выход: СЕ= 0, если дата прочитана
СХ = год (в формате ВСЮ, то есть 2001Ъ для 2001-го ‘тода)
РН= месяц (в формате ВСО)
. ОГ = день (в формате ВСО)
Другие устройсва _ ООС ОСЗ
СЕ = 1, если часы не работают или попытка чтения. пришлась на мо-
мент обновления ::
‚ МТ ТАЙ АН = 028: Определить время ВТС
Вход: АН = 025
Выход: СЕ = 0, если время прочитано =
СН = час (в формате ВСО)
СТ.= минута (в формате ВСР)
ОН = секунда (в формате ВСО)
ОТ.= 01Ъ, если действует летнее время; оо, если нет
СЕ = 1, если часы не работают или попытка чтения пришлась на мо-
мент обновления .
ГУТ ТАЁ АН = 05й: Установить дату КТС
Вход: АН = 056
СХ = год (в формате ВСВ)
ОН = месяц (в формате ВСО)
Ру. = день (в формате ВСО).
ГУТ 1АЁ АН = 031: Установить время ВТС
Вход: АН = 036
СН = час (в формате ВСО)
СГ. = минута (в формате ВСО)
ОН =секунда (в формате ВСО)
ОГ = 011, если используется летнее время, 0 - если нет
Кроме того, ВТО$ позволяет использовать ВТС для организации будильников
№ задержек.

УТ 1АЁ АН = 06; Установить будильник


Вход: АН = 06,
СН = час (ВСЬ)
СГ.= минута (ВСР).
ОН = секунда (ВСО)
’ Выход: СЁ = 1, если произошла ошибка (будильник уже установлен или
и преры
вание вызвано в момент обновления часов); ^^
СЕ= 0, если будильник установлен
Теперь каждые 24 часа, когда время совпадет с заданным, часы реального’ време-
ни вызовут прерывание [8.08 (ТТ 4АВ), которое должна обрабатывать установив-
игая будильник программа. Если при вызове СН = ОЕЕВ, СТ.=ОЕ ЕВ, а рН> ов,
ю$ будильник начнет срабатывать |раз В минуту.

№№ Г ТАВ АН= 07: Отменить будильник


Входз АН = 07
Эта функция позволяет отменить будильник, например для того, чтобы уста-
№"-вить его на другое время. о
№!!! Основы программирования для.М$ 00$
ВТО$ отслеживает каждый отсчет системного таймера с помощью своего об-
работчика прерывания 1КО0 (ТМТ 81) и увеличивает на 1 значение 32-битного
счетчика, который располагается в памяти по адресу 00005:046СЬ, причем во вре-
‚ мя переполнения этого счетчика байт по адресу 00001:04701 увеличивается на 1.
Т№Т 1АЁ АН = 001; Узнать значение счетчика времени
Вход: АН =.00,
Выход: СХ:ОХ - значение счетчика
АГ. = байт переполнения счетчика

МТ ТАЙ АН = 018: Изменить значение счетчика времени


` Вход: АН = 018
СХ:ОХ - значение счетчика -
Программа может считывать значение этого счетчика в цикле (через прерывание
или просто командой МОУ)`и организовывать задержки, например, пока счетчик:
не увеличится на 1. Но так как этот счетчик использует системный таймер, мини-
мальная задержка будет равна приблизительно 55 мкс. Частоту таймера можно
изменить, программируя его.на уровне портов, но В1О$ предоставляет для этого
специальные функции.
ИМТ 151 АН = 86й: Формирование задержки
Вход: ‘АН = 86.
_СХ.ОХ- длительность задержки в микросекундах (миллионных долях
; секунды!) ,
Выход: АГ.= маска, записанная обработчиком в регистр управления прерыва-
нИями
СЕ = 0, если задержка выполнена
СР = 1, если таймер был занят
Если нужно запустить счетчик времени и продолжить выполнение програм-
мы, можно воспользоваться еще одной функцией.

ГМТ 158 АН= 83#: Запуск счетчика времени


Вход: —АН= 83
АГ, = 0 - запустить счетчик
СХ:.ОХ - длительность задержки в микросекундах
ЕЗ:ВХ - адрес байта, старший бит которого по окончании работы
счетчика будет установлен в 1
АТ. = 1 - прервать счетчик
| _ Минимальный интервал для этих функций на большинстве систем обычно
составляет около 1000 микросекунд. Воспользуемся функцией организации за-
держки для небольшой интерактивной игры:
; могт. ат о.
; Игра “Питон” (или “Змея”, или “Червяк”). Управление осуществляется
.; курсорными клавишами. Питон погибает, если он выходит за верхнюю
; ‘или нижнюю. границу экрана либо` самопересекается.
Другие устройства
.тоде] {1пу
.соде . .
. 186 | ; Для команды ризй ОА0Оп.
0г9 1008 ; СОМ-файл. .
$Тагт: . ыы
моу ах, с$- ‚ Текущий сегментный адрес плюс
а9д ах, 10001 ; 10001 = следующий сегмент,
моу 9$, ах ‚ который будет использоваться
; для адресов головы и’ хвоста.
ризв . ОАОООН , ‚ ОА000А - сегментный адрес
рор- ез ; видеопамяти (в ЕЗ).
мом ах, 131 ; Графический режим 131.
111 108.

мо 91, 320*200
поу сх, 6008 ; Заполнить часть видеопамяти, .
` ; остающуюся за пределами
гер ЗТозЬ ; экрана, ненулевыми значениями
р $ (чтобы питон не смог’выйти за
, ; пределы экрана).
хог $1, $1 | ; Начальный адрес хвоста в 0$:51..
том р, 10 ‚: Начальная длина питона - 10.
Этр пи 009 ‚ Создать первую еду. |
та1п_сус]е:
‚: Использование регистров в этой программе:
; АХ - различное. °
ВХ - адрес головы, хвоста или еды на экране.
СХ - 0 (старшее слово числа микросекунд для функции задержки).
; ОХ - не используется (модифицируется процедурой гапбот).
; 0$ - сегмент данных программы (следующий после сегмента кода).
; ЕЗ - видеопамять.
; 0$:0Т - адрес головы.
; 0$:$Т - адрес хвоста. |
; ВР - добавочная длина (питон растет, пока ВР > 0; ВР уменьшается на каждом
; шаге, пока не станет нулем). |
моу ` ах, 20000 ; Пауза - 20: 000 мкс.
тоу ан, 861 . <; (СХ =0 после ВЕР. 51088
Г. ; и больше не меняется)
| 11 151 . ; Задержка.
| моу ап, 1 ‚ Проверка состояния клавиатуры.
171 161 _ | В
7 зПогЕ по_Кеургезз ; Если клавиша нажата -
хог . ап, ай ; АН=О0 - считать’ скан-код
10 ^ 168 `; нажатой клавиви в АН.
стр ап, 488 ; Если это стрелка вверх,
зле эПогф поф_ир ‚
тоу могд рфг сз: тоуе_Ч1гест1оп,
-320 ; изменить
‚ направление движения на “вверх”.
у

ШИ! Основы программирования для М5`005.

стр ай, 501 .,; Если это стрелка вниз,


пе ЗПогЕ лот_90мп
тому иога рфг с$:моме_91гест1оп,
320 : изменить ,
; направление движения на “вниз”
п0{_4омп: |
стр ` ап, 4ВИ ‚ Если это стрелка влево,
пе зпогЕ поф_1ет ‘
МОМ. мога р\г сз: поме_Ч1гест1оп, -1 ; изменить
‚ Направление движения на “влево”.
пот_1е1т;
стр ай, 408 ; Если зто стрелка вправо,
пе. ЗВог{ по_Кеургез$
моу мог рег сз:томе_Ч91гес(1оп,1 ;’ изменить
; направление движения на “вправо”.
по_кеургезз:.
апд ор, бр | ; Если питон растет (ВР > 0),
712 ЗПогЕ адуапсе_Пеад ; пропустить стирание хвоста.
1043м ‚; Иначе: считать адрес хвоста из
, ; 05:51 в АХ и увеличить ЭТ на 2.
ХСп9 Бх, ах . |
оу Буте рфг ез:[6х],0 ; Стереть хвост на’экране.
моу Ьх, ах |
1пс Бр - ; Увеличить ВР, чтобы следующая
‚ команда вернула его в 0.
адуапсе_Пеаа: ,
дес Бр ‚ Уменьшить ВР, так как питон
; вырос на 1, если стирание хвоста
; было пропущено, или чтобы вернуть его
; в О - в другом случае.
ада ох, мога ртг с$:тоуе_91гест1оп
‚ 6х = следующая координата головы.
оу а1, ез;[Ьх] у ; Проверить содержимое экрана в точке
; с этой координатой.. -
апа а], а1 ‚ Если там.ничего нет,
ру ЭПогЕ томе могт ; передвинуть голову.
стр а1, 00 р ‚ Если там еда, .
де пог ‘дгом_могт ‚ увеличить длину питона.
поУ` ах, 3 - ; Иначе - питон умер,
19 ов ; Перейти в текстовый ‘режим
гетп ; и завершить программу.

тоуе_могт;: . :
моу [91], 6х ; Поместить адрес головы в 05:01
11с 91
1пс 91 ; и увеличить ОТ на 2.
оу Буте руг ез:[6х],09 ; Вывести точку на экран.
стр ‚ Бу рёг сз:еатеп_Тооа,1 ; Если предыдущим
| ‚; ходом была съедена`еда -
Другие устройства. ГД ПОНИИСУ
3]е 1{_еатеп_4009 создать новую еду.
тр зпог - пай п_бус1е Иначе - продолжить основной цикл.

170 мог:
. ризй Ьх у = Сохранить адрес головы.
оу 6х, мог4 рег с$:10049_ат ВХ - адрес еды,
хог ах, ах _ АХ = 0.
са11 Чгам_Роо@ Стереть еду.
са! 1 гапдот АХ - случайное число.
апд ах, ЗРВ _; АХ - случайное число от 0 до 63.
мо Бр, ах : Это число будет добавкой
| к длине питона. |
оу Буте рёг сз:еатеп_Тоод, 1 Установить флаг
; для генерации еды на следующем ходе.
рор Ьх , Восстановить адрес головы ВХ.
пр зНогт тоуё_могт Перейти к движению питона.

-# еатеп_Тоо4: ; Переход сюда, если еда была съедена.


моу Буте руг сз:еатеп_Коод,0 Восстановить: флаг.
пи Р009: Переход сюда в самом начале.
ризН Ьх Сохранить адрес головы.
таке_1о09: |
_ са гапдот . АХ - случайное число.
апа ах, ОРЕРЕВ АХ - случайное четное число.
оу Ьх, ах ВХ - новый адрес для еды.
хог ах, ах
тр мог р1г ез:[5х],ах Если по этому адресу
находится тело питона,
пе маКе_Ёоод , еще раз сгенерировать случайный адрес.
стр мога руг ез:[6х+320],ах Если на строку ниже
находится тело питона -
Эпе таке_РооЧ то же самое.
тоу могд ртг сз:1009_ат,5х Поместить новый адрес
| ‚ еды в Гоод_ат,
поу ах, 00000 цвет еды в АХ и
са11 дгам_Роод нарисоваты еду на экране.
рор Ьх
Этр тма1п_сус1е

Процедура Чгам_Тоо8.
Изображает четыре’ точки на экране - две по адресу ВХ и две на. следующей
строке. Цвет первой точки из пары - АЁ, второй - АН.

дгам_Роо4:
` тоу ез:[Ьх},ах
ОУ могд ртг ез: [6х+320],ах
гетп._
; Генерация случайного числа. ‘ .
; Возвращает число в АХ, модифицирует:
ОХ.

гапдот: моу ах, могв` раг сз:зеед


ЕРШ | Основы программирования для М5 005
пох Ох. ВЕАбА | о
и; 9х
‚ ес ах
пом сз:мог@ рАг зеед, ах Иа
гетп '.
‚ Переменные.

еатеп_Тоод а6 0 Са
тоуе_091гест10оп м 1 ° ; Направление движения: 1 - вправо,
; -1 - влево, 320 - вниз; -320 - вверх.
зеед: ; Это число хранится за концом программы,
Ро0д_а+ еди 3ее4+2 ; а это - за предыдущим.
епд зтагт |

4.7.2. Последовательный порт


Каждый компьютер обычно оборудован, до крайней мере, двумя последова-
тельными портами, которые чаще всего используются для. подключения мыши
и модема, а также других дополнительных устройств или соединения компьюте-
ров между собой. Для работы с устройствами, подключенными к портам, такими
как мышь, применяются драйверы, которые общаются с последовательным пор-.
том непосредственно на уровне портов ввода-вывода и предоставляют програм-
мам некоторый набор функций более высокого уровня, так что прямая работа
с последовательными портами оказывается необходимой только при написании
таких драйверов, работе с нестандартными устройствами или с модемами.
РО$5 всегда инициализирует первый порт СОМ как 2400 бод, 8М1 (8 бит в сло-
ве, 1 стоп-бит, четность не проверяется) и связывает с ним устройство 5ТРАЦХ,
куда функциями 3 и 4 можно записывать и откуда считывать один байт.
Функция р0$ 031: Считать байт из ЗТРАИХ
Вход: АН = 03р
Выход: А. = считанный байт
Функция 2О5 041: Записать байт в $ТРАОХ
Вход: АН= 048
ОТ. = байт
`’Можно также воспользоваться функциями записи в файл (401) и чтения из
файла (ЗЕЬ), поместив в ВХ число 3,как это показано ранее для вывода на экран.
Несмотря на то что есть возможность изменить установленную РО$ скорость
работы порта (2400 бод) командой МОПЕ, все равно отсутствие обработки оши-
бок, буферизациии гибкого управления.состоянием порта делает указанные функ-
ции РО5 практически неприменимыми. В1О$ позволяет управлять любым из
портов, писать и читать один байт и считывать состояние порта с помощью функ-
ций прерывания 14Ъ, однако, так же:как и ОО$, не допускает инициализацию
порта на скорость выше, чем 9600 бод. Таким образом выясняется, что многие
программы вынуждены программировать порты напрямую, ‘но, если в системе
присутствует драйвер; предоставляющий набор сервисов ЕОЗ$П. (такие как Х00
*

Другие устройства. `. .. | >


или ВМО), то для полноценного буферированного обмена данными последова-
тельными портами можно пользоваться лишь функциями прерывания 14Б.
МТ 14 АН= 04: Инициализация ЕО$5П.-драйвера
Вход: АН= 046
ОХ- номер порта (0 — для СОМ1, 1 - для СОМ2 ит.д.)
Выход: АХ = 19546
ВГ. = максимальный поддерживаемый номер функции
ВН - версия спецификации ЕО$$П-
Т№Т 144 АН- 05: Деинициализация ЕО$$1П-- драйвера
Вход: АН- 05
ОХ- номер порта (00в- 03)
МТ 14В АН= 00: Инициализация последовательного порта. .
Вход: АН= 00.
АТ,= параметры инициализации: _о
биты 7-5: о |
000 - 19 200 бод (110 бод без 0551.) о и
001 - 38 400 бод'(150 бод без ЕО$$1:)
010- 300 бод
011- 600604
100— 1200 бод
101- 2400 бод
_ 110- 4800 бод
111- 9600 бод ` `
биты 4-3: четность (01 — нечетная, 11 — ‘четная, 00 или 10 - нет)
бит`2: число стоп-битов (0 — один, 1 - два)
биты 1-0: длина слова (00- 5, 01 - 6, 10- 7,11 - о
ОХ- номер порта (00- 038)`
Выход: АН = состояние порта
бит 7: тайм-аут
бит 6: буфер вывода пуст (без ЕО$$П.: регистр сдвига передатчика
‚пуст)
бит 5: в буфере вывода есть место (без РО5$1: регистр хранения
передатчика пуст)
бит'4: обнаружено состояние ВВЕАК
бит, 3: ошибка синхронизации: _
бит2:ошибка четности бе. :
бит 1: ошибка переполнения= данныее потеряны к
бит 0: в буфере ввода есть данные |
‚ АГ. = состояние модема ки
бит: обнаружена несущая' (состояние линии ОСЬ) в
бит 6: обнаружен звонок (состояние линии ВТ)
‚ бит,5: запрос для передачи «состояние линии О5К). .
бит4:сброс. для передачи {состояние яинии СТ5) .
ЕЕТИНИШИИИНИИИ И" Основы программирования для М$ 2О$`
бит 3: линия ОСО изменила состояние
бит 2: линия В] изменила состояние
‚бит 1: линия О$В изменила состояние
бит 0: линия СТ$ изменила состояние
МТ 14Ё АН= 01: Запись символа в последовательный порт
Вход: АН = 011
АТ. = символ
ОХ - номер порта (001 -— 03Ъ)
Выход: АН = состояние порта
ПМТ 14 АН = 02: Чтение символа из последовательного порта с ожиданием
Вход: АН =028.
’ .Х = номер порта
Выход: АН = состояние порта
АЕ= считанный символ, если бит 7 АН равен нулю (ве было тайм-аута)
ПМТ 148 АН= 03: Получить текущее состояние порта
Вход: АН= 03Ь
* ОХ= номер порта бы — озв).
Выход: АН = состояние линии
АТ. = состояние модема
Воспользуемся этими функциями, чтобы написать короткую терминальную
программу:
; Тег. азт
‚ Простая Терминальная программа для модема на С0М2. Выход по А1Т-Х.

.1о4е1 лу
‚„соде .
огд 100Н | ; Начало СОМ-файла.
эТагт:
оу ав, 0 ‚ Инициализировать порт.
ей а], 111000116 ; 9600/8п1
по\у 9х, 1 ; Порт С0М2.
и 148

па1п_1оор:
пом ай, 2 |
111 148 ; Получить байт от модема, .‹
Тезт ан, ав ; Если что-нибудь получено,
912 по_1прит _.
т - 291 ; вывести его на экран,
по_1прит: : ; Иначе:
тоу ап, 1
11 161 , ‚ проверить, была ли нажата ‘клавиша.
ре па1п_100ор ‘°`’'’': Если да: о ь
оу ап,8
11 211 т считать ее Код (без’ отображения на экране).
тезт а1,а1 ; Если это нерасширенный АЗСТТ-код -
Другие устройства = = = МИ
312 зепд_спаг ; отправить его в.модем. . ;
_1и 218 ; Иначе получить расширенный АЗСТТ-код.
стр а1, 208 „ Если ‘это А1Т-Х
те зепв_спаг | |
гет ; завершить программу.
зепд_сваг: .
мо ав, 1 , .
17 148 ‚ Послать введенный символ в модем.
Эр зпогЕ пазп_1оор ; Продолжить основной цикл.

епд Зфагт

Этот терминал тратит чрезмерно много процессорного времени на постоянные '


вызовы прерываний 141 и 16. Более эффективным оказывается подход, заключаю-
щийся в перехвате прерываний от внешних устройств, о котором рассказано далее.

4.7.3. Параллельный порт


Параллельные порты используются в первую очередь для подключения прин-
теров, хотя встречаются и другие устройства, например переносные жесткие диски,
которые могут присоединяться к этим портам. Базовые средства 20$ и В1О$ для
работы с параллельными портами: аналогичны соответствующим средствам для
работы с последовательными портами: РОЗ инициализирует стандартное устрой-
ство РЕМ, соответствующее первому порту 1.РТ1, которое может быть переопреде-
.
лено командой МОШЕ, и предоставляет прерывание для вывода в это устройство
Функция 005 05#: Вывод символа в стандартное устройство РЕМ
Вход: АН = 056
Гут. = символ
Кроме того, можно пользоваться функцией записи в файл или устройство,
поместив в ВХ число 4, соответсвующее устройству РЕМ. ВОЗ, в свою очередь,
предоставляет базовый набор из трех функций для работы с принтером.
|
ГМТ 17, АН = 00: Вывести символ в принтер
Вход: АН = 00% |
АТ. = символ |
ОХ - номер параллель ного порта (00 — ГРТ1, 01 - ГРТ2, 02 - ГРТЗ)
Выход: АН = состояние принтера:
бит 7: принтер не занят
бит 6: подтверждение
бит 5: нет бумаги ^
бит 4: принтер в состоянии опНпе
бит 3: ошибка ввода-вывода =
бит 0: тайм-аут
МТ 17Ь, АН = 01: Выполнить аппаратный сброс принтера
Вход; АН = 01 ее.
ОХ = номер порта (005 - 028)
Выход: АН = состряние принтера
ШИ! Основы программирования для М5 005$
МТ 171, АН= 02: Получить состояние принтера их
Вход: АН =.026 ‹
„БХ = номер порта. (00ь — 028)
Выход: АН = состояние принтера
Например, чтобы распечатать содержимое экрана на принтере, можно напи-
сать такую программу:
‚ рЕЪфзсг. азт
; Распечатать содержимое экрана на принтере.

2. ‚тоде1 1ту
. соде
.186 ° . ; Для команды ризв 08800Н.
ог9 100н ` ; Начало СОМ-файла.
эТагт: | :
ЮУ ап, 1 .
моу ‚9х, 0 ; Порт ЕРТЛ:
т о В ; Инициализировать принтер.
стр ав, 908 ; Если принтер не готов,
‚ пе рг1пег_еггог ; выдать сообщение об. ошибке... . с
ризН 088001 ; Иначе: |
рор д ; 0$ = сегмент видеопамяти в текстовом‘ режиме,
хог $1, 31 ‚ ЗР= 0, , | `
то сх, 80*40 ; СХ = число символов на ‘экране.
с14 ; Строковые операции вперед.
та1п_1оор:
104$и ‚АБ - символ, АН - атрибут, 1 = $Г + 2.
тому ав, 0 ; АН - номер функции.
10 . ТТ ; Вывод символа из АЁ на принтер.
1юор ма1ип_1о0р
гет . ; Закончить программу.
рг1пТтег_еггог:
моу _ 9х, оРРзет 39 ; Адрес сообщения об ошибке в 05:0Х.
моу ав,9
17 РА ; Вывод строки на экран.
гет

п59 9 “Принтер на ЁРТТ находится в состоянии. о?711пе или занят$”


епа зам
Чтобы распечатать экран в.текстовом режиме на ТРТИ,.достаточно всего лишь
одной команды ГМТ. 05$, что в точности эквивалентно нажатию клавиши Рибсг.

4.8. Работа с файлами '


Возможно, основная функция РО$ в качестве операционной системы- орга-
низация доступа к дискам как к набору файлов и директорий. РО$ поддерживает
только один тип-файловой системы—ЕАТ и, начиная с версии 7.0 (УЛидо\з 95),
его модификацию УЕАТ с длинными именами файлов. Первоначальный набор
Работа с файлами `^ о м
в М5 РОЗ 1.0, оказался: очен
функций для работы с файлами, предложенный
я 37-байтной структурой ЕСВ
неудобным: каждый открытый файл описывалс
я для всех файловых опера-
(блок управления файлом), адрес которой требовалс
структуру данных ОТА (область
ций, а передача данных осуществлялась через
с усовершенствованием ЕАТ (на-
передачи данных). Уже в М$ РО5 2.0, вместе ОМ Х-подобных
набор
пример, появлением вложенных директорий), появился файла всего одно 16-
файлами, использу ющих для описания
функций работы с
. Все остальные функции ра-
битноё число, идентификатор файла или устройства
число. Первые пять идентификато-
боты с файлами используют затем только это
ров инициализируются системой следующим образом: );
0: 5ТОМ - стандартное устройство ввода (обычно клавиатура
устройств о вывода (обычно экран);
1: ЗТРОЧТ - стандартное
об ошибках (всегда экран);
2: ЗТРЕВВ - устройство вывода сообщений
3: АЧХ — последовательный порт (обычно СОМ);
— параллельный порт (обычно Т1РТ1); о
4: РКМ сброс ‘буферов на
так что функции чтения/за писи (а также
м.
диск) файлов можно применять и к устройства

4.8.1. Создание и открытие файлов .


Функция 00$ ЗСЕ: Создать файл й . |
.
Вход: АН = ЗСЬ
СХ = атрибут файла. .
в М№оуе |Мебухаге
бит 7: файл можно открывать разным процессам
бит 6: не используется .
)
бит 5: архивный бит (1, если файл не сохранялся
быть 0 для функ ции ЗСВ) .
бит 4: директория (должен
ЗСВ).
бит 3: метка тома (игнорируется функцией
бит 2: системный файл
бит 1: скрытый файл
бит 0: файл только для чтения
м файла (АЗС!-строка
Р$:ОХ = адрес АЗС!7-строки с полным имене |
АЗ$СИ-символов, оканчивающаяся нулем)
зошла ошибка '
Выход: СЕ=биАХ = идентификатор файла, если не прои
СЕ=1иАХ = 03}, если путь не найден
ытых файлов
СЕ=1иАХ = 04В, если слишком много откр .
|
СЕ=ТиАХ = 054, если доступ запрещен
равно открывает его, присваивая
_ Если файл уже ‘существует, функция ЗСВ все
следует пользоваться функцией 5ВВ.
ему нулевую длину. Чтобы Этбго не произошло; и
4 о Че
существующий: файл. |
Функция 20$ ЗРЕ: Открыть ОА
Вход АН-ЗОВ
` `АТ. = режим доступ а
бит 0: открычь для чтения” ^
"о ре.
бит-1: открыть для записи” “7.
(0) ‘ д!
‘бизы 2-3: зарезервированы
КЕНИИ И ИИ: Основы программирования для М$ ОО$.
биты 6-4: режим доступа для других процессов:
000: режим. совместимости (остальные процессы также долж-
ны открывать этот файл в режиме совместимости)
001: все операции запрещены
010: запись запрещена
011: чтение запрещено
100: запрещений нет
бит 7: файл не наследуется порождаемыми процессами
05$:0Х = адрес АЗС17-строки с полным именем файла
СТ. = маска атрибутов файлов
Выход: СЕ=0иАХ = идентификатор файла, если не произошла онгибка
СЕ=1иАХ = код ошибки (021 — файл не найден, ОЗЬ - путь не найден,
046 — слишком много открытых файлов, 051 — доступ
запрещен, 9СЬ — неправильный режим доступа)
Функция 20$ 5В: Создать и открыть новый файл
Вход АН = 5ВЬ
СХ = атрибут файла —
„_ ОЗОХ = адрес АЗСТ/-строки с полным именем файла
Выход: СЕ-ОиАХ = идентификатор файла, открытого для чтения/записи
в режиме совместимости, если не произошла ошибка
СЕ=1иАХ= код ошибки (03ЗВ — путь не найден, 04Ь — слизиком мно-
го открытых файлов, 05Ъ — доступ запрещен, 50В - файл
уже существует)
Функция РО$ 5Ай: Создать и открыть временный файл
Вход: АН = ЗАВ
СХ = атрибут файла
‚ [ОХ= адрес АЗСГА-строки с путем, оканчивающимся символом \,
| и тринадцатью нулевыми байтами в конце
‚ Выход: СЕ =0иАХ= идентификатор файла, открытого для чтения/записи
в режиме совместимости, если не произошла ошибка
{в строку по адресу О5:ОХ донисывается имя файла)
СЕ -ТиАХ -код ошибки 93 -— путь не найден, 04} — слишком много
открытых файлов, 05 — доступ запрещен)
Функция ЗАВ создает файл с уникальным именем, который не является на
самом деле временным. Такой файл следует специально удалять, для чего его имя.
и записывается в строку в О5:ОХ.
Во всех случаях строка с полным именем файла имеет вид типа
Е11езрес 4’: с: \вата\
Лепате.ехт',0
причем, если диск или путь опущены, используются их текущие значения.
Для работы с длинными именами файлов в 0О$ 7.0 (У\Лпдо\ 95) и старше
используются дополнительные функции, которые вызываются так же, как функ-
ция ОО$ 716. -.
Работа с файлами
Функция ГЕМ 6СР: Создать или открыть файл с длинным именем
Вход: АХ = 716СЬ :
ВХ- режим доступа УЛа4о\з 95
биты 2-0: доступ
000 — только для чтения
001 - только для записи '
010 — для чтения и записи
100 — только для чтения, не изменять время последнего обраще-
ния к файлу |
биты 6—4: доступ для других процессов `(см. функцию зоь)
бит 7: файл не наследуется порождаемыми процессами
бит 8: данные не буферируются
бит 9: не архивировать файл, если используется архивирование
файловой системы (ДочЫезрасе)
бит 10: использовать число в ОГ для записи в конце короткого име-
ни файла
бит 13: не вызывать прерывание 246 при критических ошибках
бит 14: сбрасывать буфера на диск после каждой записи в файл
_СХ = атрибут файла °
ОХ= действие
бит 0: открыть файл (ошибка, если файл существует)
бит 1: заменить файл (ошибка, если файл не существует)
бит 4: создать файл (ошибка, если файл существует)
р5:$1 = адрес АЗС!7-строки с именем файла
О] = число, которое будет записано в конце короткого варианта имени
файла |
Выход: СЕ=0
АХ = идентификатор файла
СХ = 1, если файл открыт
СХ = 2, если файл создан
СХ = 3, если файл заменен
СЕ - 1, если произошла ошибка
АХ = код ошибки (7100Ъ, если функция не поддерживается)
Если функции открытия файлов возвращают ошибку «слишком много отжры-
тых файлов» (АХ= 4), следует ‘увеличить число допустимых идентификаторов
с помощью функции 67.
"Функция РО5 67[: Изменить максимальное число ‚ идентификаторов файлов
Вход: . АН= 67 |
ВХ= новое максимальное число идентификаторов (20-65 535)
Выход: СЕ- 0, если не произошла ошибка
СЕ =1и АХ = код ошибки, если ироизошла ошибка (например: од,
если заданное число. меньше, чем количество уже от-
крытых файлов, или 08В, если`РО$ не хвятает памяти
для новой таблицы идентификаторов) ›
В Основы программирования для М$ 205
Следует помнить, что все дочерние процессы будут наследовать только пер-
вые 20 идентификаторов и должны вызывать функцию 67Ь сами, если им требу-
ется больше. мо | | .: .
у

4.8.2. Чтениеи запись в файл


Функция РО5 ЗЕ: Чтение из файла или устройства
Вход: АН = ЗЕРЬ
ВХ = идентификатор
СХ = число байтов: .
05$:0Х - адрес буфера для приема данных
_ Выход: СЕ=0диАХ = число считанных байтов, если не было ошибки
СЕ=1иАХ = 05$, если доступ запрещен, 06}, если неправильный иден-
тификатор Ы

Если при чтении из файла число фактически считанных байтов в АХ меныше,


чем заказанное число в СХ, то был достигнут конец файла. Каждая следующая.
операция чтения, так же как и записи, начинается не с начала файла, а с того бай-
та, на котором остановилась предыдущая операция чтения /записи. Если требует-
ся считать (или записать) произвольный участок.файла, используют функцию
42 (функция 15еекК в С). | | .
Функция 2О$5 421: Переместить указатель чтения /записи
` Вход: АН = 426
ВХ = идентификатор ,
СХ.ОХ = расстояние, на которое надо переместить указатель (со знаком)
АТ, = перемещение: | |
0. от начала файла `
1 — от текущей позиции
2 - от конца файла , | ‚ , :
Выход: СЕ=0иСХ.ОХ = новое значение указателя (в байтах от начала файла),
если не произошла ошибка =
СЕ=1иАХ = 061, если неправильный идентификатор
Указатель можно установить за реальными пределами файла: в отрицательное
число, тогда следующая операция чтения/записи вызовет ошибку; в положитель-
ное числа, большее длины файла, тогда очередная операция записи увеличит раз-
мер файла. Эта функция также часто используется для определения длины фай-
ла — достаточно вызвать ее с СХ = 0, ВХ =0, АГ. =2, ив СХ:ОХ будет возвращена
длина файла в байтах. о В В `. |
Функция 00$ 401: Запись в файл или устройство.
Вход: : АН = 406. -
ВХ = идентификатор
СХ - число байтов.
О5:0Х - адрес буфера в данными (’. “ Не
СЕ=0иАХ = число записанных байтов, если не произошла ошибка -
Выход:
СЕ=1иАХ = 05Н’если доступ запрещеи; 06; если неправильный иден-
’‘тификатор’"
Работа с файлами.
Если при записи в файл указать СХ - 0, он будет обрезан по текущему значе-
нию указателя. На самом деле происходит запись в буфер ОО$, данные из кото-
рого сбрасываются на диск во время закрытия файла или если их количество
превышает размер сектора диска. Для немедленной очистки буфера мможно ис-
пользовать функцию 681 (функция ЯВ в С). о
Функция 00$ 68#: Сброс файловых буферов 2О$ на Диск
Вход: —АН= 68В
ВХ = идентификатор
Выход: СЕ= 0, если операция выполнена
СЕ = 1, если произошла ошибка (АХ= код ошибки) >
Для-критических участков программ предпочтительнее использовать более эф-
фективную функцию ООВ."
Функция 20$ ООЕ: Сброс всех файловых буферов на диск °
Вход: АН = 0ОРЬ.
Выход: Никакого.
4.8.3. Закрытие и удаление файла - |
Функция 2О$ ЗЕЁ: Закрыть файл | /
Вход: АН=ЗЕБ `.
ВХ - идентификатор: -
Выход: СЕ= 0, если не произошла ошибка
СЕ = 1иАХ= 6, если неправильный` идентификатор
Если файл был открыт для записи, все файловые буфера сбрасываются на диск,
устанавливается время модификации файла и записывается его новая длина.

Функция 205 418; Удаление файла


Вход: АН-=Ав.
0$:0Х- адрес АЗС! -строки с полным именем файла
Выход: СЕ= 0, если файл удален
СЕ*т1иАН= 02}, если файл не найден; оЗЬ, если путь не найден; 05Ъ,
если доступ запрещен
Удалить файл можно только после того, как он будет закрыт, иначе роз про-_
должит выполнение записи в несуществующий файл, что может привести к раз-
рушению файловой системы. Функция 418 не позволяет ‘использовать: маски
(символы* и ? в имени файла) для удаления сразу нескольких файлов, Хотя это-
го можно добиться, вызывая ее через недокументированную функцию 5000}. Но,
начиная с ОО$ 7.0 (УЛп4о\з 95), официальная Функция удаления
у’ файла способ-.
на работать сразу с несколькими файлами. .
Функция ГЕМ 418: Удаление файлов с длинным именем, _
Вход: АХ= 71416 |
‚ 0$:0Х = адрес А$С17- строки с длинным. именем файла
$1= 00001: маски не разрешены и атрибуты в.СХ игнорируются
КЕНИИ ||Основы программирования для М5 205
$1 = 0001Ъ: маски в имени файла и атрибуты в СХ разрешены:
СТ, = атрибуты, которые файлы могут иметь
СН = атрибуты, которые файлы должны иметь
Выход: СЕ = 0, если файл или файлы удалены |
`’ СЕ=1иАХ= код ошибки, если произошла ошибка. Код 7100} означа-
ет, что функция не подлерживается

`4.8.4. Поиск файлов


Найти нужный файл на диске намного сложнее, чем просто открыть его, — для.
этого требуются две функции при работе с короткими именами (найти первый
‚ файл и найти следующий файл) и три - при работе с длинными именами в РО5 7.0
(найти первый файл, найти следующий файл, прекратить поиск). .
Функция 2О5 4Ей: Найти первый файл
Вход: АН= 4ЕВ
‘ АГ, используется при обращении к функции АРРЕМО
СХ = атрибуты, которые должен иметь файл (биты 0 (только для чте-
ния) и 5 (архивный бит) игнорируются. Если бит 3 (метка тома)
установлен, все остальные биты игнорируются)
0$:0Х.= адрес АЗС!7-строки с именем файла, которое может включать
путь и маски для поиска (символы* и ?).
Выход: СЕ = 0 и область ОТА заполняется данными, если файл найден
СЕ = 1иАХ = 02, если файл не найден; 0ЗЪ, если путь не найден; 125,
если неправильный режим доступа.
Вызов этой функции заполняет данными область памяти ОТА (область переда-
чи данных), которая начийается по умолчанию со смещения 0080 от начала блока
данных Р$Р (при запуске СОМ- и ЕХЕ-программ сегменты 05$ и Е$ содержат сег-
ментный адрес начала Р5Р), но ее можно переопределить с помощью функции ТАБ.
Функция 0О5 ЛАВ: Установить. область ОТА
Вход: АН = 1АВ
05$:0Х = адрес начала ОТА (128-байтный буфер)
Функции поиска файлов заполняют ОТА следующим образом:
+008: байт —биты 0-6: АЗСП- -код буквы диска.
, | бит 7: диск сетевой.
+01В: 11 байт — маска поиска (без пути)
+0СЬ: байт., — атрибуты для поиска
+005: слово - порядковый номер файла в директории _
+0ЕЬ: слово — номер кластера начала внешней директории
+116: 4 байта — зарезервировано
+15Ъ: байт — - атрибут найденного файла
+16Ъ: слово - время создания файла в формате 205:
биты 15-11: час (0-23)
биты 10-5: минута
1

` биты 4-0: номер секунды, деленный на 2 (0-30).


Работа
с файлами ..'. 25: ПО О ИИ ЕЕ
+18В: слово - дата создания файла в формате РОЗ;
биты 15-9: год, начиная с 1980
биты 8-5: месяц _
биты 4—0: день. о
+1АЪ: 4 байта - размер файла |
+1ЕВ: 13 байт - АЗС!/-имя найденного файла с расширением
После того как ОТА заполнена данными, для продолжения поиска следует
вызывать функцию 4ЕЬ, пока не будет возвращена ошибка.
Функция 20$ 4Ей: Найти следующий файл
Вход: АН=4ЕР —
_ ОТА- содержит данные от предыдущего вызова функции 4ЕЬ ИЛИи ДЕБ
Выход: СЕ=0и ТА содержит данные о следующем найденном файле, если не
` произошла ошибка |
СЕ =1иАХ = код ошибки, если произошла ошибка,
В случае с длинными именами файлов (ГЕМ) применяется набор из трех под-
функций функции РО 71В, которые можно использовать, только если запущен
ГЕ Зет (всегда запускается при обычной установке УИпао\з 95, но не запускает-
ся, например, с загрузочной дискеты М$ 2О$ 7.0).
Функция ГЕМ ЧЕЙ: Найти первый файл с.длинным именем
Вход: АХ= 714ЕБ
СТ.= атрибуты, которые файлыможет иметь биты о и5 игнорируются)
СН = атрибуты, которые файл должен иметь
$1 = 0; использовать УЯи4о\/з-формат даты/времени
$1 = 1: использовать ОО$-формат даты/времени |
05$:0Х - адрес АЗСТ7-строки с маской для поиска (может включать*
и ?. Для совместимости маска *.* ищет все файлы в директо-
рии, а не только файлы, содержащие точку в имени)
ЕЗ:01 = адрес 318-байтного буфера для информации о файле
Выход: СЕ=0 р |
АХ= поисковый идентификатор
СХ = ОЧшсоде-флаг:
бит 0: длинное имя содержит подчеркивания вместо непреобразу-
емых Ошсоде-символов |
бит 1: короткое имя содержит подчеркивания. вместо непреобразу-
емых Отмсоде-символов.
СЕ= 1 АХ = код ошибки, если произошла. ошибка (71008 —‘функция
, не поддерживается) - р
Если файл, подходящий нод маску и атрибуты поиска, найден,: ббласть’ дан-
ных по адресу ЕЗ: О] заполняется следующим образом: "а
ыы
+001: 4 байта — атрибуты файла
биты 0-6: атрибуты файла 20$
бит 8: временный файл
оонаанивнани! Основы программирования для М$ 20$.
+045: 8 байт - время создания файла
+0СВ: 8 байт — время последнего доступа к файлу
+141: 8 байт — время последней модификации файла
+1СКВ: 4 байта — старшее двойное слово длины файла
+205: 4 байта — младшее двойное слово длины файла
+24Ъ: 8 байт — зарезервировано
+2СЬ: 260 байт - АЗСТ7-имя файла длинное
+1301: 14 байт — АЗС!7-имя файла короткое
Причем даты создания/доступа/модификации записываются в одном из двух
форматов, в соответствии со значением $1 при вызове функции. УЯп4о\$-формат —
64-битное число 100-наносекундных интервалов с 1 января 1601 года; если исполь-
зуется РО$-формат - в старшее двойное слово записывается ДОЗ-дата, а в млад-
шее - РО5-время.
Функция ТЕМ 4Ё:: Найти следующий файл
Вход: АХ= 714ЕЬ
ВХ= поисковый идентификатор (от функции 4ЕВ)
УТ = формат ‚даты/времени
Е$:ЪЬ1 = адрес буфера для информации о файле.
Выход: СЕ = 0 и СХ = Чикоде-флаг, если следующий файл найден
СЕ = Ъ. АХ = код ошибки, если произошла ошибка (71008 - функция
не поддерживается)
Функция ГЕМ АТР: Закончить поиск файла
Вход АХ- ПАВ
ВХ = поисковый идентификатор
Выход: СЕ= 0,если операция выполнена
СЕ-1иАХ-- код ошибки, если произошла ошибка (71001 — функция
не поддерживается)
В качестве примера, использующего многие функции работы с файлами, рас-
смотрим программу, заменяющую русские буквы Н латинскими Н во всех фай-
лах с расширением .ТХТ в текущей директории (такая заМена требуется для каж-
дого текста, пересылающегося через сеть Е!4опе*, программное обеспечение
` которой воспринимает русскую букву Н как управляющий символ).
; Г1доп. азт р
‚ Заменяет русские “Н” латинскими “Н” во всех файлах с расширением .ТХТ
‚; в текущей директории. .

.09е1 “1лу
. соде в с В д:
ога. 1000 ‚:. ; СОМ-файл
зтагт: | —. | |
лоу ^ ап,4 ^^ о ’’_”, Поиск первого файла.
. ХОГ сх, сх‘ В ‚ Не системный, не директория ит. д.
по\ 9х, отРзет` Г11езрёс ; Маска дяя поиска в 05:0Х.
Работа с файлами
*1]е_ореп:
11 ан
. © по_моге_#11ез ; Если СЕ = 1 - файлы кончились. |
тоу ах, 30021 ; Открыть файл:для чтения и. записи.
то 9х, 8ОН+1ЕВ .: Смещение ОТА + смещение ‚имени файла
1м 211 ; от начала БТА.
3с пот_ореп ; Если файл не открылся - перейти
; к следующему.

по\ Ьх,ах ‚;_ Идентификатор файла в ВХ.


тому сх,1 ‚ Считывать один байт.
том вх, оРзет БиРег ; Начало буфера - в 0х.
геаЧ_пех\:
поу ап, ЗЕВ ; Чтение’ файла.
17 218 ый
{с гп _пехе^ ; Если ошибка - перейти.к следующему. .....
ах ; Если АХ^=`0 - файл кончился -—
{1п9_пехт .; перейти к следующему. ,
Буте рег ыитег, 808" ; Ебли не считана русская “Н",
геад_пехт \ ; считать. следующий байт.
Буте` рег БиРРег, 488 ; Иначе = записать в’буфер
; Латинекую букву “Н”.

ах, 42011 ; Переместить указатель файла от текущей


; позиции назад на 1.
; СХ = ОЕЕЕЕИ,
; ОХ = ОРЕЕЕИ.

; ‘Записать в файл.

сх ; Один байт (СХ= 1)


9х, офРзет Би{Рег ; из буфера в 05:0Х.. <

211
тр ЗногЕ ‘геад_пеху ‚ Считать следующий байт.^
ра

Е1пд_пех{:
му ап, ЗЕ. ; Закрыть. предыдущий файл.
и 21В
по{_ореп:
моу ап, 4Р\ `; Найти ‘следующий файл.`
поу 9х, 801 ; Смещение ОТА от начала Р5Р.
тр НОГЕ 1#1]е_ореп

по_тоге_111ез: ; Если файлы кончились, 57:


гет ; выйти из программы.

#1] езрес 96 тж ЖЕ”, 0 ‚ Маска для поиска. |


БыЕРег 1а6е1 Буте .; Буфер для чтения/записи -
епб зтагт; - ‚ за концом программы. .
КЕРНИ | Основы программирования для М5 205
4.8.5. Управление файловой системой
Начиная с М5 РО$ 2.0 файловая система организована в виде директорий.
Поиск файлов выполняется только в пределах текущей директории, а создание
и удаление файлов неприемлемы к директориям, хотя на самом низком уровне ди-
ректория - тот же файл, в атрибуте которого бит 4 установлен в 1 и который содер-
жит список имен вложенных файлов, их атрибутов и физических адресов на диске.
Функция 20$ 391: Создать директорию
Вход: АН= 396 ^
0$:0Х= адрес АЗСТ-строки с путем, в котором все директории, кро-
ме последней, существуют. Для РОЗ 3.3 и более ранних вер-
сий длина всей строки не должна превышать 64 байта
. Выход: СЕ = 0, если директория создана
СЕ =1ТиАХ = 3, если путь не найден; 5, если доступ запрещен
Функция ГЕМ 391: Создать директорию с длинным именем
Вход: АХ= 71396
05:0Х= адрес АЗСГ/-строки с путем
Выход: СЕ = 0, если директория создана |
СЕ =1иАХ = код ошибки (71005, если функция не поддерживается)
Функция РО$5 ЗА#: Удалить. директорию _
Вход: АН = ЗАВ
25:0Х = адрес АЗСТ2-строки с путем, где последняя директория
будет удалена (только если она пустая, не является текущей,
не занята командой ЗО В$Т)
Выход: СЕ = 0, если директория удалена
СЕ-1иАХ - 3, если путь не найден; 5, если доступ запрещен; 10В, если
удаляемая директория - текущая
Функция ГЕМ ЗАЁ: Удалить директорию с длинным именем
Вход: АХ= 71ЗАЬ
25$:0Х- адрес строки с путем
Выход: СЕ =0, если директория удалена, иначе СЁ = 1 и АХ = код ошибки
Функция 0О5 471: Определить текущую директорию
Вход: АН = 47Ъ |
| ОГ. = номер диска (00 - текущий, 01 — Аит.д.) .
05:51 = 64-байтный буфер для текущего пути (АЗСТ7-строка без име-
ни диска, первого и последнего символа \)
Выход: СЕ =0иАХ = 01001, если операция выполнена |
СЕ =ТиАХ = ОЕБ, если указан несуществующий диск |
Функция ГЕМ 471: Определить текущую директорию с длинным именем
Вход: АХ = 7147
РТ. = номер диска
05:51 = буфер для пути (АЗСГ7-строка без имени диска, первого и пос-
леднего символа \. Необязательно содержит лишь длинные
Управление памятью ИТТ МЕТ
имена — возвращается тот путь, который использовался при
последней смене текущей директории.)
Выход: СЕ= 0, если директория определена, иначе СЕ=ТиАХ = код ошибки
Функция РО$ ЗВЕ: Сменить директорию и
Вход: АН = ЗВЬ
05$:0Х= адрес 64-байтного АЗС! -буфера с путем, который станет-те-
кущей директорией
Выход: СЕ= 0, если директория изменена, иначе СЕ =1иАХ = 3 (путь не найден)
Функция ГЕМ ЗВ: Сменить директорию с длинным именем
Вход: АХ = 713ВВ |
05$:0Х = адрес АЗС!7-буфера с путем
Выход: СЕ = 0, если директория изменена, иначе СЕ =ТиАХ = код ошибки
Перед работой с любыми функциями Г.ЕМ следует один раз вызвать подфунк-
цию ОАО, чтобы определить размеры буферов для. имен файлов’и путей.
Функция ГЕМ ОАО!: Получить информацию о разделе файловой системы УЕАТ
Вход: АХ= ИДАОБ.
0$:0Х- адрес АЗС1Т7-строки с именем раздела (например: ЧБ "С\" о)
ЕЗ:01 = адрес буфера для имени файловой системы (РАТ, МТЕ$, СОЕ$)
СХ = размер буфёра в ЕЗ:ОТ (обычно 32 байта)
Выход: СХ= 0, АХ= 00001 или 02008
ВХ= флаги файловой системы:
бит 0: функции поиска учитывают регистр символов
бит 1: регистр символов сохраняется для имен директорий
бит 2: используются символы Окоде
бит 14: поддерживаются функции ЕЕМ
бит 15: включено сжатие раздела (ДочЫезрасе)
СХ = максимальная длина имени файла (обычно 255)
ОХ= максимальная длина пути (обычно 260) в УЙп4о\з 95 $Р1 воз-
вращает 0000 для СО-ВОМ
СЕ = 1иАХ = код ошибки, если произошла ошибка (7100Ъ, если фун-
кция не поддерживается)
Кроме того, при вызове любой функции Г.ЕМ следует устанавливать СР в 1 для
совместимости с ранними версиями 20$. Старые версии РОЗ не изменяли СЕ
так что в результате, если функция не поддерживается, СЁ останется равным 1.

4.9. Управление памятью


4.9.1. Обычная память .
До сих пор, если требовалось создать массив данных в памяти, мы просто

обращались к памяти за концом программы, считая, что там имеется еще хотя

бы 64 Кб свободной памяти. Разумеется, как и во всех операционных системах,


в 2О$ есть средства управления распределением памяти — выделение блока

7 Зак. 459
ИИ Основы программирования для М$.00$
(аналог стандартной функции языка С таПос), изменение его размеров (аналог
геаПос) и освобождение (#гее).
Функция 2О5 48#: Выделить память
Вход: АН = 486
ВХ = размер блока в 16-байтных параграфах
Выход: СЕ = 0, если блок выделен
| АХ = сегментный адрес выделенного блока
СЕ = 1, если произошла ошибка:
АХ = 7 - блоки управления памятью разрушены
АХ = 8 - недостаточно памяти: =
ВХ - размер максимального доступного блока
Эта функция с большим значением в ВХ (обычно ОЕЕЕЕВ) используется
для
определения размера самого большого доступного блока памяти.
Функция 20$ 491: Освободить память
‚Вход: АН = 498
Е$ = сегментный адрес освобождаемого блока
®
Выход; СР = 0, если блок освобожден
СЕ=1, АХ = 7, если блоки управления намятью разрушены;
.
АХ= 9, если в Е5 содержится неверный адрес
Эта функция не позволит освободить блок памяти, которым текущая програм-
_ма не владеет, но с помощью функции ОО$ 506 (АХ= 50, ВХ = сегментный ад-
рес РЗР процесса) программа может «притвориться» любым другим процессом.
Функция 2О5 4Ай: Изменить размер блока памяти
Вход: АН = 4АБ
ВХ = новый размер в 16-байтных параграфах
Е$ = сегментный адрес модифицируемого блока
Выход: СЕ = 1, если при выполнении операции произошла ошибка
АХ = 7, если блоки управления памятью разрушены
АХ = 8, если не хватает памяти (при увеличении)
АХ= 9, если Е$ содержит неверный адрес
ВХ= максимальный размер, доступный для этого блока
‚Если для увеличения блока не хватило памяти, ВО$ расширяет его до возмож-
ного предела.
При запуске СОМ-программы загрузчик ОО$ выделяет самый `большой до-
ступный блок памяти для этой программы, так что при работе с основной памятью
эти функции требуются редко (в основном для того, чтобы сократить выделен-
ный программе блок памяти до минимума перед загрузкой другой программы),
но уже в М$ РО$ 5.0 и далее с помощью этих же функций можно выделять па-
мять в областях ОМВ - неиспользуемых участках памяти выше 640 Кб и ниже
1 Мб, для чего требуется снёчала подключить ОМВ к менеджеру памяти и изме-
нить стратегию выделения памяти с помощью функции РО$ 581.
Управление памятью _ —_ 95,
4.9.2, Область памяти ИМВ
Функция 2О$ 581: Считать/изменить стратегию выделения памяти
Вход: АН = 58В
АТ, = 001— считать стратегию
АТ, = 01Ъ - изменить стратегию
ВХ - новая стратегия
биты 2-0:
00 — первый подходящий блок
01 - наиболее подходящий блок
11 — последний подходящий блок |
биты 4-3: `
00 — обычная память
01 - ОМВ (00$ 5.0+) ,
10 - ОМВ; затем обычная память (РО$ 5.0+).
АТ, = 02 - считать состояние ОМВ
АГ. = 03 - установить состояние (МВ
ВХ = новое состояние: 00 — не используются, 01 — используются
Выход: СЕ=0, АХ = текущая стратегия для АТ. = 0, состояние МВ для АГ. =.2
СЕ - 1, АХ = 01Ъ, если функция не поддерживается (еслине запущен
менеджер памяти (например, ЕММЗ386) или нет строки
20$ = ОМВ в СОМЕ!С.5У5)
Если программа изменяла стратегию выделения памяти или состояние ОМВ,
она обязательно должна их восстановить перед окончанием работы.
4.9.3, Область памяти НМА
Область памяти от ОЕЕЕЕБ:0010В (конец первого мегабайта) до ОЕЕРЕВ:ОЕЕЕЕЬ
(конец адресного пространства в реальном режиме), 65 520 байт, может исполь-
зоваться на компьютерах, начиная с 80286. Доступ к этой области осуществля-
ется с помощью спецификации ХМ$5, причем вся она выделяется целиком од-
ной программе. Обычно, если загружен драйвер ННМЕМ.5У$ и если в файле
СОМЕГС.5У$ присутствует строка 2О$ = НТСН, РО$ занимает эту область, осво-
бождая почти 64 Кб в основной памяти. При этом ОС может оставить небольшой
участок НМА (16 Кб или меньше) для пользовательских программ, которые обра-
щаются к нему с помощью недокументированной функции мультиплексора ААВ.
[МТ 28, АХ - 4А01Ь: Определить размер доступной части НМА (20$ 5.0+)_
Вход: АХ = 4АО№ .
Выход; ВХ = размер доступной части НМА в байтах, 0000}, если 20$ нев НМА
Е$:01 = адрес начала доступной части НМА (0ЕЕРЕВ:ОЕЕЕЕЬ, если
рРО$ нев НМА)
ГУТ 2Е1, АХ = 4А028: Выделить часть НМА (20$ 5.0+)
Вход: АХ = 4А02Ь \
ВХ = размер в байтах .
ЕЕИНИИ И" Основы программирования для М$ 20$
„Выход: Е5:0Т = адрес начала выделенного блока
ВХ =размер выделенного блока в байтах
В версиях 00$ 5.0 и 6.0 нет функций освобождения выделенных таким обра-
зом блоков НМА. В РО5 7.0 (\Мтдо\з 95) выделение памяти в НМА было орга-
низовано аналогично выделению памяти в обычной памяти и ОМВ, сфункциями
- изменения размера и освобождения блока.
[МТ 2Е), АХ = 4АОЗЙ: Управление распределением памяти в НМА (20$ 7.0+)
Вход: АХ = 4А03ЗЬ
ОТ. = 0 - выделить блок (ВХ = размер в байтах)
ОТ. = 1 - изменить размер блока (Е5:01 = адрес, ВХ = размер) ‘

ОТ. = 2 - освободить блок (Е5:0] = адрес)


СХ = сегментный адрес владельца блока
Выход: Р1-= ОЕЕЕЕЬ, если не хватило памяти, Е5З:О1 = адрес блока (при выде-
` лении)

Следует помнить, что область НМА доступна для программ только в том
@©® случае, когда адресная линия процессора А20 разблокирована. Если ОО$ не
занимает НМА, она практически постоянно заблокирована на совмести-
мость с программами, написанными для процессора 8086/8088, которые
считают, что адреса ОЕЕЕЕР:О0010Ё— ОЕЕЕЕР:ОЕЕЕЕЙ всегда совпадают
с ООООР:0000Е —ОбООВЕЕЕЕЙ. Функции ХМ5 01-07 позволяют управлять
состоянием этой адресной линии. .

4.9.4. Интерфейс ЕМ5


Расширенная память (ЕМ5З) - дополнительная возможность для программ, за-
пускающихся в реальном режиме (или в режиме У86), обращаться к памяти, ко-
торая находится за пределами первого мегабайта. ЕМ$ позволяет отобразить сег-
мент памяти, начинающийся обычно с 000005, на любые участки памяти,
аналогично тому, как осуществляется доступ к видеопамяти в ЗУСА-режимах.
Вызывать функции ЕМ$ (прерывание 671) разрешается, только если в системе
присутствует драйвер с именем ЕММХХХХО. Для проверки его существования
можно, например, вызвать функцию ЗОВ (открыть файл или устройство). При-
чем на тот случай, если драйвер ЕМ$ отсутствует, а в текущей директории есть
файл с именем ЕММХХХХО, следует дополнительно вызвать функцию 1ОСТЕ -
‚ МТ 21 сАХ = 4400} и ВХ = идентификатор файла или- устройства, полученный
от функции ЗТЪ. Если значение бита 7 в ОХ после вызова этой функции равно 1,
то драйвер: ЕМ$ наверняка присутствует в систёме.
Основные функции ЕМ$:
МТ 671, АН= 46р: Получить номер версии
Вход: АН= 46.
Выход: АН =ОбилЕ = номер версии в упакованном св (408 для 4. 0).
Во всех случаях, если АН не ноль, произошла ошибка
Управление памятью Ш
зови
Го 497
ГМТ 67В, АН= 418: Получить сегментный` адрес окна
Вход: АН= 4
Выход: АН =Ои ВХ - сегментный адрес окна
ГМТ 67, АН = 42#: Получить объем памяти
Вход: АН = 426
Выход: АН =0
ОХ - объем ЕМ$-памяти в 16-килобайтных страницах
ВХ = объем свободной ЕМ$-памяти в 16-килобайтных страницах
ПМТ 67, АН= 438: Выделить идентификатор и ЕМ$-память
Вход: — АН= АЗЬ
ВХ = требуемое число 16-килобайтных страниц
Выход: АН = 0, ОХ - идентификатор .
Теперь указанный в этой функции набор страниц в ЕМ$-памяти описывается
как занятый и другие программы не смогут его выделить для себя.
ПМТ 67В, АН= 44й; Отобразить память
Вход: АН= 446
АГ. - номер 16-килобайтиой страницы в 64-килобайтном окне ЕМ5 (0-3)
ВХ = номер 16-килобайтной страницы в ЕМ$-памяти
ОХ = идентификатор
Выход: АН=0
Далее запись/чтение в указанную страницу в реальном адресном пространстве
приведет к записи/чтению в указанную страницу в ЕМ$-памяти.
[МТ 671, АН = 454: Освободить идентификатор и ЕМ5-память
Вход: (АН = 456 |
ОХ = идентификатор
Выход: АН=0
Спецификация ЕМ$ была разработана для компьютеров [ВМ ХТ, снабжав-
шихся особой платой, на которой и находилась расширенная память. С появле-
нием процессора 80286 стало возможным устанавливать больше одного мегабай-
та памяти на материнской плате, и для работы с ней была введена новая
спецификация - ХМ$. Тогда же были созданы менеджеры памяти, эмулировав-
шие ЕМ$ поверх ХМ$, для совместимости со старыми программами, причем ра-
бота через ЕМ5 выполнялась медленнее. Позже, когда в процессорах Тибе] появил-
ся механизм страничной адресации, выяснилось, что теперь уже ЕМ$ можно
реализовать гораздо быстрее ХМ$. Большинство программ для РО$, которым
требуется дополнительная память, поддерживают обе спецификации.
4.9.5. Интерфейс ХМ5
Спецификация доступа к дополнительной памяти (ХМ$) — еще один метод,
позволяющий программам, запускающимся под управлением РОЗ в реальном ре-
жиме (или в режиме \86), использовать память, расположенную выше границы
первого мегабайта. '
ШИ! Основы программирования для М$.005 |
МТ 2Е), АН= 43: ХМЗ5- и ОРМ5-сервисы
Вход: АХ= 43001: проверить наличие ХМ5
Выход: АН= 801, если ННМЕМ.$У$ или совместимый драйвер загружен
‚ Вход: АХ= 4310: получить точку входа ХМ5
Выход: ЕЗ:ВХ= дальний адрес точки входа ХМ5
После определения точки входа все функции ХМ$ вызываются с помощью
команды САГЛ. на указанный дальний адрес.
Функция ХМ5 001: Определить номер версии
Входз АН= 00 =
Выход: АХ = номер версии, не упакованный ВСР (03008 для 3.0)
ВХ = внутренний номер модификации
ЬХ = если НМА существует; 0, если нет
Функция ХМ$ 08й: Определить объем памяти
Вход: АН= 08Ь
ВЕ.= 008
Выход: АХ= размер максимального доступного блока в килобайтах
ОХ= размер ХМ$-памяти всего в килобайтах |
ВТ. = код ошибки (ОАОТ, если вся ХМ$-память занята; 00, если нет
ошибок)
Так как возвращаемый: размер памяти оказывается ограниченным размером
слова (65 535 Кб), начиная с версии ХМ$ 3.0, введена более точная функция 88.
Функция ХМ5 881: Определить объем памяти
Вход: —АН =888
Выход: ЕАХ = размер максимального доступного блока в килобайтах
ВТ. = код ошибки (ОАО, если вся ХМ$-память занята; 00, если нет
ошибок)
ЕСХ= физический адрес последнего байта памяти (верный длягошиб-
ки ОАОЬ)
ЕМХ= размер ХМ$-памяти в килобайтах (0 для ошибки ОАО)
Функция ХМ$ 09Р: Выделить память
Вход: АН= 09%
ОХ-= размер запрашиваемого блока (в килобайтах)
` Выход: АХ = 1, если функция выполнена
ОХ = идентификатор блока
АХ= 0:
ВТ. = код ошибки (ОАО, если не хватило памяти)
Функция ХМ5 ОА#: Освободить память
Вход: АН = 0АВ
ОХ = идентификатор блока
Выход: АХ = 1, если функция выполнена.
‚ Иначе - АХ= 0 и-В1Т.= код ошибки (0А2Ь— неправильный идентифи-
`катор, ОАВЬ- участок заблокирован) |
Управление памятью
Функция ХМ$ ОВЁ: Пересылка данных
Вход: АН = ОВЬ .
0$:$1 = адрес структуры для пересылки памяти
Выход: АХ = 1, если функция выполнена
Иначе - АХ = би В!. = код ошибки
Структура данных, адрес которой передается в 05:51:
+00Ъ: 4 байта — число байтов для пересылки
+04В: слово — идентификатор источника (0 для обычной памяти)
+06Ъ: 4 байта — смещение в блоке-источнике или адрес в памяти
+0 АБ: слово — идентификатор приемника (0 для обычной памяти)
+0СЪ: 4 байта — смещение в блоке-приемнике или адрес в памяти
Адреса записываются в соответствующие двойные слова в обычном виде —
сегмент:смещение. Копирование ‘происходит быстрее, если данные выровнены на
границы слова или двойного слова; если области данных перекрываются, адрес
начала источника должен быть меныше адреса начала приемника.
Функция ХМ$ ОЕ: Изменить размер ХМ$-блока
Вход: АН = 0ЕЬ
ВХ = новый размер
ОХ -= идентификатор блока |
Выход; АХ = 1, если функция выполнена.
Иначе - АХ = би В1, = код ошибки
Кроме того, ХМ$ позволяет программам использовать область НМА и блоки
О МВ, если они не заняты РО$ при запуске (так как в СОМЕТС.$У$ не было строк
рОо$ = НСН или 2О$ = ОМВ). | |
; тет. азт .
; Сообщает размер памяти, доступной через ЕМ$ и ХМЗ. `

.тове1 пу
‚ с0де
. 186 ; Для команд сдвига на 4.
ог 1008 ‚ С0М-программа.
эфагт: .
с14 ‚Команды строковой обработки будут выполняться вперед.

; Проверка наличия ЕМ$.

му 9х, оРРвет етз_дг1мег ; Адрес АЗСТ7-строки “ЕММХХХХО”,


° вом ах, 30001
р 21в : Открыть файл или устройство.
3с по_етих. ; Если не удалось открыть - ЕМ$ нет.
мо\ Ьх, ах ВИ ; Идентификатор в ВХ.
мо ах, 44008 ‚^
111 218 ; ТОСТЕ: проверить состояние файла/устройства.
с по_ет$ ‚; Если не произошла ошибка,
РИМИНИ | Основы программирования для М$ 205
Тезт ух, воп ; проверить старший бит ОХ. .
32 по_ет$ ; Если он - 0, ЕММХХХХО - файл в текущей директории.

‹ Определение версии ЕМ$. ^

мо ап, 461
1% 67Н ‚ Получить версию ЕМ5.
тез ап, ан -
912 по_ет$ , : Если ЕМ5 выдал ошибку - не стоит продолжать
| ; с ним работать.
том ап,а1
‚ ап а1, ЕВ ‚ АЁ = ‘старшая цифра.
[48 ай,4 - ; АН = младшая цифра. .
са]1, оутри{_мегз1оп ; Выдать строку о номере версии ЕМ$..

; Определение доступной ЕМ$-памяти. |


тому ай, 421 . . .
111 671 ; Получить размер памяти в 16-килобайтных страницах,
$1] 9х, 4 / ; 0Х = размер памяти в килобайтах.
$61 Ьх, 4 ‚ ВХ = размер свободной памяти в килобайтах.
мо ах, 5х .
моу $1, ОРЁЕзе{ етз_ЁЕгеетет ° ‚ Адрес строки для очтри{_1по.
са11 оцфрит_1пРо ‚ Выдать строки о размерах памяти.

по_етё г ‚
пом ан, ЗЕй р
Че 21п ; Закрыть файл/устройство ЕММХХХХО.
по_етих:, `
; Проверка наличия ХМ5.

том ах, 43001


11% 2ЕВ _ ‚ Проверка ХМ$.
стр а], 80П ; Если АЁ не равен 801,
пе по_хтз ; ХМ5 отсутствует.
Те ах, 43101 ‚ Иначе:
11% 2ЕН . получить точку входа ХМ5
тоу мог рЕг ептгу_рт,Бх ‹ и сохранить ее в еп%гу_р*.
\ поу мог руг ептгу_рт+2,ез ‹ (старшее слово. - по старшему‘ адресу!)
ризй 95
рор е5 ; Восстановить ЕЗ.
7
' Определение версии ХМЗ.
Мом ап, 00
са11 Чмог@ рфг ейтгу_рт .; Функция ХМ$ 00В - номер версии.
поу Буте ‘рег ‘мет_уегз1оп,
'Х’ ; Изменить первую букву строки
: "ЕМЗ версии” на “Х"
са11 оутри{_мегз1оп ; Выдать строку о номере версии ХМ$.

; Определение доступной ХМ5-памяти.


оу ап, 08п
хог 5х,6х
са11 Чнога рёг епегу_рт ‚ Функция ХМ5 08п.
Управление памятью - ИТЕЕТ
| | 201
моу руте мг тота1 тет, 'Х' ; Изменить первую букву строки
; “ЕМЗ-памяти” на “”Х”.
поу 31, ОРРэзет ‘хтз_Ргеетет ; Строка для оифрит_1п®0. ^^

Вывод сообщений на экран:


ОХ - объем всей памяти,
АХ - объем свободной памяти,
$1 - адрес строки’с сообщением о свободной памяти (разный для ЕМ$ и хи).

зитрит_1пРо:
ризй ах
поу ах, 9х ; Объем всей памяти в АХ.
оу Бр, оРРзег тота1тет” ; Адрес строки - в ВР.
са11 оифри{_1пто1 ; Вывод.
рор ах у ‚ Объем свободной памяти - в АХ.
моу Бр, $1 - ‚ Адрес строки - в ВР.

эифри{_ 11101: ; Вывод.


пу 91, оРРзет Нех2дес. мога

Бех24ес
Преобразует целое двоичное число В АХ.
В строку десятичных АЗСТТ- цифр. в ЕЗ:0Т, заканчивающуюся СИМВОЛОМ “$”.
тоу Ьх, 10 — ; Делитель в ВХ.
. хог , сх, сх | . ; Счетчик цифр в 0.
34\1р: ^ хог ах, ах |
91% Ьх ‚ Разделить преобразуемое число на -10,
ааЧ 91, '0’ | ; ‘добавить к остатку АЗСТТ-код нуля
ризй 9х ” ; записать полученную цифру в стек. у
Тис сх - | ; Увеличить счетчик цифр
тезт ахах — - ; и, если еще есть, что делить,
дп2 91\1р . : продолжить деление на 10.
${оге: |
рор ах : Считать цифру из’ стека.
то ‚ Дописать ее в конец строки в Е: ВТ.
]оор зтоге - ; Продолжить для всех СХ-цифр.
оу Бузе ртг е$:[91],'$° ; Дописать '$’ в конец строки.

том ` ` 9х, Бр ` ; 0Х - адрес первой ‘части строки.


моу ав,3
1м 211 ‚ Функция 003 О9Н - вывод строки.
тоу 9х, отРзет пех24ес_мога : ОХ - адрес строки с десятичным’ числом.
11 218 ; Вывод строки.
поу 9х, оРРзет ео1 ; ОХ - адрес последней части строки.
17 21Н | ° ; Вывод строки. ,

пох: . гет м ‚ Конец программы и процедур очтри*_1пРо


И и ошрит_1т01.

; Вывод версии ЕМЗ/ХМ$.


‚ АХ - номер в неупакованном ВСО-формате.
РОМАН
НО ШИИ | Основы программирования для М$ 20$
оифри*_уегз1оп:
ог ах, 30301 ; Преобразование неупакованного ВСО в АЗС.
. оу Буфе рфг мадог,ап ; Старшая цифра в мадог.
тоу Буте руг т1лог,а1 ; Младшая цифра’ в м1пог.
тоу Чх, оРРзет. тет_уегз1оп ; Адрес начала. строки - в 0Х.
то\ ан, 9 |
171 211 ; Вывод строки.
ге
етз_Ч9г1\уег 95 "ЕММХХХХО”, 0 ; Имя драйвера для проверки ЕМ$.
мет_\уегз1оп 96 "ЕМЗ версии " ; Сообщение о номере версии.
та] ог 96 "0.” ; Первые байты этой
тлог 6 “0 обнаружен ”,0Он,
ОАп, '$’; и этой строк будут
: | ; заменены реальными номерами версий.
Тота] тет 6 “ЕМ$-памяти: $”
етз_Ггеетет а6 "ЕМ$-памяти: $”
ео1 а5 'К’, ООН, ОАВ, ' $’ | ; Конец строки.
хтз_Ггеетет 96 "Наибольший свободный блок ХМ: $"

ептгу_рт: ; Сюда записывается точка входа ХМ$.


нех2дес_мога еци ептгу_р\+4 ; Буфер для десятичной строки.
епд этагт ;

4.10. Загрузка и выполнение программ


Как и любая операционная система, ОО$ загружает и выполняет программы.
При загрузке программы в начале отводимого для нее блока памяти (для СОМ-про-
грамм это вся свободная на данный момент память) создается структура данных Р5Р
(префикс программного сегмента) размером 256 байт (1001). Затем 20$ создает
копию текущего окружения для загружаемой программы, помещает полный путь
и имя программы в конец окружения, заполняет поля РУР следующим образом:
\
+00Ъ: слово -ОСЬЬ 206 - команда ПМТ 208. Если СОМ-программа завершает-
ся командой КЕТМ, управление передается на эту команду.
Введено для совместимости с командой СР/М САЦ. 0
‚+028: слово -— сегментный адрес первого байта после области памяти, выделен-
ной для программы
` +046: байт — — не используется РОЗ
+051: 5 байт -— ЭАВ ОБОВ ОЕЕБВ 010 ОЕОВ - команда СА. ЕАК на абсолютный
адрес 000СОБ, записанная так, чтобы второй и третий байты со-
ставляли слово, равное размеру первого сегмента для СОМ-фай-
лов (в этом примере ОРЕЕОВ). Введено для совместимости с ко-
мандой СРУМ САМ. 5
+0 АВ: 4 байта - адрес обработчика ПМТ 228 (выход из программы)
+ОЕЪ: 4 байта — адрес обработчика ПМТ 23В (обработчик нажатия СЫ]-ВгеаК)
+12Ь: 4 байта — адрес обработчика ПМТ 24Ь (обработчик критических ошибок)
+16Ъ: слово — сегментный адрес РЗР процесса, из которого был запущен текущий
+18: 20 байт - ]ЕТ - список открытых идентификаторов, один байт на иденти-
‹ фикатор, ОЕЕВ - конец списка.
Загрузка и выполнение программ | —

+2СЬ:слово = - сегментный адрес копии окружения для процесса


+2ЕВ:2 слова - $5:5Р процесса при последнем вызове ПМТ 218
+32Ъ: слово — — число элементов ]ЕТ (по умолчанию 20)
+345: 4 байта -— дальний адрес ТЕТ (по умолчанию Р$Р:0018)
+381: 4\байта - дальний адрес предыдущего РР -
+3СВ: байт — флаг, указывающий, что консоль находится в состоянии ввода
2-байтного символа
+306: байт - флаг, устанавливаемый функцией 0871 1ьпрерывания 2ЕВ (при
следующем вызове ПМТ 21Ь для работы с файлом имя файла бу-
дет заменено полным)
+ЗЕЬ: слово — - не используется в РО5
+408: слово — — версия 2О$5, которую вернет функция РО$ 30} (РОЗ 5.0+)
+425: 12 байт - не используется в РОЗ
+501: 2 байта -— ОСЬ 218 - команда ПМТ 218
+528: байт = -— ОСВЬ - команда ВЕТЕ
+53Ь: 2 байта - не используется в РОЗ
+55}: 7 байт - область для расширения первого ЕСВ
+5СВ:16 байт -— первый ЕСВ, заполняемый из первого аргумента командной строки
+6СЬ:16 байт - второй ЕСВ, заполняемый из второго аргумента командной строки
+7СЬ: 4 байта - не используетсяв РО$
+801: 128 байт — командная строка и область ОТА по умолчанию
и записывает программу в ‘память, начиная с адреса Р$Р:0100Ъ. Если загружается
ЕХЕ-программа, использующая дальние процедуры или сегменты данных, 005
модифицирует эти команды так, чтобы используемые в них сегментные адреса
соответствовали сегментным адресам, которые получили указанные процедуры
и сегменты данных при загрузке программы в память. Во время запуска` СОМ-
программы регистры устанавливаются следующим образом:
АТ,= ОЕЕЬ, если первый параметр командной строки содержит непра-
вильное имя диска (например, 2\оте тв), иначе — 00%
АН= 0ЕЕБ, если второй параметр содержит неправильное имя диска,
иначе — 00
С$= 0$= ЕЗ= 5$ = сегментный адрес РР
$Р= адрес последнего слова в сегменте (обычно! ОРЕЕЕБ; меньше, если
не хватает памяти)
_При запуске ЕХЕ-программы регистры $5:5Р устанавливаются в соответствии
с сегментом стека, определенным в программе, затем в стек помещается слово
0000$ и выполняется переход на начало программы (Р$Р:0100В для СОМ, соб-
ственная точка входа для ЕХЕ).
Все эти действия выполняет одна Функция _205 — загрузить и ВЫПОЛНИТЬ
программу.
Функция РО$ 4ВА: Загрузить и ВЫПОЛНИТЬъ программу
Вход: АН’= 4ВЬ
АТ.= 00} - загрузить и выполнить |
РОННИ В | Основы программирования для М$ 205
АТ.= 011 - загрузить и не выполнять
`РЗ:ОХ- адрес АЗСТ/-строки с полным именем программы
ЕЗ:ВХ- адрес блока параметров ЕРВ:
+00}: слово — сегментный адрес окружения, которое будет скопи-
ровано для нового процесса (или 0, если использу-.,
ется текущее окружение)
. +02}: 4 байта — адрес командной строки для нового процесса
+06Ъ: 4 байта - адрес первого ЕСВ для нового процесса
+0АЪ: 4 байта — адрес второго ЕСВ для нового процесса
+0ЕЪ: 4 байта — здесь будет записан 55:5Р нового процесса после
его завершения (только для АТ. = 01)
+125: 4 байта — здесь будет записан С$:Р (точка входа) нового
процесса после его завершения (только для АГ. = 01)
АТ. = 0ЗЬ - загрузить как оверлей
0$:0Х - адрес АЗС!7-строки с полным именем программы
ЕЗ:ВХ - адрес блока параметров:
+001: слово— сегментный адрес для загрузки оверлея
+025: слово — число, которое будет использовано в командах, при-
з меняющих непосредственные сегментные адреса, —
’ обычно то же самое, что и в предыдущем поле. 0 для
СОМ-файлов
АТ. = 05} - подготовиться к выполнению (2О$ 5.0+)
05:0Х - адрес следующей структуры:
+001: слово — 008
+02Ъ: слово — бит 0 — программа — ЕХЕ
_ бит 1 — программа — оверлей
+04Ъ: 4 байта — адрес АЗС12-строки с именем новой программы
+08: слово — сегментный адрес РЭР новой программы
+0АЪ: 4 байта — точка входа новой программы
+ОЕБ: 4 байта — размер программы, включая Р5Р
Выход:
СЕ = 0, если операция выполнена, ВХ и ОХ модифицируются,
СЕ = 1, если произошла опгибка, АХ= код ошибки (2 — файл не найден,
5 — доступ к файлу запрещен, 8 - не хватает памяти. 0АБ-— непра-
вильное окружение, ОВВ -— неправильный формат)
Подфункциям 00 и 01 требуется, чтобы свободная память для загрузки про-
граммы была в нужном количестве, так что СОМ-программы должны воспользо-
ваться функцией РОЗ ААВ с целью уменьшения отведенного им блока памяти до
минимально необходимого. При вызове подфункции 03 РО$5 загружает оверлей
в память, выделенную текущим процессом, поэтому ЕХЕ-программы должны
убедиться, что ее достаточно.
Эта функция игнорирует расширение файла и различает ЕХЕ- и СОМ-файлы
но первым двум байтам заголовка (МА для ЕХЕ-файлов).
Загрузка и выполнение программ ^^ ООО
ей управле-
Подфункция 05 должна вызываться после загрузки и перед передач
ния РО$ и ВТО$ нельзя вызыват ь после
ния на программу, причем никакие прерыва
мы.
возвращения из этой подфункции и до перехода на точку входа новой програм
Загруженной и вызванной таким образом програм ме предоста вляется несколь-
ется для
ко способов завершения работы. Способ, который чаще всего применя
СОМ-файлов, - команда ВЕТМ. При этом управление передается на адрес
Р5Р:0000, где располагается код команды ПМТ 20}. Соответственно программу мож-
но завершить сразу, вызвав ПМТ 20}, но оба эти способа требуют, чтобы С$ содер-
жал сегментный адрес РЗР текущего процесса. Кроме того, они не позволяют вер-
цию
нуть.код возврата, который может передать предыдущему процессу информа
запущен ная программ а. Рекомен дованны й способ заверше-
о том, как завершилась
ния программы -— функция 2О$ 4СВ.
Функция 205 4Сй: Завершить программу
Вход АН = 4СЬ
АТ. = код возврата
как пере-
Значение кода возврата можно использовать в пакетных файлах РОЗ
ю функции 2О$ 40В.
менную ЕКВОВГЕУЕЕ и определять из программы с помощь
процесса
Функция 0О$ 4: Определить код возврата последнего завершившегося
Входз АН = 4АОЬ р

Выход: АН = способ заверше ния:


00Ъ — нормальный
016 — С&1-ВгеаК
02Ъ - критическая ошибка
ОЗЬ - программа осталась в памяти как резидентная
АГ. = код возврата
СЕ=0
мы, кото-
Воспользуемся функциями 4АВ и 4ВЬ в следующем примере програм
енная ко-
рая ведет себя как командный интерпретатор, хотя на самом деле единств
ывает, — команда ех!. Все остальн ые команды передаю т-
манда, которую она обрабат
и вернуть ся).
ся настоящему СОММАМО.СОМ с ключом /С (выполнить команду
пе1].азт
Программа, выполняющая функции командного интерпретатора
(вызывающая соттапд.сот для всех команд, кроме ех1 т);

.тоде1 11пу
. соде
р | , |
‚ 186
ог9 1008 —_ ; СОМ-программа

"$" | „Последний символ В приглашении ко вводу,


ргомру_еп@ ‚ еду

эТагт: | |
моу зр, ето В_о{_ргодгат+1001+2008 ; Перемещение ‘стека на 2001
; после конца. программы
‚ (дополнительные 1008 - для РУР)..
ШИ! Основы программирования для М5 20$
МОУ ` ав, 4АВ
зТаск_з1111=1еп9*Н_оР_ргодгат+100Н+200В
оу ‚ Бх, зтаск_зВ1Р эпг 4+1
11 218 ; Освободить всю память после конца
программы и стека,

; Заполнить поля ЕРВ, содержащие сегментные адреса,


том, ах,сз
по\ ога р%г ЕРВ+4,ах Сегментный адрес командной строки.
ту могЧ р\г ЕРВ+8,ах Сегментный адрес первого ЕСВ.
поу мог рфг ЕРВ+ОСВ,ах Сегментный адрес второго ЕСВ.

па? п_1оор:

‚; Построение и вывод приглашения для ввода,

тоу ан, 191 функция 003 191:


аа 21н определить текущий диск.
ада а1,'А’ Теперь.АЕ = АЗСТТ-код диска (А, В, С,).
руте ртг Чг1уе_Ле{тег, а] , Поместить его в` строку.
ап, 471 Функция 005 47:
91,00
$$, ОРРзет рмб_биРег
2 определить текущую директорию
аГ,0 Найти ноль (конец текущей директории)
91, ответ ‘ргопр®_зтагт в строке с приглашением.
сх, рготрт_1
зсазЬ
91 ОТ - адрес байта с` нулем.

9х, отР$е{т рготрт_эТагт 05:0Х - строка приглашения.


91,9х 01 - длина строки`приглашения.
2
сх,91
Ьх,1 3190
ав, 401
218 Вывод строки в файл или устройство.
а], рготр*_епа
29Н Вывод последнего символа в приглашении.
1
‚ Получить команду от пользователя
поу ап, оАВ Функция 00$ ОАН:
том Чх, оРРзе{ ‘соттапа_ВиЕР6г
и 218 буферированный ввод.

оу ° а1, 008 ; Вывод символа СВ


11 291
ту а1, ОАВ . Вывод символа [Е -
пе 298 {СН и ЁЕ вместе - перевод строки).

сир
ле
буте ртг соттапа_БиРег+1, 0
та1п_1оор
‚ Если введена
‚ продолжить
пустая
основной
строка,
цикл.
Загрузка и выполнение программ И.| | 207
Проверить, является ли введенная команда командой “ех1т”.

тоу 91, оРРзет сомтапд_БиРРег+2 | ‚ Адрес введенной строки..


оу $1, оРЕзеф стд_ех{ ‘ ; Адрес эталонной строки
. ‚ “ех1т”, 008.
оу сх, ств_ех1*_1 | . Длина эталонной строки.
гере стрзб , | ‚ Сравнить строки.
9сх2 дот_ех{ | ‹ Если строки идентичны -
‚ выполнить ех1\т.

Передать остальные команды интерпретатору 00$ (СОММАМО, СОМ).


хог сх, сх
моу $1, ОРРзет соттапа_ЪБиРег+2 . Адрес введенной строки.
том 91, оРРзет соттапа_Техт о. ; Параметры для соттапа. сом.
тоу с1,Буте руг соттапа_биРег+1 ‚ Размер введенной строки.
Чл 1. , _ ; Учесть ООВ в конце.
гер мо\$Ь у ; Скопировать строку.
[А ах, 48001 . Функция 00$ 481.
оу ах, оЕРзет сомтапа_сот. ‚ ‘Адрес АЗСТ2-строки с адресом.
моу ъх, оРЕзет ЕРВ |
апт 218 . Исполнить программу.
тр зНог{ та1п_3оор ; Продолжить основной цикл.
дот_ех1т: .
201 ; Выход из программы (геф нельзя,
11
| ы | ; потому что мы перемещали стек).

ста_ехлт [6] "ех1 т”, 00П ; Команда “ех1т”.


ста_ех1_Т еды $-ста_ех1+ ‚.Ее длина.

рготр® _эТаге 6 “{1пузйе11:” ‚ Подсказка для ввода.


9г1ме_1е1тег 6 С:
рма_БиР Тег [ее] 64 дир (7?) ; Буфер для текущей директории.
рготр*_1 еди $-ргомре_$Тагт ‚ Максимальная длина подсказки.

соттапа_ сот 6 "С: \СОММАМО. СОМ", 0 ; Имя файла.

ЕРВ 9м 0000 ‚ Использовать текущее окружение.


фе] - ОРРзет соттапа11ле, 0 ; Адрес командной строки.
м 0051, 0, 006СВ, 0 . Адреса ЕСВ,` переданных 005
| ; Нашей программе при запуске`
; (на самом деле они не используются).

соттапа11пе 95 125 ` | ; Максимальная длина


- р ‚ командной строки.
96 "С" | .
; Ключ /С для’ СОММАМОСОМ.
соттапа_Техе 6 122 дир (?) | ; буфер для командной строки.

96 122 ; Здесь начинается буфер для ввода.


соттапа_рБиЁРег
1епоти_оР_ргодгат еду 124+$-этагт ‚ Длина программы + длина
буфера для ввода.
епа этаг{ °
[2081 ТТИ Основы программирования для М$ 20$
Чтобы сократить пример, в нем используются функции для работы с обычны-
ми короткими именами файлов. Достаточно заменить строку
уе ап, 471
на
поу ах, 71471

и увеличить размер буфера для текущей директории (р\4_ЪиНег) с 64 до 260


байт, и директории с длинными именами будут отображаться корректно в под-
сказке для ввода. Но с целью совместимости следует также добавить проверку на
поддержку функции 718 (Т.Е№) и определить размер буфера для директории с по-
мощью подфункции Г.ЕМ ОАОВ. |

4.11. Командные параметры и переменные среды


В случае если команда не передавалась бы интерпретатору РОЗ, а выполня-
лась нами самостоятельно, то оказалось бы: чтобы запустить любую программу
из-под звеН.сот, нужно предварительно перейти в директорию с этой програм-
мой или ввести ее, указав полный путь. Дело в том, что СОММАМО.СОМ при
запуске файла ищет его по очереди в каждой из директорий, указанных в пере-
менной среды РАТН. РО$ создает копию всех переменных среды (так называе-
мое окружение ПО$5) для каждого запускаемого процесса. Сёгментный адрес ко-
пии окружения для текущего процесса располагается в РУР по смещению 2СВ.
В этом сегменте записаны все переменные подряд в форме АЗС!7-строк вида
"СОМ$РЕС=СЛМ 5 СОММАМО.С
/МРО ОМ",0.
М По окончании последней
строки стоит дополнительный нулевой байт, затем слово (обычно 1) — количество
дополнительных строк окружения, а потом - дополнительные строки. Первая до-
полнительная строка - всегда полный путь и имя текущей программы - также
в форме АЗСТ2-строки. При запуске новой программы с помощью функции 4ВЬ
можно создать полностью новое окружение и передать его сегментный адрес за-
пускаемой программе в блоке ЕРВ или просто указать 0, позволив РО$ скопиро-
вать окружение текущей программы. |
Кроме того, в предыдущем примере мы передавали запускаемой программе
(соттал4.сот) параметры (/с команда), но пока не объяснили! как программа
может определить, что за параметры были переданы ей при старте. Во. время за-
пуска программы РО$ помещает всю командную строку (включая последний
символ ООВ) в блок РР запущенной программы по смещению 81 и ее длину в байт
80Ъ (таким образом, длина командной строки не может быть больше 7ЕЪ (126)
символов). Под \Ип4о\з 95 и РО$ 4.0, если командная строка превышает эти раз-
меры, байт Р5Р:0080Ъ (длина) устанавливается в 7ЕВ, в последний байт Р5Р
(Р5Р:00ЕЕБ) записывается ОО}, первые 126 байт командной строки размещают-
ся в РР а вся строка целиком — в переменной среды СМОЛМЕ.
‚ саф.азт
°; Копирует объединенное содержимое всех файлов, указанных в командной строке,
°; В стандартный вывод. Можно как указывать список файлов, так и использовать
; маски (символы “*” и "?") в одном или нескольких параметрах,

/
Командная строка и переменные ПИ НЕМА
; например: , ...
; сафт пеадег *.{хт Гоотег > а11-{ех{$ помещает содержимое файла
; Веадег, всех файлов с расширением .1ХЕ в текущей директории и файла
. Тоотег - в файл а1]-тех*$.
; Длинные имена файлов не используются, ошибки игнорируются.

.тоде1 11пу
;с0де
ог9 801 . По, смещению 801 от начала РЗР находятся:
стд_епа&А 96 ? ‹ длина командной строки
ста_11пе 96 ? ; и сама командная строка,
ог9 1008 ; Начало СОМ-программы - 1001 от начала РЗР.
ЗТагт: _. .
- 61а — .; Для команд ‘строковой’ обработки:
оу ор, зр ‚_ ; Сохранить текущую вершину стека в ВР.
оу с1, ста_Тепотн |
©тр с], 1 | ; Если командная строка пуста -
` Де пом. изаде ‚ вывести информацию о программе и выйти.

оу ап, 1АВ ` ; функция 00$ ЛАП:


_ МОУ 9х, оЕРзет ОТА , !
о 21и . переместить ОТА (по умолчанию она совпадает
: с командной строкой Р$Р)

: Преобразовать список параметров в РЗР:81! следующим образом:


; Каждый параметр заканчивается нулем” {АЗСТ7-строка),
; адреса всех параметров помещаются в стек`в порядке обнаружения.
‚ В переменную агдс записывается число параметров.

моу сх, -1 ; Для команд работы со строками.


тоу 91, оРРзет ста_11пе ; Начало командной строки в ЕЗ:0Т.

{1п9_рагам:
му а1,’' ; Искать первый. символ, —
герг зсазЬ ‚ не являющийся пробелом. | .
дес 91 ; 01 - адрес начала очередного параметра.
ризй 91 ; Поместить его в стек
1пс мога рог агае ; и увеличить агдс на один.
том $1, 91 , ; $1 = 01 для следующей команды 104935.
эсап_рагамз: | ,
10936 ‚ Прочитать следующий символ из параметра.
стр а1, 008 ; Если это ООбн`- это’был последний параметр
]}е рагаяз_епдед9 — ; и он кончился. т
стр а1, 20н ‹ Если это 208 - этот параметр кончился,
3 пе зсап_рагамз ; но могут быть еще.

дес $1 . ; 51 - первый байт после конца параметра.


том ` рухе рег [$1],0 ; Записать в него 0.
Ш 91,31 ; ОГ = $Т для команды 3саз6.
1пс 91 , ‚ ОТ - следующий после нуля символ.
тр зпоге РЕ1п9_рагам ; Продолжить разбор ‘командной строки.
х

РИ | ШВ! Основы программирования для


М$ 005
рагатз_епдед:
дес $1 $Т - первый байт после конца последнего
моу руфе рёг [$1],0 ' параметра - записать в него 0.
‚ Каждый параметр воспринимается как файл или маска
для поиска файлов,
‚ все найденные файлы выводятся на з&доит,
Если параметр - не имя файла,
‚ То ошибка игнорируется.

тому $1, мога рег агдс $Т - число оставшихся параметров.


пех{_111е_Ргот_рагат:
- дес Бр
дес Бр ВР^- адрес следующего адреса параметра.
дес $1 Уменьшить число оставшихся параметров,
3$ по_тоге_рагатз если оно стало отрицательным - все.
то\ 9х, мога рАг [6р] 05:0. - адрес очередного параметра.
мом ап, 4ЕВ Функция 00$ 4ЕН. .
оу сх, 01001116 Искать все файлы, кроме директорий
и меток тома.
ии 211 . Найти первый файл.
37° пех{_111е_Ргот_рагат Если произошла ошибка - файла нет.
са11 “ оитрие_Тоипд Вывести найденный файл на зта0ит.
1119_пехе: ‘

оу ап, 4Ей Функция 00$ 41. , р


моу Чх, оЕзет ОТА Адрес нашей области ОТА.
111 211 — Найти следующий файл.
с. пехЕ_#11е_Ргот_рагам Если ошибка - файлы кончились.
са11 оитрит Роипа т Вывести найденный файл на З40ит.
р ЗПогЕ Р1па_пехе Продолжить поиск файлов.
по_тоге_рагатз:
тоу ах, мога ртг агдс
$11 ах,1
а99 зр, ах Удалить из стека 2 х агдс байтов (то есть весь -
список адресов параметров командной строки).
гет Конец программы.
; Процедура. зНом_изаде
; Выводит информацию о программе.

ЗВои_изаде;
моу ав,9 Функция 00$ ОЭН..
поУ 9х, оРРзет изаде
111 218 Вывести строку на экран.
гет р Выход из процедуры.
Процедура оифри+_Роипа.
Выводит в ${90ит файл, имя которого находится в области ОТА.
Командная строка и переменные _ ПМ

сифри*_Тоипа:
поу 9х, отЕзет ОТА+ТЕН: Адрес А$С17-строки с именем файла.
моу ах, 3000Н ; Функция 00$ 301:
11 218 ; открыть файл (а1 = 0 - только на чтение).
3°` ЗК1р_Р1е ; Если ошибка - не трогать этот файл.
моу Ьх, ах ‚ Идентификатор файла - в ВХ.
му 91,1 ‚ ОТ будет хранить идентификатор 5ТООЦТ,
9о_очтрит:
пу сх, 1024 . Размер блока для чтения файла.
моу @х, оРРзет 0ТА+45°; Буфер для чтения/записи располагается за концом -ОТА.
тоу ан, ЗЕ! | ‚ Функция 00$ ЗРЕП.
117 211 ; Прочитать 1024 байта из файла.
3с #]е_9допе ‚ Если ошибка - закрыть файл.
„МОУ сх, ах . ; Число реально прочитанных байтов»в СХ.
сх? тПе_допе = ; Если это не ноль - закрыть файл.

том ав, 404 ; Функция 00$ 408.


хсп9 Бх, 91 _ ; ВХ =.1 - устройство ЭТООШТ,
171 218 ; Вывод прочитанного числа байтов в ЗТООЧТ.
° ХОП 91, 6х ; Вернуть идентификатор файла в ВХ.
3с {Е1]е_допе ; Если ошибка - закрыть файл,-
Зтр зпогф до _оифрие ; продолжить вывод файла.
1е_допе: |
ое ап, ЗЕВ ; Функция 00$ ЗЕв:
171 211 : закрыть файл.
зК1р_111е:
гет ‚ Конец процедуры оутрит_Тоилч.

изаде ‚ 9 “саф.сот у1.0“”, 001, ОАН


96 “объединяет и выводит файлы на зт4ои{”,
00й, ОА
[418] “использование: сат имя_файла, ...”, ООВ, ОАВ
45 . “(имя файла может содержать маски *.и 7)", 00В, ОАН, $’

агдс 9\ 0 ; Число параметров


; (должен быть 0 при старте программы!
).

ОТА: ‚ Область ОТА начинается сразу за концом файла,


; а за областью ОТА -
; 1024-байтный буфер для чтения файла.
епа этаг+ ,

Размер блока для чтения файла можно значительно увеличить, но в таком слу-
чае почти наверняка потребуется проследить за объемом памяти, доступным для
программы.
СТР ТРУТТР

Глава 5. Более сложные приемы


программирования
Все примеры программ из предыдущей главы в первую очередь предназначались
для демонстрации работы с теми или иными основными устройствами компью-
тера при помощи средств, предоставляемых ОО и В1О5. В этой главе рассказа-
но о том, что и в области собственно программирования ассемблер позволяет
больше, чем любой другой язык, и рассмотрены те задачи, решая которые, приня-
то использовать язык ассемблера при программировании для ОО$5.

5.1. Управляющие структуры


5.1.1. Структуры ИЕ... ТНЕМ... ЕТЗЕ
Эти часто встречающиеся управляющие структуры передают управление на.
один участок программы, если некоторое условие выполняется, и на другой, если
оно не выполняется, записываются на ассемблере в следующем общем виде:
(набор команд, проверяющих условие)
Усс Е] зе
(набор команд, соответствующих блоку ТНЕМ)
Зар Епа1Е
Е1 зе: {набор команд, соответствующих блоку ЕЁЗЕ)
ЕП: :

‚ Для сложных условий часто оказывается, что одной командой условного пере-
хода обойтись нельзя, поэтому реализация проверки может сильно увеличиться.
Например, следующую строку на языке С

Зе (((%2У) 88 (2<1)) || (а1=5)) ©=6;


можно представить на ассемблере так:
х

; Проверка условия.
оу ах,А
стр ах,В
пе ТВеп ‚ Если а! = 6 - условие выполнено.
поу ах,Х
стр ^ ах,у
19 еп Е ; Если х < или = у - условие не выполнено.
оу ах,2
“стр ‘‘ах.т
1 епб1® —; Если 2 >‘или`= н = условиб не выполнено.
=
ТАеп: , | <; Условие выполняется,
7 м 40 о |
тоу С, ах _
епё1Г: | о . ты .
5.1.2. Структуры СА$Е
- `Управляющая структура типа СА$Е проверяет значение> некоторойИ перемен-
ной били выражения) и передает: управление на: различные ‘участки программы:
Кажется очевидным, что эта`структура должна’реализовываться в виде серии
структур ГЕ.. ТНЕМ... 'ЕЁЗЕ, как показано в примерах) тде:требовались различные
действия в зависимости от Значения нажатой клавишги; :
Пусть переменная 1 принимает значения от 0:до 2, и-в зависимости от значе-
ния надо выполнить процедуры сазед, сазе] и сазе2; 2... :
= му ах, ИИ аа | .
| стр. ах, 0 ср Проверка на 0. | 7 : | а
’упе поф0 |
са11 сазед ° и. а Е воЬ,
. пр епсазе. `. \
ото: стр ах, 1 - з Проверка на 1. ^` -
дпе по+1 ,
са] сазе1
ар епасазе : : -.
пот1: стр ах,2 . ;. Проверка на 2.
| пе пот2 т
са11 сазе2
пота:
епдсазе:

Но ассемблер предоставляет более удобный способ реализации таких струк-


тур - таблицу переходов: `
МОУ Ьх,1_ | о ..
$81 6х, 1 _ ; УмножитЬ ВХ на2 (размер адреса
о ; в таблице’ переходов’ = 4 ‘для
, ; 32-битных: адресов).
Зтр с3: }итр_таБ1е[ьх]; Разумеется, в этом примере
; достаточно использовать са11.

Зитр_таБ]е м 2000, Г001,1002. ; Таблица переходов.


000; — са11 сазеб
тр епдсазе .
Г001: сай сазе1 ` ,
- р `епасазе т
Го: сай сазег .
Эр епдсазе о <

Очевидно, что для переменной с большим числом вначений способ с таблицей


переходев является наиболее быстрым (не требуется многочисленных проверок),
аесли значения переменной — числа, следующие в точности друг за другом (так
д

ПАНИНШШИИИШИНИ! |—Сложные приемы программирования


что в таблице переходов нет пустых участков), то эта реализация структуры САЗЕ
окажется еще и значительно меньше.

5.1.3. Конечные автоматы


Конечный автомат — процедура, которая помнит свое состояние и при обра-
щении к ней выполняет различные действия для разных состояний. Например,
рассмотрим процедуру, которая складывает регистры АХ и ВХ при первом вызо-
ве, вычитает при втором, умножает при третьем, делит при четвертом, снова скла-
дывает при пятом и т. д. Очевидная реализация, опять же, состоит в последова-
тельности условных переходов:
ЗТате в 0
ЗТате_масй?пе:
стр ЗТате,0
- ме по 0 —
‚ Состояние 0:` сложение.
а99 ах, 6х
1пс зтате
гет |
пот_0: стр ЗТате,1
—_. пе пот_1
; Состояние ‘1: вычитание.
$05 ах,6х
1пс зтате
гет
пот_1: стр эзфате,2
ле пот_2
; Состояние 2: умножение.
ризв 9х
п] ‘6х
рор . 9х
1пс эфате ‹
гет
; Состояние 3: деление,
пот_2: ризп ^ ах
хог_ ах,4х
Ч1у 5х
рор 9х
моу ЗТате,9
гет
Оказывается, что (как и для САЗЕ) в ассемблере есть средства для более эф-
фективной реализации данной структуры - все тот же косвенный переход:
ЗТате дм оРРзеё зтате_0
эТфате_таси1те:
Этр этате \
ЗТафе_0: ада ах, 5х ‚ Состояние 0: сложение.
моу эТате, оЕЕзет зтате_1
° гот `
`
\

° зтате_1: зи6 ах, 5х ; Состояние 1: вычитание.


оу зтате, оРРсет этате_2 |
_ г р - ..
зтате_2: ризв 9х ; Состояние 2: умножение.
ми] Ьх ` | `
- рор ах. .
`поу ° зфате, отРэет. зате_3
. НС: о.
зтате_3: ризй 9х 5 ; Состояние 3: деление,
хог дх, 9х
[А 6х
рор 9х
- му Зтате, оГРзет этате_0
гет , . :
Как и в случае с САЗЕ, использование косвенного перехода приводит к тому,
что не требуется никаких проверок и время выполнения управляющей структу-_
‚ры остается одним и тем же для четырех или четырех тысяч состояний.

5. 1.4. Циклы

Несмотря на то что набор команд Тове включает команды организации ЦИК-

лов, они годятся только для одного типа циклов — ЕОК-циклов, которые ВЫПОЛ-
НЯЮТСЯ фиксированное число раз: В общем виде любой цикл записывается в ас-

семблере как условный переход.

УННЕ--ЦИКЛ:
. (команды инициализации цикла)
метка: ТЕ (не выполняется условие ‘окончания цикла)
ТНЕМ .
{команды тела цикла)
]тр метка

ВЕРЕАТ/ИНТИ цикл: ,
(команды инициализации цикла)
метка: (команды тела цикла)
ТЕ (не выполняется условие _ окончания цикла)
ТНЕМ {переход на ‘метку)

{Такие циклы ВЫПОЛНЯЮТСЯ: быстрее на ассемблере, и всегда следует стремиться


переносить проверку условия окончания цикла в конец)

ГООРИЕМОТ-ООР--цикл;
{команды инициализации ‘цикла)
метка:
(команды тела цикла)
ТЕ (выполняется условие окончания цикла) _
ТНЕМ )тр метка2
(команды тела цикла).
тр метка
метка2:
РЕЗ ИИ ИН! ’ Сложные приемы программирования
5.2. Процедуры и функции
Можно разделять языки программирования на процедурные (С, Разса1|,
Еоггап, ВАЗГС) и непроцедурные (115Р. ЕОВТН, РКОТОС), где процедуры -
блоки кода программ, имеющие одну точку входа и одну точку выхода и возвра-
щающие управление на следующую команду после команды передачи управле-
ния процедуре. Ассемблер одинаково легко можно использовать как процедурный
язык и как `непроцедурный, и в большинстве примеров программ до сих пор мы
успешно нарушали рамки и того, и другого подхода. В настоящей главе реализа-
ция процедурного подхода рассмотрена в качестве наиболее популярной.

5.2.1. Передача параметров


Процедуры могут получать или не получать параметры из вызывающей про-
цедуры и могут возвращать или не возвращать результаты (процедуры, которые
что-либо возвращают, называются функциями в языке Разса, но ассемблер не
делает каких-либо различий между ними).
Параметры можно передавать с помощью одного из шести механизмов:
О по значению;
Опо ссылке; ‚
Оло возвращаемому значению;
Опо результату; |
Опо имени; .
О отложенным вычислением.
`

: Параметры можно передавать в одном из пяти мест:

Ов регистрах;
Ов глобальных переменных;
Ов стеке; `
О в потоке кода;
Ов блоке параметров. р
Следовательно, всего в ассемблере возможно 30 различных способов передачи
параметров для процедур. Рассмотрим их по порядку. |
Передача параметров по значению
Процедуре передается собственно значение параметра. При этом фактически
значение параметра копируется, и процедура использует его копию, так что мо-
дификация исходного параметра оказывается невозможной. Этот механизм при-
меняется для передачи небольших параметров, таких как байты или слова, к при-
меру, если параметры передаются в регистрах: | г:
тоу ах, мог рфг уа1ие ; Сделать копию значения. ..
са11 ргоседиге ; Вызвать процедуру.
Передача параметров по ссылке ,
Процедуре передается не значение переменной, а ее адрес, по которому проце-
дура сама прочитает значение параметра. Этот механизм удобен для передачи
1
Процедуры и функции МЕХ
больших массивов данных и втех случаях, когда процедура должна модифициро-
вать параметры (хотя он и медленнее из-за того, что процедура ‘будет выполнять
дополнительные действия для: получения значений параметров).
° оу ах, оРзет уа1ие | о .
.са11 ‚„ргоседиге- :

Передача! параметров по возвращаемому значению ,


Этот механизм объединяет передачу по значению и по ссылке. Процедуре. пере-.
дают адрес переменной, а процедура делает локальную копию параметра, затем
работает с ней, а в конце записывает локальную копию обратно по переданному ад-
ресу. Этот метод эффективнее обычной передачи параметров по ссылке в тех слу-
чаях, когда процедура должна обращаться к параметру очень большое количество
раз, например, если используется передача параметров в глобальной переменной:
‚МОУ 91а} мага Зе, оРЁзе{ уа1ие
ба11 ргоседиге ` и р ..
[..] о | |
ргоседиге ргос пеаг ` ь :
том ах, 9106а1_уагзаб1е
том ах, мога рег [9х]
(команды, работающие с АХ в цикле десятки тысяч раз)
МОУ мога рег [9х],ах
ргоседиге епар

Передача параметров по результату


Этот механизм отличается от предыдущего только тем, что при вызове проце-
дуры предыдущее значение параметра никак не определяется, а переданный ад-
рес используется ТОЛЬКО ДЛЯ записи в него результата.

Передача параметров по имени


Данный механизм используют макроопределения, директива ЕО, а также,
например, препроцессор С во время обработки команды #Чевпе. При реализации.
этого механизма в компилирующем языке программирования (к которому отно-
сится и ассемблер) приходится заменять передачу параметра по имени другими
механизмами с помощью, в частности, макробпределёний.
Если установлено макроопределение

разз_Бу_паме . тасго рагатетег1' |


моу ах, рагатетег1 о
епдт | и”
то теперь`параметр В программе можно. передавать следующим образом;

разз_бу_пате уа1ие
са11 ргоседиге.. о
Примерно так же поступают языки программирования высокого уровня, под-
держивающие этот механизм: процедура получает адрес специальной функции-
заглушки, которая вычисляет адрес. передаваемого по.имени параметра.
‚ РЕЗИВШШИИИНИИИ | — Сложные приемы программирования
Передача параметров отложенным вычислением
Как и в предыдущем случае, здесь процедура получает адрес функции, вычис:
ляющей значение параметра. Такой механизм удобен, если вычисление значения
параметра требует много ресурсов или времени, например, если функция. должн:
’ выбрать один из нескольких ходов при игре в шахматы, вычисление каждого пара-
‚ метра может занимать несколько минут. Во время передачи параметров отложен:
ным вычислением функция получает адрес заглушки, которая при первом обраще:
нии к нейвычисляет значение параметра и сохраняет его во внутренней локальной
переменной, а при дальнейших вызовах возвращает ранее вычисленное значение.
Если процедуре вообще не потребуются значения части параметров (например,
если первый же ход приводит к мату), то использование отложенных вычислений
способствует выигрышу с большей скоростью. Этот механизм чаще всего приме-
няется в системах искусственного интеллекта и операционных системах.
Рассказав об основных механизмах передачи параметров процедуре, рассмот-
рим теперь варианты, где их передавать.
”Передача параметров в регистрах ,
Если процедура получает небольшое число параметров, идеальным местом для
их передачи оказываются регистры. Примерами служат практически все вызовы
прерываний РОЗ и ВТО. Языки высокого уровня обычно используют регистр
АХ (ЕАХ) для того, чтобы возвращать результат работы функции.
Передача параметров в глобальных переменных
Когда не хватает регистров, один из способов обойти это ограничение — запи:
сать параметр в переменную, к которой затем следует обращаться из процедуры.
Этот метод считается неэффективным, и его использование может привести к тому,
что рекурсия и повторная входимость станут невозможными.
Передача параметров в. стеке
_ Параметры помещаются в стек сразу перед вызовом процедуры. Именно этот
метод используют языки высокого уровня, такие как С и Разса]. Для чтения пара-
метров из стека обычно применяют не команду РОР а регистр ВР, в который по-
мещают адрес вершины стека после входа в процедуру:
ризв рагатетег1* | ; Поместить ‘параметр’ в. стек.
рузн рагатетег2 .
са11 ргоседиге
а9д зр, 4 2. ; Освободить’
стек от параметров:
[...} |
ргоседиге ргос пеаг
‚ рызН.. ..,.Бр, |
пом Бр, р :
(команды, которые могут использовать стек)
тому ах, [6р+4] ; Считать параметр 2.
‚; ЕГо адрес в сегменте стека ВР + 4,’потому что при выполнении команды САН.
; в стек поместили адрес возврата -`2 байта для процедуры
‚ типа МЕАН (или 4 - для РАВ), а’ потом еще и`ВР - 2 байта.
‘Процеду
и функции
ры о МЕТ
том Ьх, [6р+6] ‚ ‹; Считать. параметр 1.
(остальные команды) _
рор ор .
—_ ге*
ргоседиге епдр

Параметры в стеке, адрес возврата и старое значение ВР вместе называются


активизационной записью функции. В |
Для удобства ссылок на параметры, переданные В стеке, внутри функции иног-
да используют директивы ЕОП, чтобы не писать каждый раз точное смещение
параметра от начала активизационной записи (то есть от ВР), например так:
„’

‚рузП Х
. ризп У
ризп 2
са11 ху22у
[...}.
ху22у — ргос пеаг`
Ху27у_7 еди [5р+8
хуггу-у еду —^ [6^+6]
ху2ту_х. ди ‚[6р+4]
риузй Ыр
оу Бр, 5р. `
. (команды, которые могут использовать стек)
моу ах, ху2?у_х ‚Считать параметр. Х.
(остальные команды) | :.
рор Бр
гет 6
ху27у епар

При внимательном анализе этого метода передачи параметров возникает сразу


два вопроса: кто должен удалять параметры из стека, процедура или вызывающая
ее программа, и в каком порядке помещать параметры в стек. В обоих случаях ока-.
зывается, что оба варианта имеют свои «за» и «против+. Так, например, если стек
освобождает процедура (командой ВЕТ число байтов), то код`программы полу-
чается меньшим, а если за освобождение стека от параметров отвечает вызываю-
щая функция, как в нашем примере, то становится возможным последовательными
командами СА. вызвать несколько’ функций с одними и теми же параметрами.
Первый способ, более строгий, используется при реализации процедур в языке
Разса], а второй, дающий больше возможностей для оптимизации, -— в языке С. Ра-
зумеется, если передача параметров через стек ‘применяется и для возврата ре-
зультатов работы процедуры, из стека не надо удалять все параметры, но пойу- -
лярные языки высокого уровня не пользуются этим методом. Кроме того, в языке
С параметры помещают в стек в обратном порядке, (справа налево), так что стано-
вятся возможными функции с изменяемым числбм параметров (как, например,
реш! -первый параметр, считываемый ‘из [ВР+4], определяет число остальных
параметров). Но подробнее.о тонкостях передачи параметров в стеке рассказано
далее, а здесь приведен обзор методов. -
РЕОИШНШИНИНИШИ "Сложные приемы программирования
Передача параметров в потоке кода
В этом необычном методе передаваемые процедуре данные размещаются пря-
мо в коде программы, сразу после команды САЦ. (как реализована процедура
рип в одной из стандартных библиотек процедур для ассемблера ОСВТЛВ):
са1] ре1пт. |
Те “Тй1$ А$С12-11пе м111] Бе рглитеа”,0
(следующая команда). -

Чтобы прочитать параметр, процедура должна использовать его адрес, кото-


рый автоматически передается в стеке как адрес возврата из процедуры. Разуме-
‚ ется, функция должна будет изменить адрес возврата на первый байт после конца.
переданных параметров ‘перед выполнением команды ВЕТ. Например, процедуру
ришё можно реализовать следующим образом:
р, о [0 пеаг
/ ризй Бр
оу ор,зр
ризН ° ‘ах
ризп $1 |
мо $1, [6р+2] ; Прочитать адрес
* | ; возврата/начала данных. ..
с14 : ‚ Установить флаг направления
; для команды 1043. `
рг1пт_геадсраг: .
- 10436 ; Прочитать байт из строки:
Тезт а], а1 ; Если это 0 (конец строки),
° 2 рг1пт_допе ‚ вывод строки закончен.
111 291 ‚ Вывести символ в АЁ на экран.
тр ЗВогЕ рг1п{_геааспаг
рг1пе_.дбпе: . .
| Мом [6р+2 ], $1 ; Поместить новый адрес возврата в стек.
. рор’ $1 |
рор ах
рр р
гет
рез пт епдр

Передача параметров в потоке кода, так же как и передача параметров в стеке


в обратном порядке (справа налево), позволяет передавать различное число пара-
метров, но этот метод — единственный, дающий возможность передать по значению
параметр различной длины, что и продемонстрировал приведенный пример. Дос-
тут к параметрам, переданным в потоке кода, осуществляется несколько медлен-
нее, чем к параметрам, переданным в регистрах, глобальных переменных или стеке,
и примерно совпадает со следующим методом.
Передача параметров в блоке параметров
Блок параметров - это участок памяти; содержащий параметры, так жекак
и в предыдущем примере, но располагающийся обычно в сегменте данных.
Процедуры и функции.
Процедура получает адрес начала этого блока при помощи любого метода переда-
чи параметров (в регистре, в переменной, в стеке, в коде или даже в другом блоке
параметров). В качестве примеров реализации этого метода можно назвать мно-
гие функции ОО$ и ВГО$ - поиск файла, использующий блок параметров РТА,
или загрузка (и исполнение) программы, ‚использующая блок параметров ЕРВ.

5.2.2. Локальные переменные


Часто процедурам требуются локальные переменные, которые не будут нуж-
ны после того; как процедура закончится. По аналогии с методами передачи пара-
метров можно говорить о локальных переменных в.регистрах — каждый регистр,
который сохраняют при входе в процедуру и восстанавливают при выходе,
фактически играет роль локальной переменной. Единственный недостаток реги-
стров в роли локальных переменных — их слишком мало, Следующий вариант -—
хранение локальных данных в переменной в сегменте данных- удобен и быстр
для большинства несложных ассемблерных программ, но процедуру, использую-
щую этот метод, нельзя вызывать рекурсивно: такая переменная на самом деле яв-
ляется глобальной и находится в одном и том же месте в памяти для каждого
вызова процедуры. Третий и наиболее распространенный способ хранения ло-
кальных переменных в процедуре - стек. Принято располагать локальные пере-
менные в стеке сразу после сохраненного значения регистра ВР, так что на них
можно ссылаться изнутри процедуры, как [ВР-2], [ВР-4], [ВР-6] ит. д:
Гообаг . ргос пеаг — ,
Гообаг.х’ - еду [6р+8] ; Параметры. .
Тообаг_у еди [5р+6] |
фообаг_7 еци [6р+4]
Тообаг_1 еди [6р-2] `: Локальные переменные.
фообаг_м . еци [6р-4] |
Рообаг_п еду ([6р-6]

ризв Бр ; Сохранить. предыдущий ВР.


тому Бр,зр ;: Установить ВР для этой процедуры.
Зи6 эр, 6 _; Зарезервировать 6 байт для у
. ; локальных. переменных:
_ (тело процедуры)
тоу р, бр .; Восстановить $Р, `выбросив
; из стека все локальные ‘переменные.
рор ор ‚ Восстановить. ВР вызвавшей : процедуры.
. | ге. 5 ;. Вернуться, -.удалив ‚пареметры из; стека..
Тооваг. _ . епар. Е .

„Внутри процедуры ГооЪаг стек будетзаполнен ‘так, как показано на рис. 16.
Последовательности команд, используемые в начале и в конце названных проце-
дур, оказались настолько часто применяемыми, что в процессоре 80186 были введе-
НЫ специальные команды ЕМТЕК и ГЕАХУЕ, выполняющие эти же самые действия:
Рообаг - ргос пеаг : ;

Гообаг_х ед. [6р+8] ; Параметры.


тообагу = еб [6р+6]
222111
| 11т11 | Сложные приемы програ
ммирования
гообаг_2 . ва [6р+4]
Рообаг_1 еди ` [6р-2] ; Локальные переменные. `
Гоораг_м еди [6р-4] . |
Рообаг_п, еди [6р-6) : 12.
ептег 6, 0. ; ризй Бр [р |
; МОУ Бр,зр | ВР | <— ВР
; 346 зр,6 |
(тело процедуры) .
]еауе | ; пом $р,Бр [м_
| ‚ рор Бр | м |— 5
гет 6 ; Вернуться, удалив
В ”’ ‘`ъь параметры из стека.
Роораг ое епар _

Областьв стеке, отводимая для локальных перемен- © Рис. 16. Стек при
ныхэместе сактивизационной записью, называется сте- вызове процедуры
ковым кадром. о. юоБаг ..

5.3. Вложенные процедуры


Во многих языках программирования можно описывать процедуры внутри
друг друга, так что локальные переменные, объявленные в пределах одной проце-
дуры, доступны только из этой процедуры и всех вложенных в нее. Разные языки
программирования используют различные ‘способы реализации доступа к пере-
менным, объявленным в функциях с меньшим уровнем вложенности (уровень
вложенности главной процедуры определяют как 0 и увеличивают на 1 с каждым
новым вложением).
5.3.1. Вложенные процедуры со статическими ссылками
` Самый простой способ предоставить вложенной процедуре доступ к локальным
переменным, объявленным во внешней процедуре,— просто передать ей вместе с па- |
раметрами адрес активизационной записи, содержащей эти переменные (см. рис. 17).
При этом, если процедура вызывает вложенную вв себя процедуру, она просто
передает ей свой ВР например так: `
ризН Бр - ;
са11 пезтед - гос

То есть статическая и динамическая ссылки в активизационной записи проце-


дуры пезе4_ргос в этом случае не различаются. Если процедура вызывает дру-
гую процедуру на том же уровне вложенности, она должна 4 передать ей адрес
акъивизационной записи из общего предка:
ризВ [6+4] т пи ай
са11 реег_ргос

Если же процедура вызывает процедуру значительно меньшего уровня вло- `


женности, так же как если процедура хочет получить доступ к переменным,
Вложенные процедуры 2231

ВЗР ро дуры редка

№"
ыы — ссылка

ОИ
Рис. 17. Стек процедуры со статическими ссылками

объявленным в процедуре меньшего уровня вложенности, она должна проследо-


вать по цепочке статических ссылок наверх, вплоть до требуемого уровня. То есть,
если процедура на уровне вложенности 5 должна`вызвать процедуру на уровне
вложенности 2, она должна поместить в стек адрес активизационной записи внен-
ней по отношению к ним обоим процедуры с уровня вложенности 1:
1
пю\ 6х, [6р+4] ‚ ; Адрес записи уровня 4 8” ВХ.
‚ МОУ ‚Бх,
$$: [6х+4] . ^; Адрес записи уровня 3 в. ВХ.
моу 6х, 33: [6+4]. ; Адрес записи уровня 2 в ВХ.
ризН 3$:[6х+4] - ; Адрес ‘записи уровня 1 в стек.
са11 ргос_ат_1е\ме12 |
` Метод реализации вложенных процедур. имеет как преимущества, так и недо-
статки. С одной стороны, вся реализация вложенности сводится к тому, что в стек
помещается всего одно дополнительное число, а с другой стороны — обращение
к переменным, объявленным на низких уровнях вложенности (а большинство
программистов определяет все глобальные переменные на уровне вложенности 0),
так же как и вызов процедур, объявленных на низких уровнях вложенности, ока-
зывается достаточно медленным. Многие реализации языков программирования,
использующих статические ссылки, помещают переменные, определяемые на
уровне 0, не в стек, а в сегмент данных, но тем не менее существует способ, откры-
вающий быстрый доступ к локальным переменным с любых уровней:

5.3.2. Вложенные процедуры с дисплеями


Процедурам можно передавать не только адрес одной вышерасположенной
активизационной записи, но и набор адресов сразу для всех уровней вложеннос-
ти — от нулевого до более высокого. При`этом доступ к любой нелокальной про-
цедуре сводится всего`к двум командам,а перед‘вызовом процедуры вообще не
требуется каких-либо дополнительных действий (так как вызываемая нроцедуря
поддерживает дисплей самостоятельно).
ргос_ат_3 ргос пеаг | .
-рузВ Бр ; Сохранить. динамическую ссылку.
оу Бр, зр ; Установить адрес текущей записи.
Сложные приемы программирования
ризВ 913р1ау[ 6] ; Сохранить предыдущее значение адреса
` ; третьего уровня в дисплее.
оу 91$р1ау[6], Бр ; Инициализировать третий уровень в ‘дисплее.
5и6 эр, М ‚ Выделить место для локальных переменных.
(...] . . :
тоу Ьх, 915р1ау[4] ; Получить адрес записи для уровня 2.
По . ах, 3$: [6х-6] ; Считать значение второй
; переменной из уровня 2.

ад4 эр, п ; Освободить стек от локальных переменных.


рор 915$р1ау[6] ; Восстановить старое
: ; значение третьего уровня в дисплее.
рор бр
гет |
ргос_а{_3 - епар
. 1

Здесь считается, что в сегменте данных определен массив слов 41зр1ау, имею-
щий адреса последних использованных активизационных записей для каждого
уровня вложенности: 41зр!ау[0] содержит адрес активизационной записи нулево-
го уровня, 41зр]ау{2] - первого уровня и так далее (для близких адресов)..
Команды ЕМТЕВ и ГЕАУЕ можно использовать для организации вложеннос-
ти с дисплеями, но в такой реализации дисплей располагается не в сегменте дан-
ных, а в стеке, и при вызове каждой процедуры создается его локальная копия.
; ещег №,4 (уровень вложенности 4, М байтов на стековый кадр) эквивалентно набору команд
ризй © Бр _; Адрес записи третьего. уровня.
рызв [Ьр-2] у
ризй - [6р-4] . А
ризн [6р-6]
ризй [6р-8] ‚ Скопировать дисплей.
пом Ор, эр ;
а94 Бр, 8 ; ВР = адрес начала дисплея текущей записи.
$и6 зр, № ; Выделить кадр для локальных переменных.

Очевидно, что такой метод оказывается крайне неэффективным с точки зре-


ния как скорости выполнения программы, так и расходования намяти. Более того,
‚ команда ЕМТЕК вынолняется дольше, чем соответствующий набор простых ко-
манд. Тем не менее существуют ситуации, когда может потребоваться создание
локальной копии дисплея для каждой процедуры. Например,‘если процедура,
адрес которой передан`как параметр другой процедуре, вызывающейся рекурсив-
но, должна обращаться к нелокальным неременным. Но и в этом случае передачи
всего дисплея через стек можно ‘избежать — более эффективным Методом оказы-
ваются простые статические ссылки, рассмотренные ранее.

5.4. Целочисленная арифметика.


повышенной точности
Языки высокого уровня обычно ограничены в наборе типов данных, с которыми
они могут работать, — для хранения целых чисел применяются отдельные байты,
‘Арифметика повышенной точности
слова или двойные слова. Используя ассемблер, можно придумать тип данных
совершенно любого размера (64 бита, 128 бит, 1024 бита) и легко определить все
арифметические операции с такими ‘числами. —

5.4.1. Сложение и вычитание


Команды АОС (сложение с учетом переноса) и $ВВ (вычитание с учетом зай-
ма) специально были введены для подобных операций. При сложении сначала
складывают самые младшие байты, слова или двойные слова командой АО, а за-
тем складывают все остальное командами АОС, двигаясь от младшего конца чис-
ла к старшему. Команды ЗО ВУ/ЗВВ действуют полностью аналогично.
510\а1_1 99 . 000. Вр ; 96-битное число,
Ь19\а1_2 да 0,0,0 `
Ь19\а1_3 99 . 0,0,0

; сложение 96-битных чисел 619а1_1 и 619\а1_2


. МОУ еах, диога ртг 619\а1_1 . ,
’ ад вах, нога рег. 610\а1_2 ; Сложить младшие двойные слова.

оу бог ртг Б19уаТ 3, еах-


тому еах, Чмог@ рЕг 519%а1-1Ё4]
а4с =. еах,диога раг Ь19уаТ_2[4] о ; Сложить. средние двойные слова.

том Чмога рег 6109уа1 314], еах


моу еах, диогв рег 519%а1_1[8:
адс еах, диогф рёг 519\%а1-2[8] 7 Сложить старшие двойные слова.

мо\ @мога ртг. 619%а1


_3{ 8], еах |

; вычитание 96-битных чисел Ь10уа]_1 и 6519\а1_2

тому еах, дмюг@ ртг Б+09\а1_1. , | .


$46 еах, ЧиогФ ‘руг В19\уа1_2 .. Вычесть младшие двойные слова.

° оу дмогФ рег 619\а1_3,еах =


моу еах, диог4 рег 519\а1_1[4]
ББ еах, диога ртг 519%а1_2[4] ; Вычесть средние двойные слова.

оу Фмога рг Ь19\а1_3[4], еах


` МОУ ‚вах, днога руг 519%а1_1[8]
355 _ вах, дмога рег 619\а1_2[8] ; Вычесть старшие двойные слова.

моу еах
‘Змога рег 610%а1_3[8], о

5.4.2. Сравнение | | `
Поскольку команда сравнения эквивалентна команде вычитания (кроме того,
что она не изменяет значение приемника), можно было бы просто выполнять вы-
читание. чисел повышенной точности и отбрасывать результат, но сравнение вы-
полняется и более эффективным образом. В большинстве случаев для определе-.
ния результата сравнения достаточно сопоставить самые старшие слова (байты
или двойные слова), и только если они в точности равньь потребуется сравнение
следующих слов.
8 Зак. 459
|! — Сложные приемы программирования
; Сравнение 96-битных -чисел -519\а1_1 и Ь109\а1_2. в `,
МОУ | вах, @ыога руг 619\а1_1[8], .
стр. еах, Чиог4 руг 619%а1_2[8]; Сравнить старшие слова.
и огеатег `
1 ]е55 у
пом еах, Чиогд рфг 619%а1_1[4}
стр вах, Чмог@ ртг` 619%а1_2[4}; Сравнить средние :слова,
19.’ `. дгеатег: ” в
31 1е5$ .
поУ вах,дмога рег 619уа1_1 . | ‘
стр „вах, диога руг. 619%а1_2 ; Сравнить младшие слова.
79 дгеатег .
д 1е5$
едиа]:
огеатег:
]езз:

5.4.3. Умножение
Чиобы умножить числа повышенной точности, придется вспомнить правила
умножения десятичных чисел в столбик: множимое.умножают на каждую цифру
множителя, сдвигают влево на соответствующее число разрядов и затем склады-
вают полученные результаты. В нашем случае роль цифр будут играть байты, сло-
ва или двойные слова, а сложение должно выполняться по правилам сложения
чисел повышенной точности. Алгоритм умножения оказывается заметно сложнее,
поэтому умножим для примера только 64-битные числа:
; Беззнаковое умножение двух 64-битных чисел (Хи У) и сохранение
; результата в 128-битное число 7.
му еах, @мог4 ртг Х
ту =® еБбх,еах |
ми] 9мога рег У ; Перемножить младшие двойные слова. '
Де Чмога рфг 2, еах ; Сохранить младшее слово произведения.
оу есх,едх ^’ ’ ; Сохранить старшее двойное слово.
поу еах, ебх ; Младшее слово “Х” вах. :.
‚ МиТ Фиот9 рег \[4] ; Умножить младщее слово на старшее.
ада. ‚ еах,есх.
адс `е9х,0 ‚ Добавить перенос. .
оу еБх, еах ; Сохранить частичное произведение.
МОУ есх, еах |
том вах, Зиога ртг Х[4] .
ми диога рег У ; Умножить старшее ‘слово ‘на младшее.
’ а99 ‚вах, ебх . ; Сложить с частичным произведением,
мо\ Ч9иога рфг 2[4},еах |
аЧс есх, едх
том еах, Чиога рег ХЁ4]
ми Чиога рег \[4] ‚ Умножить старшие слова,
а49 = вах, есх ; Сложить с’ частичным `произведением
адс едх, 0 ; и добавить перенос. |
оу мога рег 2[8],еах °
том мог рфг’ 7[12], едх
Арифметика повышенной точности 8
Для выполнения умножения со знаком потребуется сначала определить знаки
множителей, изменить знаки отрицательных множителей, выполнить обычное
умножение и изменить знак результата, если знаки множителей были разными.

5.4.4. Деление
Общий алгоритм деления числа любого размера на число любого размера
нельзя построить с использованием команды ПТУ- такие операции выполняют-
ся при помощи сдвигов и вычитаний и оказываются весьма сложными. Рассмот-
рим сначала менее общую операцию (деление любого числа на слово или двойное
слово), которую можно легко осуществить с помощью команд ОТУ:
Деление 64-битного числа: 91\у14епт на’ 16-битное число 91\150г.
; Частное помещается в 64-битную переменную диотепт,
; а остаток - в 16-битную переменную моди1о.
МОУ ах, могд рёг 91\14еп1[6]
хог 9х, ах
_ 91% 91%1$0г у
- ОУ мог@ ртг диофепт[6}], ах:
; МОУ ах, мога ртг. 91\14епт[4}
91% ` 9113 0г-
моу мога рег. диотей([4], ах.
_ МОУ ах;могв руг оулдете2]
Чу 91\150г | ,
оу мог рег отв [2] ах -
по ах,мога руг 91м14етт _- |
91у 91\1$0г
мо мог ртг дуотепт,ах
моу моди1о,9х

Деление любого другого числа полностью аналогично — достаточно только °


добавить нужное число троек команд шоу/4у/тоу в начало алгоритма.
Наиболее очевидный алгоритм для деления чисел любого размера на числа
любого размера - деление в столбик с помощью последовательных вычитаний
делителя (сдвинутого влевона нужное количество разрядов) из делимого, увели-
чивая соответствующий разряд частного на 1 при каждом вычитании, пока не
останется число, меньшее делителя (остаток):
Деление 64-битного числа в ЕБХ:ЕАХ на 64-битное. чисто в`ЕСХ:ЕВХ.
‚ Частное помещается в ЕОХ:ЕАХ, и остаток - в ЕЗТ: ЕОТ.
А ебр, 64°; Счетчик битов.
Хог 231, ез1 ,
хог е91,е91 ; Остаток = 0.
. 1 1оор:; $11 еах,1
гс] едх, 1 . :
гс1 ед1, 1 ; Сдвиг на 1 бит влево 128-битного числа.
гс] е31, 1 ; ЕЗГ:ЕОТ:ЕОХ:ЕАХ.
стр ез1,есх ; Сравнить старшие двойные слова.
Ча 91\14е |
75 пех
РЯЗИШШИИИШИШИЕ | Сложные приемы программирования
стр 201, ебх ; Сравнить младшие двойные .слова. ,
6 пехе у |
91у19е:
$иБ е91, ебх `
66 е$1,есх ; ЕЗТГ:ЕОТ = ЕВХ:ЕСХ. .
`1пс еах ‚ Установить младший бит в ЕАХ.
пехт: дес ебр ; Повторить цикл 64 раза. |
те Ь11100р

Несмотря на то что этот алгоритм не использует сложных команд, он выпол:


няется на порядок дольше, чем одна команда ОГУ,

5.5. Вычисления с фиксированной запятой


_ Существует широкий класс задач, где требуются вычисления с
вещественны-
ми числами, но не нужна высокая точность результатов. Например, в этот класс
задач попадают практически все процедуры, оперирующие с координатами и цве-
тами точек в дву- и трехмерном пространстве. Так как в результате все выведетс
я
на экран с ограниченным разрешением и каждый компонент цвета будет записы-
ваться как 6- или 8-битное целое число, все те десятки знаков после запятой,
ко-
торые вычисляет ЕРО,не нужны. А раз не нужна высокая точность, вычисление
можно выполнить значительно быстрее. Чаще всего для представления вещест-
венных чмсел с ограниченной точностью используется формат чисел с фикси-
рованной запятой: целая часть числа представляется в виде обычного целого чис-
ла, и дробная часть - точно так же в виде целого числа (как мы записываем
небольшие вещественные числа на бумаге).
Наиболее распространенные форматы для чисел с фиксированной запятой

8:8 и 16:16. В первом случае на целую и на дробную части числа отводится по
одному байту, а во втором — по одному слову. Операции с этими двумя формата-
ми можно выполнять, помещая число в регистр (16-битный - для формата 8:8
и 32-битный - для формата 16:16). Разумеется, можно придумать и использовать
совершенно любой формат, например 5:11, но некоторые операции над такими
числами могут усложниться. | | |
`5:5.1. Сложение и вычитание
Сложение и вычитание для чисел с фиксированной запятой ничем не отлича-
ется от сложения и вычитания целых чисел:
оу ах, 10801 _ ; АХ = 10808 = 16,5
то\ Ьх, 12401 _ ; ВХ = 1240Н = 18,25
а99 ах, Бх ` ; АХ = 22608 = 34,75
Зи ах, 6х | ; АХ = 10801 = 16,5

5.5.2. Умножение
р При выполнении этого действия следует просто помнить, что умножение 16-бит-
ных чисел дает 32-битный результат, а умножение 32-битных чисел — 64-битный ре-
зультат. Например, пусть ЕАХ и ЕВХ содержат числа с фиксированной запятой
в формате 16:16; ^ | |
ЕО |
ной запятой
‚ Вычисления с фиксирован
хог едх, едх
— м1 ебх | ; Теперь ЕОХ:ЕАХ содержит 64-битный результат
всю целую часть, а ЕАХ - всю дробную). .
; (ЕОХ содержит
$Аг@ еах ‚едх, 16 ; Теперь ЕАХ содержит ответ, если не
; произошло переполнение (то. есть если результат не превысил 65 535).

Аналогом МОУ. в таком случае будет последовательность команд


`
1ти1 ебх
эАГ@ ›» вах, едх, 16

_ 5.5.3. Деление
Число, записанное с фиксированной запятой в формате 16:16, можно предста-
вить как число, умноженное на 216. Если разделить такие числа друг на друга сразу —
мы получим результат деления целых чисел: (А х216) /(ВХ 216) = А/В. Чтобы ре-
зультат имел нужный нам вид (А/В) Х 205, надо заранее умножить делимое на 216;

; Деление числа’с фиксированной` запятой-в формате 16:16


; в регистре ЕАХ на такое же число в ЕВХ, без. знака:
‚ ХОГ едх, едх
Гог еах, 16 . р
: ХСНа ах, 4х | ; ЕОХ:ЕАХ = ЕАХ х 2%
1 еБх ‘у ВАХ = результат деления,

; Деление числа с фиксированной запятой в формате 16:16


; в регистре ЕАХ на такое же число в ЕВХ, со знаком:
с94
Гог гах, 16 `
хсп9 ах, 9х ; ЕОХ:ЕАХ = ЕАХХ 2%.
191У ебх ‚ ЕАХ = результат деления.

5.5.4. Трансцендентные функции -


Многие операции при работе с графикой используют умножение числа на синус
(или косинус) некоторого угла, например при повороте: $ = зт(п) Х у. При вычис-
х
лении с фиксированной запятой 16:16 это уравнение преобразуется в $ = шКяп(п)
х 65 536) х у/65 536 (где ше — целая часть). Для требовательных ко времени работы
участков программ, например для работы с графикой, значения синусов принято
считывать из таблицы, содержащей результаты выражения шКяп(п) Хх 65 535),
где п меняется от 0 до 90 градусов с требуемым шагом (редко требуется шаг мень-
ь
ше 0,1 градуса). Затем синус любого угла от 0 до 90 градусов можно вычислит
с помощью всего одного умножен ия и сдвига на 16 бит.`Син убы и косинусы дру-
гих углов вычисляются в соответствии с обычными формулами приведения:
$11(х) = $11(180-х) для 90 <х < 180
з1п(х) = -з1п(х-180) для 180 <х < 270
з1п(х) = -511(360-х) для 270 <х < 360.
с03(х) = з1п(90-х)

хотя часто используют таблицу синусов на все 360 градусов, устраняя дополни-
тельные проверки и изменения знаков в критических. участках программы.
‚ РЕРМШИИИИИНИИИ | — Сложные приемы программирования
Таблицы синусов (или косинусов), используемые в программе, можно создать
заранее с помощью простой программы на языке высокого уровня в виде тексто-
вого файла с псевдокомандами О\У/ и включить в текст- программы директивой
псаде. Другой способ, занимающий меньше места в тексте, но чуть больше вре-
мени при запуске программы, — однократное вычисление всей таблицы. Таблицу
можно вычислять как с помощью команды ЕР\) 51 и потом преобразовывать к же-
лаемому формату, так и сразу в формате с фиксированной запятой. Существует
довольно популярный алгоритм, позволяющий вычислить таблицу косинусов
(или синусов, с небольшой модификацией), используя рекуррентное выражение
соз(х,) = 2603(э1ер)соз(х,,) - соз(х,,)
где $ер — шаг, с которым вычисляются косинусы, например 0,1 градуса.
; 938.азт
‚ Строит фигуры Лиссажу, используя арифметику с ‘фиксированной запятой
и генерацию таблицы косинусов.
‚ Фигуры Лиссажу - семейство кривых, задаваемых параметрическими выражениями
; х(Е) = соз($САЕЕМ х т) .
; У(Е) = з1т(3САЦЕ Нх $)

; Чтобы выбрать новую фигуру, измените параметры ЗСАГЕ_Н и ЭСАЕЕ М,


' Для построения. незамкнутых фигур удалите строку аб 91,512 в процедуре моуе_ро1пт.
.04е? Т1пу
. соде
.386 ; Будут использоваться 32-битные регистры.
0го 1008 ; СОМ-программа.
ЭСАЕЕ.Н еди 3 ; Число периодов в фигуре по горизонтали.
ЗСАЕЕМ едби 5 ; Число периодов по вертикали.
этаге ргос пеаг |
с19 | ; Для команд строковой обработки.
том: 91, оГГзет с0$_ пабе ‚ Адрес начала таблицы косинусов.
том ебх, 16777137 ° ; 224 х с0о3(360/2048) - заранее. вычисленное
моу - сх, 2048 `^ ; число элементов для таблицы,
са11 Би119_тае ; Построить таблицу косинусов.
мо ах, 00131 ; Графический режим
111 10н ; 320х200х256.
моу ах,.1012н ; Установить набор регистров палитры УбА,
оу Бх, 70Н ; начиная с регистра 70Н.
оу сх, 4 ; Четыре регистра.
му 9х, огРзет ра1е{те ; Адрес таблицы цветов.
171 108
ризн. 0А000Н ‚; Сегментный адрес видеопамяти
рор . е$ ; в Е.

та1п`10ор:
са11 — а1зрфау_растиге ; Изобразить точку со следом.
Вычисления с фиксированной запятой
ТОМ 9х, 5000
гхог сх, сх
ОМ ав, 861 |
Пауза “на СХ:0Х микросекунд.

поу ап, ЛА. о: Проверить, была ли нажата клавиша.


10 168 :
7 тма1п_1о0р .. .; Если нет - продолжить основной цикл”
‘оу — ах,000З8 ^ \Гекстовый режим
"пт 108 ; 80х24.

гет : Конец программы.


зтагт епар
; Процедура Би119_таб1е.
Строит таблицу косинусов в формате с фиксированной запятой 8:24
; по рекуррентной формуле со&(х,) = 2х 60$ (зрап/зТерз) х соз(х,..) - соз(х, +),
где зрап - размер. области, на которой вычисляются косинусы. (например, 360),
а этерз - число шагов, на которые разбивается область.
; Вход: 0$:01 = адрес таблицы
; 05:[01]= 224
; | ЕВХ = 224 х соз(зрап/зерз)
_; СХ = число элементов таблицы, ‘которые надо вычислить
; Выход: таблица размером СХ х 4 байта заполнена
; Модифицируются: ОТ, СХ,ЕАХ,
ЕБХ

Би114_Таб]е ргос ‚ пеаг


тому @иога рЁг [91+4], е5х ; Заполнить второй элемент таблицы.
$46 сх, 2 ; Два элемента уже заполнены.
„ а99 91,8 .
му еах, ебх
6и119_таБ1е_1оор:
ин еБх ; Умножить с03(зрап/зтерз) на со3(х, ,).
$Агд вах, е9х, 23 ; Поправка из-за действий с фиксированной
запятой 8:24 и умножение на 2.
Зи6 еах, Чмога рег [91-8 ; Вычитание с03(х,,).
510$4 ; Запись результата в таблицу.
]оор Би319_фаб1е.
1оор
ге!
6и119_табБ1е епдр

; Процедура 41зр1ау_р1стиге.
; Изображает точку со следом.
91$р]ау_р1сфиге ргос пеаг
са11 томе_ро1 пт ' . Переместить точку.

мо Бр, 7ЗА . | ; Темно-серый цвет в нашей палитре.


моу Ьх, 3 | ; Точка, выведенная ‘три шага назад.
са11 Чгам_ро1пт ; Изобразить ее.
дес Бр ; 72н - серый цвет в нашей палитре.
дес Ьх ; Точка, выведенная: два шага назад.
РЕНИ Сложные приемы программировани:
‹ са1} дгам_ро1пт ; Изобразить ее.
дес _ Ш ; 7 - светло-серый цвет в нашей палитре.
дес 5х ‚ Точка, выведенная один шаг назад,
° са11 гам _ротпт ‚ Изобразить ее.
ес Бр ; ТОВ - белый цвет в нашей палитре.
дес ьх ! ; Текущая точка.
са1] Чгам_ро1 пт ; Изобразить ее.
гет
91зр1ау_р1сфиге- епдр

; Процедура 9гам_ро1пт.
; Вход: ВР - цвет
, ВХ - сколько шагов назад выводилась точка .
,
гам _ро1ит ргос пеаг
моу7х сх, Буте рёг ро1т_х[Ьх] ; Х-координата.
мо\У7х 9х, буте рег ро1пт_У[Ьх] ; У-координата.
са11 рутр1хе1_ 131 ; Вывод точки на экран.
гет
Фгам_ро1пт епар

‚ Процедура тоуе_ро1пт. . : `
; Вычисляет «координаты для следующей точки.
; Изменяет координаты точек, выведенных раныше.

моуе_ро1 пт ргос пеаг


Тис мога рфг Не
апд мога ‘рег т1те, 2047 |; Эти две команди организуют счетчик
в переменной. 1те, который изменяется от 0 до 2047 (7ЕРВ)
моу еах, диога рег ро1пе_х ; Считать координаты точек
тому ебх, Чиога рег ро1ие_у ; (по байту на точку)
моу - Чнога рег ро1пе_х[1], еах ; и-записать их.со сдвигом
поу ‘бмог@ рег ро1пт_У[1],е5х ; 1 байт.
тоУ ‹ 01,м0гд рхг ф1те ‚ Угол (или время) в ОТ
ти] 01,41, ЗСАЕЕ_Н ; Умножить его на ЗСАЕЕН.
апа 91, 2047 ‚ Остаток от деления на. 2048,
$81 91,2 ‚ Так как в таблице 4 байта на косинус.
оу ах, 50 | ; Масштаб по горизонтали.
ми] мога рёг со$_Та61е[41+2] : Умножение на косинус: берется старшее
‚ слово (смещение + 2) от косинуса, записанного в формате
8:24.
‚ ‚; Фактически происходит умножение на косинус в формате 8:8.
оу Чх, 040008 ; 320/2 (Х центра экрана) в формате 8:8.
ЗиБ 9х, ах ; Расположить центр фигуры в центре экрана
оу буте руг ро1пе_х,ан ‚; И записать новую текущую точку.
оу 91, мог руг т1те - ‚ Угол (или время) в ОТ
и 91, 41, ЗСАЕЕ У ; Умножить его на ЗСАГЕ М.
ада .91,512 ; Добавить 90 градусов, чтобы заменить
‚ косинус на синус. Так как у нас 2048 шагов на 360 градусов,
; 90 градусов - это 512 шагов.
апд 91, 2047 | ; Остаток от. деления на. 2048,
Вычисления с плавающей запятой 2331
$81 -91,2 ; так как в лаблице 4 байта на косинус.
пом ах, 50 ; Масштаб по вертикали...
и мог@ рег соз_{а61е[91+2] ; Умножение на косинус.
Мом 9х, 064001 Г : 200/2 (У центра экрана) в формате. 8:8.
-зы6 9х, ах . ; Расположить центр фигуры в центре экрана
тоу Буе рег ро1пт_у,п ; и записать новую текущую точку.
гет | +
поме_ро1пт епар
; рикр1хе1_138
‚: Процедура вывода точки на экран в режиме 138.
; 0Х = строка, СХ. = столбец, ВР = цвет, Е = АбООН
ритр1хе1 _13н ргос пеаг
ризп 91
ЮУ ах,9х . ; Номер строки.
$11 ах, 8 ‹ Умножить на 256.
моу 91,ах
$11 91,6 ; Умножить на 64
ад 91, ах ; и сложить - То же, что ‘и. умножение на 320.
ааа 91, сх ; Добавить номер столбца.
по ах, Бр .
эфозЬ . ‚ Записать: в видеопамять.
рор 91
гет
ритр1хе1 131 епар

ро1п_х [69 ОЕРв, ОРЕП, ОРРИ, ОРЕЙ ; Х-координаты точки и хвоста.


ро1пт_у 96 ОЕЕВ, РЕ, ОРЕЙ, ОРРИ ; У-координаты точки Й’ хвоста,
| 95 ? - ; Пустой байт’- нужен для команд
: ; сдвига координат’ на один байт.
11те Чи 0 ; Параметр в уравнениях Лиссажу - время
; или угол.

ра1етте 95 ЗЕв, ЗЕв, ЗЕ® ‚ Белый.


[6] зов, зон, 301 `; Светло-серый.
6 201, 201, 208 ; Серый.
95 10н, 101,10 ^ ; Темно-серый.

бо$ тае ^ 99 10000005; Здесь начинается таблица КЭсинусов.


епа ЗТагт

При генерации таблицы использовались 32- битные регистры, что приводит


к увеличению на 1 байт и замедлению на 1 такт каждой команды, применяющей
их в 16-битном сегменте, но на практике большинство программ, интенсивно ра-
ботающих с графикой, -- 32-битные.

5.6. Вычисления с плавающей запятой


Набор команд для работы с плавающей запятой в процессорах пб] достаточно
разнообразен, чтобы реализовывать весьма сложные алгоритмы, и прост в исполь-
зовании. Единственное, что может представлять определенную сложность, — почти
| Сложные приемы программировани:
все команды РРИ по умолчанию работают сего регистрами данных
как са ‘стеком
выполняя операции над числами в $Т(0) и $Т(1) и помещая результ
ат в $Е(0), та!
что естественной формой записи математических выражений для
ЕРО оказыва
ется обратная польская нотация (КРМ). Эта форма записи встреча
ется в програм
мируемых калькуляторах, языке Форт и ночти всегда неявно присутс
твует во все;
алгоритмах анализа математических выражений: они сначала
преобразовывают
обычные выражения в обратные и только потом начинают их анализ.
В обратно}
польской нотации все операторы указываются после своих аргум
ентовтак
, чтс
$т(х) превращается в хэш, аа+Ь превращается ваЪ +. При этом
полностью про-
падает необходимость использовать скобки, например: выражение (а
+5) х7- с
записывается кака +7 ха-.

Посмотрим, как выражение, записанное в КРМ, на примере процедуры
вычис-
ления арксинуса легко преобразовываетсяс помощью команд ЕРИ.
; аз1п
; Вычисляет арксинус числа, находящегося в 51(0) (-1 < х< +1),
‚ По формуле аз1п(х) = атап(34 ге (х2/(1-х2)))
; (в НРМ: хх «= ххя 1-1 загЕ атап).
; Результат возвращается в $1(0), в стеке ЕРУ должно быть два свободных регистра.
а$1п ргос пеаг ; Комментарий показывает содержимое стека ЕРИ:.
ы ; Первое выражение - 5Т(0), второе - $Т(1у ит. д. |
; Х (начальное состояние стека)
#19 510) Хх, Хх
ти ;
#14. $1(0) г, х?
2191 1х, же
фзирг ; 1-х2, х2
РА у ; Х2/(1-х?)
ЕзагЕ °; Заге(х2/(1-х?))
#191 ; 1, загЕ(х2/(1-х?))
Рратап \ ; афап(загЕ(х2/(1-хг)))
` гет .
а$1п епар
. #
.

Теперь попробуем решить небольшое дифференциальное уравнение


- уравне-
ние Ван-дер-Поля для релаксационных колебаний:
Хх" = -х + м(1-х2)х', > 0
будем двигаться по времени с малым шагом В, так что
Х(Е + В) =.х(+) + пх(ф)'
х(Е + В)” = х(1)° + вх(+)"
или, сделав замену у = х',

у = у + 1(м(1-х?)у - х)
х = х + Пу

Решение этого уравнения для всех т > 0 оказывается


периодическим аттрак-
тором, поэтому, если из-за ошибок округления решение
отклоняется от истинного
Вычисления с плавающей запятой
в любую сторону, оно тут же возвращается обратно. При т =-0, наоборот;решение
оказынается неустойчивым и ошибки округления приводят к очень быстрому
росту х и у до максимально допустимых значений для вещественных чисел.
‚Эту‹программу нельзя реализовать в целых числах или числах с фиксирован-
ной запятой, потому что значения х и х' различаются на много порядков- кривая
содержит почти вертикальные участки, особенно при больших т.
; Мар. ам
; ‘Решение уравнения Ван-дер--Поля'
; ин = -х() + м(1-х(1)?)х(#)°
; =.0, 1, 2, 3, 4, 5, 6, 7, 8.

‚ Программа выводит на экран.решение. с м`= 1, нажатие клавиш 0-8 изменяет м.


; Езс - выход, любая другая клавиша - пауза до нажатия одной из Ес, 0-8.

.тове] 11пу
. 286 ; Для команд ризпа и рора.
.287 ; Для Команд ЕРУ.
. соде
_ ог9 1001 _ _; СОМ-программа.
Тат ргос пеаг
с14
рузН 0А0ООв
рор е5 . ; Адрес видеопамяти в ЕЗ.

моу ах, 00121


11 108. ; Графический режим 640х480х16.

Ни ; Инициализировать ЕР.

хог _ ЗЫ, 81 | ; 51 будет содержать координату т и меняться


; от 0 до 640.
#131 ; 1
1119 мог рег П1пу ; 32, 1
е91У п о (@= ТИ)
; Установка начальных значений для _@1зр1ау: р
;Ш=1, х=И= 1/32, у=зх =0
ада1п: 1119 могб рег м мо
119 $1(1) хм, п (х=в)
#197 Бу, х, № В (у=0)
са11 _913р1ау °; Выводить на экран решение, пока
; не будет нажата клавиша.
`9_Кеу: тоу ан, 101 ; Чтение клавиши с ожиданием.
17 161 ; Код нажатой клавиши в А+.
стр а}, 1ВВ ; Если это Езс, |
}2 ) 9_оит ; выйти из программы.
стр а], ’0’ ; Если код меныве “0”,
6 д_кеу ; пПауза/ожидание следующей клавиши.
стр а], '8’ ; Если код больше “8”,
‘Г За 9_Кеу ° ‚ Пауза/ожидание ‘следующей. клавиши.
г зи6 а1,'0' ; Иначе: АС =, введенная цифра,
Сложные приемы программирования
моу руте ртг м, а1 м - введенная
, цифра._
эр 31(0) ‚ х м,.П
Еэфр $1(0) , Ш в
Езтр $1(0) И
тр зПогЕ ада1т

901: поу. ах, 0003 в Текстовый режим.


171 101
гет | Конец программы. \ <,
ЭТаге епар

; Процедура 41зр]ау_.
; Пока не нажата клавиша, выводит решение на экран, делая паузу после каждой из
; 640 точек.
^

_915р1ау ргос пеаг


915тоге:
моу 6х, 0 ; Стереть предыдущую точку: цвет = 0.
воу СХ, $1
ИГ сх,1 ; СХ - строка.
му дх, 240
ив бх,мога рёг 1х[31] ; ОХ - столбец,
са11 *“ ритрухель
са] 1 пехт_х ; Вычислить х({) для следующего +.
мо ох,1 ‚ Вывести точку: цвет = 1.
пом ах, 240
зи6 ах, мог рег 1х[31] ; ОХ - столбец.
са11 ритр1хе11Ь
1пс $1
1пс $1 ; 1 = 91 +2 (массив слов).
стр $1, 640*+2 , ‚ Если 5Т достигло конца массива ТХ,
71 по{_епазсгееп ‚ пропустить паузу.
ЫИ 31, 640*2 ; Переставить 5Т на начало массива 1Х.
по{_епазсгееп:
поу ах, 5000
хог сх, сх
тоу ав, 868
11 151 ; Пауза на СХ:0Х микросекунд.
оу ан, 118
111 161 ‚; Проверить, была ли нажата клавиша.
72 91зтоге ‚; Если нет - продолжить вывод на экран.
гет ; Иначе - закончить процедуру. ,
_91$р1ау епар

; Процедура пехт_х.
; Проводит вычисления по формулам:
‚; у=у+ п(м(1-х^2)у-х)
р х=х + Ву
; Вход: $1 = у, $1(1) =х, $1(2) = м, $1(3) = |.
; Выход: 51 = у, 8%(1) =х, $1(2) = м, 31(3) = В, Х * 100 записывается в 1х[51].
Вычисления с плавающей запятой
пехЕ_х ргос пеаг
#191 ; Ту х, м п
19 $1(2) ух, 1, у, х, №, п
ти] эт, 81(3) ; х2, 1, у, х, м, В
156 ; (1-х2), у, х, м, п и
#14 $1(3) ом, (1-х2): у, х, м, Н
ти] М, у, х, №, Ш (М = м(1-х2))
119 $1(1) уу, М, у, Хх, №, п |
тЫ с Му у хм, В,
#19 $1(2) ох, Му, у, х, м, В
тЗиБ ; Му-х, у, х, м, В
+19 31(4) о И, Му-х, у, х, м, В
_ Пы ‚ ; И(Му-х), у, х, м, 1
#9 51(1) - ; у, П(Му-х), у, х, м, В
тада у у, у х, № В (У =у + п(М-х))
Рхс Бу, у, х, м |
я $1(4) д: у, У, Хх, м п
ти] уп, \, Хх, м И,
. Радар $1(2), 1 гу Х; м; В : „ {ХФ=х + Пу)
119 $1(1) :хухювп
1119 мога ртг с 100 ;.190, Х, У,.Х, м, В. 2
Ти _; 100%, У, Х, м, В -
Нар мог@ раг 1%[81] ; \, Х, п, 1
гет |
пех Хх, . епар ы

: Процедура вывода точки на экран в режиме, использующем 1°бит на пиксел.


; ОХ = строка, СХ = столбец, Е = АОООВ, ВХ = цвет (1. -`белый, 0 - черный). >
; Все регистры сохраняются.
ритрахе11Ь ргос пеаг
ризпа .-: 2 Сохранить регистры,
„рузИ Ьх
хог хх | в
во\ ах, 9х | ; АХ = номер строки.
11 ах, ах, 80 ; АХ = номер строки х число байтов в строке.
ризН `сх | --
5Вг сх, 3 ‚ СХ =`номер байта в строке.
а9д ах, сх ; АХ = номер байта в видеопамяти.
поу 91, ах его в БГ и 51.
; Поместить’
тому $1,91

рор вх ‚. ; Соснова содержит номер столбца.


< МОУ Ьх, 00801
`апд сх, 078 ; Последние. три бита СХ =
; остаток сот деления на 8 =
. номер бита в байте, считая справа налево.
ЭВг Ьх, с1 ; Теперь нужный бит в ВЕ установлен в 1.
109$ ез':Буте рег 1х ; АЁ = байт из видеопамяти.
‚рор ах И
‚ бес 9х ; Проверить цвет.
Сложные приемы программировани
`]з Б]аск: ; Если 1 -
ог ‚ ах,вх ‚ установить выводимый битв 1.
тр. ЗПОГЕ мН1те
Б]аск: пот- ъх о; ли 0 -
апд ах,0х <. ‚ установить выводимый цвет в 0
мп Те: _ -- . .
Зт03Ь ` ;.и вернуть байт на место.
рора . ; Восстановить регистры.
гет ; Конец.
рифр1хе11Ь епдр . р
м .. @м 1 ; Начальное значение п,
с_100 о би 100 ; Масштаб по вертикали,
В1пУ вм 32 ; Начальное значение `1/п.
1х: ; Начало буфера для значений х(т)
| ; (всего 1280 байт за концом программы).
епа зТаг{ | \

5.7. Популярные алгоритмы


5.7.1. Генераторы случайных чисел
“Самый часто применяемый тип алгоритмов генерации псевдослучайных пос:
ледовательностей — линейные конгруэнтные генераторы, описываемые общим ре
куррентным соотношением: , |
Ти = (ат, + с) МО пт..

При правильно выбранных числах а и с эта последовательность возвращает все


числа от нуля до шт-1 псевдослучайным образом и ее периодичность сказывается
только на последовательностях порядка т. Такие генераторы очень легко реализу-
ются и работают быстро, но им присущи и некоторые недостатки: самый младший
‚ бит намного менее случаен, чем, например, самый старший, а также, если попытать-
ся использовать результаты работы этого генератора для заполнения К-мерного про-
странства, начиная с некоторого К, точки будут лежать на параллельных плоскостях.
Оба недостатка можно устранить, используя так называемое перемешивание дан-
ных: числа, получаемые при работе последовательности, не выводятся сразу, а по-
мещаются в случайно выбранную ячейку небольшой таблицы (8-16 чисел); число,
находившееся в этой ячейке раньше, возвращается как результат работы функции.
Если число а подобрано очень тщательно, ‘может оказаться, что число
с равно нулю. Так, классический стандартный генератор Льюиса, Гудмана и Мил-
лера использует а = 16 807`(75) при ш = 21-1, а генераторы Парка и Миллера
‚ используют а = 48 271 иа = 69 621 (при том же т). Любой из этих генераторов
можно легко применить в ассемблере для получения случайного 32-битного чис-
ла, достаточно всего двух команд — МОЕ и ПУ.
; Процедура гапд. : а Ве
; Возвращает в ЁАХ случайное. положительное 32=битное число. (от0. до 21-2)...
Популярные алгоритмы.
гапд ргос .пеаг
ризп едх
оу вах, диог@ руг зеед ; Считать последнее
‚ случайное число.
тезт вах, еах ‚ Проверить его, если это -1, .
33 тессв_зеед ; функция еще ни разу не
вызывалась и надо создать
начальное значение,
гапдот12е:
ти] мог руг гапд-а :; Умножить на число а.
93у бмог9 руг галат Взять остатокот деления на 21-1.
моу еах, едх
оу Смог рег зеед, еах ‚ Сохранить для следующих вызовов.

рор едх
ге

Тетсп_зеед;
ризп 9$
ризп 00401
рр 93 :
моу еах, диог@ ртг 93:006Сй. : Считать двойное. слов о.
из. ‘области
:. рор 95 : данных 8105 по адресу
‚ 0040:006б - текущее число
тр ПОГ гапдот12е : тактов таймера.

гапд_а 94 . 69621
гапд_м да 7ЕЕЕРЕРЕЙ
зеед `. 99 -1
гапд епдр
можно
Если период этого генератора (порядка 10°) окажется слишком мал,
ора с разными а и т, не имеющи ми общих делител ей,
скомбинировать два генерат
т, = 2 147 483 563 иа, - 40 692 сш, = 2 147 483 399.
например: а, = 400 014 с
Генератор, работающий по уравнению
". Ти = (а,1, +‘а,Г,) №0 м,

где ш — любое из т, и т, имеет период 2,3 х 108...


ся
Очевидный недостаток такого генератора —‘команды МОТ. и ОГУ относят
можно избавит ься, использ уя один из генерат оров
’ксамым медленным. От ОТУ
тся на
с ненулевым числом с и м, равным степени двойки. (тогда ПТУ п заменяе
13 849, ш = 216 илия = 1664 525, с =10139 04 223,
АМР т-1), например: а = 25 173, с =
основан ным на сдвигах или вычитан иях.
та = 232, однако проще перейти к методам,
конгру-
‚ Алгоритмы, основанные на вычитаниях, не так подробно изучены, как
и широко использ уются и, по-види мому, не
энтные, но из-за большой скорост
ое объясне ние алгдрит ма этого генерат ора
имеют заметных недостатков. Детальн
приведено
(а также алгоритмов: многих других генераторов случайных чисел)
в книге Кнута Д. Е. «Искусство программирован ия» (т.2).
ЕРТАНИИИИНИИИИИ !— Сложные приемы программирования
; Процедура згапа_1п1+.
Инициализирует кольцевой буфер. для генератора, использующего вычитания,
; Вход: ЕАХ - начальное значение, например из области
; Данных 810$, как в предыдущем примере.
згапа_1п11 ргос пеаг
ризН Ьх
рип 31
риузН едх
| тоу едх,1
; Засеять кольцевой буфер. _
Де Ьх, 216
90_0. оу мога рег аБЛех[Ьх],ах
$и6 вах, едх
хСпо еах, едх
‚46 ох,4
39е д0_0

_; Разогреть генератор.
мо ох, 216
до_1: ризв Ьх°
40_2: тоу $1, 6х
ада $1, 120
стр “ $1, 216
Бе ЗКр
$6 $1, 216
$К1р: (ед вах, Чмог9 руг ТаБ1ех[ох]
$и6 вах, мог рфг таБ1ех[з1]
тому Чмог@ рЕг таб1ех[ьх], еах
зи 5х,4
39е 90_2 | у =
рор Ьх
5и6 ох,4
99е 90_1

; Инициализировать индексы.
зи6 ах, ах
моу мог рфг 1пдехо,ах \
оу ах, 124
поу 1пдех1,ах

_ рор еах
рор $1
рор ох
гет |
эзгала_1п11 епдр

; Процедура згапа,
; Возвращает случайное 32-битное число в ЕАХ (от 0 до 23-1).
|
; Перед первым вызовом этой процедуры должна быть один раз вызвана процедура згапё 11.
згапа ргосе пеаг
ризй 5х |
ризй $1
Популярные алгоритмы о -
оу = Бх, мог ртг 1пдехо
моу $1, мог рфг 1п4дех1 ; Считать индексы.
оу еах, Чмог@ рфг ТаБех[Ьх]
5% —` вах, диогд руг таб]ех[$1] : Создать новое случайное число.
МОУ Фиог@ ртг та ]ех[31],
еах ; Сохранить его в кольцевом
буфере.
зи6 51,4 Уменьшить индексы,
2. Е1х..31 перенося их на конец буфера,
Р1хед_ $1: оу мог рфг 1пдех1,$1 если они выходят за начало.
зи Ьх,4
д Нх_Ьх
{1хед_вх: оу 1пдехб„Бх
рор $1
рор ох
гет

+1х_91: пом $1, 216 у


Этр зпогЕ Е1хед_$1
{1х_ВХ: моу Ьх, 216
тр зВогф Р1хед_ВХ

згапа епар
ТтабБ1ех ва 55 @ир (?) Кольцевой буфер случайных чисел,
1пдехо [А ? Индексы для кольцевого буфера. _
1пдех1 Ом ?

Часто необходимо получить всего один или несколько случайных битов, а ге-
нераторы, работающие с 32-битными числами, оказываются неэффективными.
В таком случае удобно применять алгоритмы, основанные на сдвигах:
; гапа8 * \
; Возвращает случайное 8-битное число в А,
; Переменная зееф должна быть инициализирована заранее,
; например из области‘ данных ВТ05, каков примере для конгруэнтного генератора.
гапа8 ргос пеаг., |

моу ах, могд рфг зеед


‚ мУ сх,8
пемб1{: моу Ьх,ах
апд Ьх, 00208
хог БН,61
с1с--
Эре $11
$1
ЗИ: — гСг ах,1
` 1оор пены
МОУ мог4 рфг зеед, ах
моу ав,0
гет
гапа8 епар
зеед. м `.1
ЕРЯМИНИИНИШИИ | — Сложные приемы программировани;
5.7.2. Сортировки
'Ещеодна часто встречающаяся задача при программировани
и - сортировка дан
ных. Все существующие алгоритмы сортировки можно
разделить на сортировку
перестановкой, в которых на каждом шаге алгоритма меняет
ся местами пара
чисел
сортировки выбором, в которых На каждом шаге выбира
ется наименьший элемент
и дописывается в отсортированный массив; и сортировки вставлением, в которых
элементы массива рассматривают последовательно
на подхо- и каждый вставляют
дящее место в отсортированном массиве. Самая простая
сортировка перестанов-
кой -— пузырьковая, в которой более легкие элементы «всплывают» к началу масси-
ва; сначала второй элемент сравнивается с первым
с ним и, если нужно, меняется
местами; затем третий элемент сравнивается со вторым
и только в том случае, ког-
даони переставляются, сравнивается с первым, и т. д. Этот алгоритм ‘также явля-
ется и самой медленной сортировкой - в худшем случае
для сортировки массива М
чисел потребуется №/2 сравнений и перестановок, а в
. %®
среднем - №/4.
; Процедура БчбБ1е_зог+.
; Сортирует массив слов методом пузырьковой сортировки.
; Вход: 09:01 = адрес массива
; ОХ = размер массива {в словах)
бибб1е_зогЕ . ргос пеаг
ризва
с19
стр дх, 1
Те зогт_ех1е ; Выйти, если сортировать нечего.
дес 9х - |
$6_100р1: тоу сх, ах . ; Установить длину цикла,
`_ ХОГ Ьх, 5х ; ВХ будет флагом обмена.
том $1, 91 ; 91 будет указателем на
; текущий элемент.
$п_100р2: 104$м ; Прочитать следующее слово.
стр ах, мога ртг [31]
Ъе по_змар ; Если элементы не в порядке,
хсНа ах, мог рёг [$1] ; поменять их местами
оу могд рег [31-2],ах
1пс ох ^ ‚ И установить флаг в 1.
по_5мар: 100р $п_100р2
стр Ьх, 0 ‚; Если сортировка не закончилась,
пе $п_100р1 ‚ перейти к следующему элементу.
зогЕ_ех1т:рора ‘
гет
руб е_зог+ епар у
Пузырьковая сортировка осуществляется так медленно потому
, что сравнения
выполняются лишь между соседними элементами. Чтобы получи
ть более быст-
рый метод сортировки перестановкой, следует выполнять
сравнение и переста-
новку элементов, отстоящих далеко друг от друга. На этой идее
основан алгоритм,
который называется быстрой сортировкой. Он работа
ет следующим образом:
делается предположение, что первый элемент является средни
м по отношению
Популярные алгоритмы 1. 1243
к остальным. На основе такого предположения все элементы разбиваются на две
группы- больше и меньше предполагаемого среднего. Затем обе группы отдель-
но сортируются таким же методом. В худшем случае быстрая сортировка массива
из М элементов требует № операций, но в среднем случае — только 21о,п срав-
нений и еще меньшее число перестановок.
; Процедура 9и1сК_зогт.
; Сортирует массив слов методом быстрой. сортировки.
; Вход: 05:ВХ - адрес массива
; ‚ ОХ = число элементов массива

Чи1сК-зоге ргос пеаг .


. бр 9х, 1 ; Если число ‘элементов 1 или 0,
.. ]]е 930гт_допе ; То. сортировка уже закончилась.
хог 91,91 | ; Индекс для просмотра сверху (0Т= 0).
ей $1,9 ; Индекс для просмотра снизу (531 = `х).
дес $1 ; $1 = 0Х-1, так как элементы
; нумеруются с нуля,
$81 ° 31,1 г И Умножить на 2, так как
; это массив слов, .
мо\ ах, мог ртг [6х]; АХ = элемент Х,, объявленный средним.
зТер_2: ; Просмотр массива снизу, пока. не встретится элемент,
; меньший или равный Х,.
стр мог рег [6х]( 31}, ах ; Сравнить Хх их
]е „зтер_3 ^^ о: Если Х больше, перейти
$46. $1,2 ; к следующему снизу элементу
тр зНогЕ з1ер_2 . ; и продолжить
. просмотр.
з1ер_3: ; Просмотр массива сверху, пока’не встретится элемент
; меньше Х, или оба просмотра. не придут в одну точку. |
сир 81. 91 ; Если просмотры встретились,
)е зтер_5 ; перейти к цшагу 5.
ада 91,2 | ; Иначе: перейти .
. | . ; к следующему сверху элементу.
стр мога ртг [6х][91],ах ; Если он меньше .Х,,
рр эзтер_3 ; ‘продолжить шаг 3.

зТер_4: ; 01.указывает на элемент, который не должен быть в верхней части,


; $1 указывает на ‘элемент, который не должен быть в нижней части.
; Поменять их местами.
моу сх, мог рег [5х][91] м =Х,
не сх, мога: рег. 6х][31] = Хх, Х = ЖЖ
моу мога рег [6х][91],сх ЖЖ = СХ
Зтр зПогЕ зтер_2
. / о
зТер_5: ; Просмотры встретились, Все ‘элементы в нижней группе больше Х,,
; все элементы в ‘верхней группе и текущий - меньше или равны Х..
'’’; Осталось поменять местами Х, и текущий элемент:
г хено ах. мога рег [6х][91] ; Ж=Х,, ХЕХ,
тому мог@ ртг [6х],ах УХ =А
ЕУЛИШШИНИИИНИИИ Сложные приемы программирования
‚; Теперь можно отсортировать каждую из полученных групп.
ризй ах
ризп 91
ризН Ьх ` `
поу ОХ, ЧЕ. ; Длина массива Х,.Х
ЗИг 9х, 1 ; в ОХ.*
‘са11 9и1сК_воге _ _; Сортировка.
рор ох
рор 91
рор 9х

а4а 6х, 91 ; Начало массива Х»,...Х,


а9а х, 2 ; в ВХ.
ИР 91,1 ; Длина массива Х‚...Х,
1пс 91 `
$иЬ 9х, 91° ‚ в 5х;
са11 Чи1СК_в0гЕ о - ; Сортировка.
9з0гЕ_допе: ге* -
Чи1СК_зогЕ епар

Помимо того, что быстрая сортировка — самый известный пример алгоритм


а,
использующего рекурсию, то есть вызывающего самого себя, это ещеи
самая бы-
страя из сортировок «на месте», то есть сортировка, применяющая только
ту па-
мять, в которой хранятся элементы сортируемого массива. Можно доказать
, что
сортировку нельзя выполнить быстрее, чем за поё,п операций, ни в
худшем, ни
в среднем случаях, и быстрая сортировка хорошими темпами приближается
к это-
му пределу в среднем случае. Сортировки, достигающие теоретического
предела,
тоже существуют — это сортировки турнирным выбором и сортировки
вставлени-
ем в сбалансированные деревья, но для их работы требуется резервирование
до-
полнительной памяти, так что например, работа со сбалансированными
деревья-
ми будет происходить медленно из-за дополнительных затрат на
поддержку
сложных структур данных в памяти.
Приведем в качестве примера самый простой вариант сортировки вставле
ни-
ем, использующей линейный поиск и затрачивающей порядка 12/2
операций. Ее
так же просто реализовать, как и пузырьковую сортировку, и она тоже
имеет воз-
МОЖностТЬ ВЫПОЛНЯТЬСЯ «на месте». Кроме того, из-за высокой оптимал
ьности
кода этой процедуры она может оказаться даже быстрее рассмотренной
нами «бы-
строй» сортировки на подходящих массивах.
|
‚ Процедура \1пеаг_зе1ест1оп_зоге.. _
; Сортирует массив слов методом сортировки линейным выбором,
; Вход: 05:51 (и ЕЗ:5Т) = адрес массива
; ОХ = число элементов ‘в. массиве
40_змар: 1еа 6х, мога ре [91-2] ИИ
моу ах, мога ртг [5х] ; Новое минимальное число.
Дес сх ; Если поиск минимального закончился,
Эсхи {а11 ‚ перейти к концу, °
Перехват прерываний 0
°1ю00р1: зсазм -_. ; Сравнить минимальное в АХ
. ; со следующим элементом массива.
За 90. змар .. ; Если найденный элемент еще меньше -
- ; выбрать его как минимальный.
]оор 100р1 |
; Продолжить сравнения \
‚ с’ минимальным элементом в АХ.
1а11: хсНд ах, мога р\г [$1-2] .; Обменять минимальный элемент
ту _ мюга рёг [5х], ах: с элементом, находящимся ^
‚; В начале массива.

11пеаг. зе1ест1оп_.зог{ ргос. пеаг ; Точка входа в процедуру.


мо Хх, $1 , : ВХ содержит адрес минимального элемента.
1093м | `_; Пусть. элемент, 'адрес
. которого был в ЗТ, минимальный,
оу 91,51. °’
; ОГ - адрес элемента, сравниваемого `
; с минимальным.
дес 9х ``; Надо проверить 0Х-1 элементов массива.
мо сх, ах : | `
33 100р1 ; Переход на проверку, если ОХ $ 1.
гет
1 1пеаг_зе1ес1оп_зог{ тер

5.8. Перехват прерываний


В архитектуре процессоров 80х86 предусмотрены особые случаи, когда про-
цессор прекращает (прерывает) выполнение текущей программы и немедленно
передает управление программе-обработчику, специально написанной для обра-
ботки подобной ситуации. Такие особые ситуации делятся на два типа: прерыва-
ния и исключения, в зависимости от того, вызвало ли эту ситуацию какое-нибудь
внешнее устройство или выполняемая процессором команда. Исключения делят-
ся далее на три типа; ошибки, ловушки и остановы, в зависимости от того, когда
по отношению к вызвавшей их. команде они происходят. Ошибки появляются пе- .
ред выполнением команды, поэтому обработчик такого исключения получит в ка-
честве адреса возврата адрес ошибочной команды (начиная с процессоров 80286).
Ловушки происходят сразу после выполнения команды, так что обработчик по-
лучает в качестве адреса возврата адрес следующей команды. И наконец, остано-
вы могут возникать в любой момент и вообще не. предусматривать средств воз-.
врата управлення в программу.
'Команда [МТ (а также ПУТО и МТЗ) используется в программах как раз для
того, чтобы вызывать обработчики прерываний (или исключений). Фактически
они являются исключениями ловушки, поскольку адрес возврата, который пере-
дается обработчику, указывает на следующую команду, но так как эти команды
были введены до разделения особых ситуаций на прерывания и исключения, их
‚практически всегда называют командами, вызова прерываний. Ввиду того, что
обработчики прерываний и исключений в ОО$ обычно не различают механизм
вызова, с помощью команды ПМТ можно передавать управление как на обработ-
чики прерываний, так и исключений. |
ЕЗИИИИШИИ Сложные приемы программировани
Как показано в главе 4, программные прерывания, то есть передач
а управле
ния при помощи команды ПМТ, являются основным средством вызова
‘процеду
205 и ВГО$5, потому что в отличие от вызова через команду СА. здесь
ненужн
знать адреса вызываемой процедуры - достаточно только номера. С другой
сторс
ны интерфейса рассмотрим, как строится обработчик программного прерыва
ни;
5.8.1. Обработчики прерываний
Когда в реальном режиме выполняется команда ПМТ, управление передает
с.
по адресу, который считывается из специального массива, таблицы векторо
в пре
рываний, начинающегося в памяти по адресу 00005:00008. Каждый
элемент тако
го массива представляет собой дальний адрес обработчика прерыва
ния в форма
те сегмент:смещение или 4 нулевых байта, если обработчик не установ
лен
Команда ПМТ помещает в стек регистр флагов и дальний адрес возврата
, поэтом)
чтобы завершить обработчик, надо выполнить команды рор+ и ге
или одну ко
манду 1теё, которая в реальном режиме полностью им аналогична.
#

; Пример обработчика программного прерывания.


1п_папа?ег ргос Раг
оу ах,0
1гет
111, ап] ег.“ - епар

После того как обработчик написан, следующий шаг — привязка его к ВЫбран-
‚ ному номеру прерывания. Это можно сделать, прямо записав его адрес в таблицу
векторов прерываний, например так:
ризв 0 ; Сегментный адрес таблицы векторов прерываний -
рор е5 : в Е. |
рузВР ; Поместить регистр флагов в стек.
с]1 ; Запретить прерывания (чтобы не произошло
‚ аппаратного прерывания между следующими командами,
;’ обработчик которого теоретически может вызвать Т№Т 87Н в тот момент,
‚ когда смещение уже будет записано, а сегментный адрес еще
нет,
‚ что приведет к. передаче управления в неопределенную область памяти).
; Поместить дальний адрес обработчика 1п1_пала]ег
; В таблицу векторов ‘прерываний, в элемент номер 871
; (одно из. неиспользуемых прерываний).
мо мог рег. ез:[871*4], оЁРзеф 1пт_папа1ег
оу мога рег ез:[871*4+2], зе9 1пе_Вап ег
рорЕ ; Восстановить исходное значение. флага ТЕ.
Теперь команда ГМТ 87 будет вызывать наш обработчик, то есть приводи
ть
к записи 0 в регистр АХ.
Перед завершением работы программа должна восстанавливать все старые
обработчики прерываний, даже если это были неиспользуемые прерывания типа
87Ь — автор какой-нибудь другой программы мог подумать точно так же.
Для это-
го надо перед предыдущим фрагментом кода сохранить адрес старого обработчи-
ка, так что полный набор действий для программы, перехватывающей прерыва-
ние 87, будет выглядеть следующим образом:
`Перехват прерываний. ^_ 227
пес ризн = :0
ги; рор. . ез `. `.
; копировать адрес предыдущего, т бработчика В переменную. 019_ напалег.
г. Мю —. вах, диога рег. е$:[878*4]
воу @иога руг,.014_Напа1ег,еах
; установить наш обработчик. '
ризВЕ а 5
_ С]11 .
_ поу \огЧ рег ез:[871*4], оЁРзе{ 11%. Напатег
- У . мОГасртг ез:[87Н*4+2], 389 1пе пап ег
" роре — `
‚ Телб’ , программы.
1...
; Восстановить ‘предыдущий обработчик.
‚г:. ризВ 0 : .
рор ез
° ризВТ.
с11
моу еах, могд ртг о19_Папфег
тому могд рфг ез:[871*4], еах
рорР р

‹ Хотя прямое изменение таблицы векторов прерываний и кажется достаточно.


удобным, все-таки это не лучший подход к установке обработчика прерывания,
и пользоваться им следует только в исключительных случаях, например внутри
обработчиков прерываний. Для обычных программ РО$ предоставляет две сис-
темные функции: 258 и 358 - установить и считать адрес обработчика прерыва-
ния, которые и рекомендуются к использованию в обычных условиях:
; Скопировать адрес предыдущего обработчика в переменную 034. Вапд] ег.
том ах, 35878 ; АН= 351, АЁ = номер прерывания.
пи 218 _ | ; Функция 00$: считать
: ; адрес обработчика прерывания.
тоу мог4 ртг 014 _Напег, 5х ; Возвратить смещение в ВХ
по\у мог рег о18_Пап9]ег+2;ез ; и сегментный адрес в Е$.
| ; Установить наш обработчик.
моу ах, 25871. ; АН = 251, АЁ = номер прерывания.
том 9х, зе9 1п{ вап ег ; Сегментный адрес -
оу 93, 9х ; в 05, ° р
тоу ах, оРЕзет 111 папа1ег ; смещение в ОХ.
17 211. . ; Функция 00$: установить
; обработчик в тело программы
. ; (не забывайте,, что ЕЗ
` . , ° у; Изменился после вызова функции 351!)
°[..}
; Вобстановить предыдущий обработчик :
г 198. 9х,014_ПапаТег- : Сегментный адрес в’0$`и смещение в ОХ.
"ЮУ ах, 25871 ^. ; АН = 251, АЁ = номер ‘прерывания.
1% 218 ; Установить обработчик.
МЕ! Сложные приемы программирования
Обычно обработчики прерываний применяют с целью обработки прерывания
от внешних устройств илис целью обслуживания запросов других программ. Эти
возможности рассмотрены далее, а здесь приведен пример использования обыч-
ного обработчика прерывания (или, в данном случае, исключения ошибки) для
того, чтобы быстро найти.минимум и максимум в большом массиве данных.
‚ Процедура м1птах..
; Находит минимальное и максимальное значения в массиве слов.
; Вход: 0$:ВХ = адрес. начала массива
; СХ = число элементов в массиве
; Выход: |
; АХ = максимальный элемент
; ВХ = минимальный элемент
м1птах ргос пеаг
‚ Установить наш обработчик прерывания 5.
ризй 0
рор ез
по _^ вах, мог. рёг ез:[5*+4]
тоу Чмога рфг 019_1п15, еах
пом мога рЕг ез:[5*4],оРРзет 1п15_Напд]ег
мочу мог@ рЕг е$:[5*4]+2,с5
; Инициализировать минимум и. максимум первым элементом массива.
по\ ах, мога рег [6х] |
90у могд р&г 1омег_боупа,ах
мо мога ртг , иррег_Боипа,ах
; Обработать массив. |
. №0У 91,2 : и ; Начать со второго элемента.
Бспеск:
у
тому ах, мога рфг [6х9] ; Считать элемент в АХ.
Боипа ах, Боип4$ т ; Команда ВОУМО вызывает
| ; исключение - ошибку 5, |
‚ если АХ не находится в пределах
. _; 1омег_боипа/иррег_Боипа.
а99 91,2 ° ; Следующий элемент,
1оор Ьспеск ‚; Цикл на все элементы.
; Восстановить предыдущий обработчик.
тоу . еах,0могЯ рфг 019 115
тоу @мог@ рег ез:[5*4],
еах
; Вернуть результаты.
му ах, мога руг ‘иррег_Боипа
му Бх, мога рфг 1омег_воипа
‚ гет
Боипаз:
1омег_Боипа [6 2 |
иррег_Боила — 9%? р
014 _1п15 94 $ оо
; Обработчик ТМТ 5 для процедту уры
птах.
; Сравнить АХ со значениями уррег_Боипд и 10очег_Боцп@ и. копировать
; АХ в один из них. Обработчик не обрабатывает. конфликт между
Перехват прерываний ‘ - М оооиовлУлес
; исключениам `ВОН и`программным прерыванием распечатки: экрана ТАТ: 5.
; Нажатие. клавиши РгЕбсг в момент. работы процедуры тфотах. приведет”
; К ошибке. Чтобы это: исправить,. можно, например, проверят `бай“..
; на. который. указывает адрес возврата, если это ОСОВ.
; (код команды ТМТ), то обработчик. был вызван как? ИТ -5,
1115 _папд1ег ргос Раг
стр ах, мог9 рёг 10мег_50ип9. ; Сравнить АХ с нижней границей.
д. 115_1омег _; Если. не меньше -
‚ это было нарушение
МОУ мога ртг иррег_Боипд,ах ; верхней границы.
1 ге , /
115 _1ощег: у и ко
моу мога рег 1омег_Боипд, ах; Иначе это было’ нарушение
1гет , ; нижней границы.
1115_Лап]ег = епдр
1 пмах епар

Разумеется, вызов исключения при ошибке занимает много времени, но, если
массив достаточно большой и неупорядоченный, значительная часть проверок
будет происходить без ошибок и`быстро.
При помощи собственных обработчиков исключений можно справиться и с дру-
гими особыми ситуациями, например обрабатывать деление на ноль и остальные
исключения, которые возникают в программе. В реальном режиме есть вероят-
ность столкнуться всего с шестью исключениями: ‘
о#0Е (деление на ноль) — ПМТ 0 — ошибка, появляющаяся при переполнении
и делении на ноль. Как для любой ошибки, адрес возврата указывает на оши-
бочную команду;
О #ОВ (прерывание трассировки) —1МЕ 1- — ловушка, возникающая после вы-
полнения каждой команды, если флаг ТЕ установлен в 1. Используется от-
ладчиками, действующими в реальном режиме;
О #ОЕ (переполнение)— ПМТ 4 - ловушка, возникающая после выполнения
команды ПМТО, если флаг ОЕ установлен;
© #ВК (переполнение при ВООМО)-— ПМТ 5 - уже рассмотренная нами ошиб-
ка, которая происходит при выполнении команды ВОПМО;
о #00 (недопустимая команда). [МТ 6 - ошибка, возникающая при попытке
выполнить команду, отсутствующую на данном процессоре;
о #ММ (сопроцессор отсутствует) — ПМТ7 — ошибка, появляющаяся при по-
пытке выполнить команду ЕРО, если ЕРО отсутствует.

5.8.2. Прерывания от внешних устройств


Прерывания от внешних устройств, или аппаратные прерывания, -— это то, что
понимается под термином «прерывание». Внешние устройства (клавиатура, диско-
вод, таймер, звуковая карта и т. д.) подают сигнал, по которому процессор преры-
вает выполнение программы и передает управление на обработчик прерывания.
Всего на персональных компьютерах используется 15 аппаратных прерываний,
хотя теоретически возможности архитектуры позволяют довести их число до 64.
Сложные приемы программирования
| .

Рассмотрим их кратко в порядке убывания приоритетов («прерывание имеет


более высокий приоритет» означает, что, пока не завершился его обработчик, пре-
рывания с низкими приоритетами будут ждать своей очерёди):
01800 (ТМТ 8) - прерывание системного таймера, вызывается 18,2 раза в се-
кунду. Стандартный обработчик этого прерывания вызывает ПМТ 1СВЬ при
каждом вызове, так что, если программе необходимо только регулярно полу-
чать управление, а не перепрограммировать таймер, рекомендуется исполь-
зовать прерывание 1СВ;
1591 (МТ 9) - прерывание клавиатуры, вызывается при каждом нажатии
и отпускании клавиши на клавиатуре. Стандартный обработчик этого преры-
вания выполняет довольно много функций, начиная с перезагрузки по СЫ]1-
АЁ-Ое| и заканчивая помещением кода клавиши в буфер клавиатуры ВТО$;
ОВО? - к этому входу на первом контроллере прерываний подключены ап-
паратные прерывания [КО8— [КО15, но многие ВТО$ перенаправляют 1809
на ПМТ 0АБ;
01808 (ПМТ 701) - прерывание часов реального времени, вызывается часами
реального времени при срабатывании будильника и если они установлены
на генерацию периодического прерывания (в последнем случае вов вызы-
вается 1024 раза в секунду);
01609 (ПМТ 0АВ или ПМТ 71Ъ)- прерывание обратного хода луча, вызывается
некоторыми видеоадаптерами при обратном ходе луча. Часто используется
дополнительными устройствами (например, звуковыми картами, $С$]-адап-
терами ит. д.);
018010 (ПМТ 724) - используется дополнительными устройствами;
[К О11 (ТМТ 73) - используется дополнительными устройствами;
015012 (ТМТ 748) — мышь на системах Р5, используется дополнительными
устройствами;
018013 (ПМТ 028 или ПМТ 751) — ошибка математического сопроцессора. По
умолчанию это прерывание отключено как на ЕРУ, так и на контроллере
прерываний;
о[.О14 (ПМТ 761)- прерывание первого ТОЕ-контроллера «операция завер-
шена»;
918015 (МТ 771)- прерывание второго ГОЕ-“контроллера «операция завер-
шена»;
01803 (ТМТ 0ВЬ) - прерывание последовательного порта СОМ2, вызывает-
ся, если порт СОМ? получил данные;
[804 (ПМТ 0СВ)— прерывание последовательного порта сомь вызывается,
- если порт СОМ1 получил данные;
01305 (ГУТ 0ОВ) -— прерывание ТГ.РТ2, используется дополнительными уст-
ройствами;
о1В.Об (ПМТ 0ЕВ) - прерывание дисковода «операция завершена»;
01307 (МТ 0ЕВ) - прерывание ГРТ1, используется дополнительными уст-
ройствами.
Перемват прерываний _
Самые полезные для: программ аппаратные прерывания - прерывания систем-
ного таймера и клавиатуры. Так как стандартные обработчики. этих прерываний
выполняют множество функций, от которых зависит работа системы, их нельзя
заменять полностью, как мы поступали с обработчиком 1МТ 5. Необходимо вы-
звать предыдущий обработчик, передав ему управление следующим образом
(если его адрес сохранен в переменной о14_Пап ег - см. примеры ранее):
рузНЕ ..
са11 014_папа1ег

Данные команды выполняют действие, аналогичное команде ПМТ: (сохранить


флаги в стеке и передать управление подобно команде са), поэтому;когда обра-
ботчик завершится командой ТВЕТ, управление вернется в нашу программу. Так
удобно вызывать предыдущий обработчик в начале собственного. Другой способ —
простая ‘команда тр:
тр 6$:0149_папд]ег

приводит к тбму, что по выполнении команды ТВЕТ старым обработчиком управле-


ние сразу же перейдет к прерванной программе. Этот способ применяют, если нужно,
чтобы сначала отработал новый обработчик, а потом он передал управление старому.
На следующем примере посмотрим, как осуществляется перехват прерывания
от таймера:
; Чмтег.азм
; Демонстрация перехвата прерывания системного таймера: вывод ‘текущего. времени
; в Левом углу экрана.

.тоде] 11пу
. соде ' :
‚ 186 : ` р Аля ‘разпа/рора и сдвигов.
0гд 1008
ЗТагт. . ргос - пеаг
; Сохранить адрес предыдущего ,обработчика прерывания Сп. |
ЮУ ах, 351С8 ; = 351, АЁ = номер прерывания.
1щ 218 ; ия 005: определить’ адрес обработчика
‘оу мог рег 019 Ти 1СВ,5х ; прерывания’
тоу мога руг 014_1п14С1+2,ез ; (возвращается в ЕЗ:ВХ).
‚ Установить наш обработчик. , вв
А ах, 251С8 ‚; АН = 251, АЁ = номер прерывания.
оу Чх, оРРвет. 1пЕ1Сп. Наполег ; 05:0Х - адрес’ обработчика.
111 2 .- ; Установить обработчик прерывания 1СН.

‚ Здесь размещается собственно: программа, например вызов” соттапа. сот.


поу ^ ап, 1 .
Ли ‚211. : Ожидание нажатия -на любую клавишу.
; Конец программы.

; Восстановить предыдущий обработчик прерывания 161.


_тоу ах, 251С1 р . ; АН =.265,,. АС: = номер прерывания.
моу Чх, мог рфг 019_1п11С1+2
Ш! Сложные приемы программировань
тоу 93, 9х . . ° :
моу 9х, мога’ рег с5:019_1пЕ1СВ ; 0$:0Х - адрес обработчика.
1 218 |
тет

019 Ти 1Сн 94 - ? ; Здесь хранится адрес предыдущего обработчика.


‚ Зфагт_ро$1110п 9м 0 ; Позиция на экране, в которую выводится `
; Текущее время.
ЗТаге епар
; Обработчик для прерывания 168. о
‚; Выводит текущее время в позицию зТаге_роз11ол на экране (только в текстовом режиме
111С1_Валд]ег ргос Таг
ризва ; Обработчик аппаратного’ прерывания
ризН е5 ‚ должен сохранять ВСЕ регистры.
ризИ 48
‚ ризй 68 ; На входе в обработчик известно только
рор 4$ : ; значение. регистра 55.
- МОУ ав, 028 ; Функция 028 прерывания 1АВ:.
17 ТАН ‚ Чтение времени из НТС.
‚с ехИ_папд]ег ; Если часы заняты - в. другой раз.

; АЁ = час в- ВСЬ-формате.
са]1 Ьсагазс , ‚; Преобразовать в АЗСТТ.
поу руте рфг оитрие, 11пе[2], ай ; Поместить их в
тому Буте руг’ оифри*_11пе[4],а1 ; строку оитрит_11те.
“< моу а], с1 ; СЁ = минута в ВСО-формате.
са11 5с92азс ”
оу Буте рЕг оытрит_11пе[10],ав
тмоу бусе рёг оифриф_14пе[
12], а1
пу . а, бп у ; ОН = секунда в ВСО-формате.
са11 Ьс42азс о . `
моу Буте руг оифрие_11те[
16], ай
моу Буте руг оиррит_11пеЁ18],а1
пом. _ сх, оцери*_Чпе_1 | ; Число байтов
в строке.-.в СХ.
ризН 088005 | .
рор е5 ; Адрес в видеопамяти
оу 91, мог ртг зТаге_роз11оп ; В Е5:0Г:.: .
по\ $1, ОРРзет оифрит.11пе ; Адрес строки в 05:51.
с19 | р
гер моузЬ ° ; Скопировать строку.
ех1т_Папа]ег: . | | ОВ
рор 95 (о | ; Восстановить все регистры.
рор ез
рора
.:
Эир 6$5:014_1п 108 ; Передать управление’ предыдущему обработчику.
‚ Процедура 6са2азс. р х
; Преобразует старшую цифру упакованного ВСО-числаиз АЁ в АЗСТТ-Символ,
во НН м и
Перехват прерываний
; который будет помещен в АН, а младшую цифру - в АВС символ в АГ.
Ьс92азс ргос пеаг
_ пом ав, а1
апа а}, ОРВ | - ° ; Оставить младшие 4 бита в А.
ЭГ ап, 4 ` | \% Сдвинуть старшие 4 бита в АН.
ог ах, 30301. . ; Преобразовать в АЗС1Т-символы.
гет |
осаразс епбр |
; Строка “ 00В 00:00” с атрибутом 1Ей (белый на: синем) после каждого символа.
оцфрие_11пе 96 *” *УТЕА, '0’, ЛР, '0’, ЛЕВ, " В’, ЛЕВ
. 95 ЛЕВ, 0’, ЛР, 0’, ЛЕВ, *:', ЕВ
[9 '0’, ТР, *0’, 12,’ ',1ЕВ

оифри*_11пе_1 еди $-оцфрит_11пе

1пЕ1СН_папа1ег епдр -

епа ` ЗТаге

Если в этом примере вместо ожидания нажатия на клавишу поместить какую-


нибудь программу, работающую в текстовом режиме, например ипузВе! из разде-
ла 4.10, она выполнится как обычно, но в правом верхнем углу будет постоянно
показываться текущее время, то есть такая программа будет осуществлять два
действия одновременно. Именно для этого и применяется механизм аппаратных
прерываний— они позволяют процессору выполнять одну программу, в то время
как отдельные программы следят за временем, считывают символы из клавиату-
ры и помещают их в буфер, получают и передают данные через последовательные
и параллельные порты и даже обеспечивают многозадачность, переключая про-
цессор между разными задачами по прерыванию системного таймера:
Разумеется, обработка прерываний не должна занимать много времени: если
прерывание происходит достаточно часто (например, прерывание последователь-
ного порта может происходить 28 800 раз в секунду), его обработчик обязательно
должен выполняться за более короткое время. Если, например, обработчик пре-
рывания таймера будет выполняться 1/32,4 секунды; то есть половину времени
между прерываниями, вся система станет работать в два раза медленнее. А если
еще одна программа с таким же ‘долгим обработчиком `перехватит это прерыва-
ние, система остановится совсем: Именно поэтому обработчики прерываний при-
нято писать исключительно на ассемблере.

5.8.3. Повторная входимость


Пусть у нас есть собственный обработчик программного прерывания, который
вызывают обработчики двух аппаратных прерываний, и пусть эти аппаратные
прерывания произошли сразу одно за другим. В этом случае может получиться
так, что второе аппаратное прерывание осуществится тогда, когда еще не закон-
чится выполнение нашего программного обработчика. В большинстве случаев это
не приведет ни к каким проблемам, но, если обработчик обращается к каким-либо
переменным в памяти, могут произойти редкие, невоспроизводимые сбои в его ра-
боте. Например, пусть в обработчике есть некоторая переменная соитиег, исполь-
зуемая как счетчик, производящий подсчет от 0 до 99:
И Сложные приемы программировани;
оу а1, Буте ртг, соиптег ; Считать счетчик в АГ.
стр а1, 100 ; Проверить его на переполнение.
Зь соиптегок . ; Если счетчик достиг. 100,
‚ >>> здесь произошло второе прерывание <<<
зи6 а1, 100 ; вычесть `100 _
поу руте. рфг соиптег,а] ; И сохранить счетчик.
соиптег_ок:

Если значение счетчика было, например, 102, а второе прерывание произош


лс
после проверки, но до вычитания 100, второй вызов обработ
чика получит то же
значение 102`и уменьшит его на 100. Затем управление вернется
, и следующая
команда зцЬ а|,100 еще раз уменьшит АТ, на 100 и запишет получен
ное число - 98
на место. Если затем по значению счетчика вычисляется что-нибудь
вроде адреса
в памяти для записи, вполне возможно, что произойдет ошибка. О таком
обработ-
чике прерывания говорят, что он не является повторно входимы
м. |
Чтобы защитить подобные критические участки кода, следуёт временн
о зап-
ретить прерывания, например так: о
11 . | ‚ Запретить прерывания.
ом а1, Буфе руг соипфег°
° стр а1, 100
. соуптег_ок
зи6 а1, 100 . ОИ
ПО Буте рёг соиптег,а1
соиптег_ ок:
511 | ; Разрешить прерывания.
Следует помнить, что, пока прерывания запрещены, система/не отслежи
вает
_ изменения часов, не получает данных с клавиатуры, поэтому прерыва
ния надо
обязательно, при первой возможности, разрешать. Всегда лучше пересмо
треть
используемый алгоритм и, например, хранить локальные переменные
в стеке или
применить специально разработанную команду СМРХСНС, которая
позволяет
одновременно провести сравнение и запись в глобальную переменную.
К сожалению, в М$ РО$ самый важный обработчик прерываний
в системе —
обработчик [МТ 21 - не является повторно входимым. В отличие
от прерыва-
ний ВТО$5, обработчики которых используют стек прерванной програм
мы, обра-
ботчик системных функций РО$ записывает в $5:5Р адрес дна одного
из трех
внутренних стеков РОЗ. Если функция была прервана аппаратным
прерывани-
ем, обработчик которого вызвал другую функцию 0О$, она будет
пользоваться
тем же стеком, затирая все, что туда поместила прерванная функци
я: Когда
Управление вернется в прерванную функцию, в стеке окажется мусор
и произойдет
ошибка. Лучший выход — вообще не использовать прерывания РОЗ
из обработ-
чиков аппаратных прерываний, но если это действительно нужно, то
принять не-
обходимые меры. предосторожности. Если прерывание произошло’в тот
момент,
когда не выполнялось никаких системных функций 00$, ими можно
безбоязнен- _
но пользоваться. Чтобы определить, занята 2О$ или нет, надо
‘сначала, де уста-
новки собственных обработчиков, выяснить адрес флага занятости
РО$.
Перехват прерываний:
Функция 2О5 341: Определить адрес: флага занятости 205 ..
Вход: АН= 34Ь
Выход: Е$:ВХ= адрес однобайтного флага занятости РО$
ЕЗВХ - 1 - адрес однобайтного флага критической ошибки 2О$
Теперь обработчик прерывания может проверять состояние этих флагов и, если
оба флага равны нулю, разрешается свободно пользоваться функциями РО$.
Если. флаг критической ошибки не ноль, никакими.функциями 2О$ пользо-
ваться нельзя. Если. флаг занятости РО$ не ноль, можно пользоваться только
функциями 01В - ОСЬ, а чтобы воспользоваться какой-нибудь другой функцией,
придется отложить действия до тех пор, пока РО$ не освободится. Чтобы это.
выполнить, следует сохранить номер функции и параметры в каких-нибудь пере-
менных.в памяти и установить обработчик прерывания 8Ь или 1СЬ. Этот обра-.
ботчик будет при каждом вызове проверять флаги занятости и, если РО$ освобо-
дилась, вызовет функцию с номером и параметрами, оставленными в переменных
в памяти. Кроме того, участок программы после проверки флага занятости - кри-
тический, и прерывания должны быть запрещены. Не все функции ОО$ возвра- .
щаются быстро — функция чтения символа с клавиатуры может оставаться в та-
ком состоянии минуты, часы или даже дни, пока пользователь не вернется и не
нажмет на какую-нибудь клавишу, и все это время флаг занятости 2О$ будет
установлен в 1. В 2О$ предусмотрена и такая ситуация, Все функции ввода‘сим-
волов с ожиданием вызывают ГУТ 28} в том же цикле, в котором они ‘опрашива-
ют клавиатуру, так что, если установить обработчик прерывания 28}, из него мож-
но вызывать все функции ОО$, кроме 01 - ОСЬ.
Пример вызова ОО$ из обработчика прерывания от внешнего устройства рас-
смотрен чуть ниже, в резидентных программах. А сейЧас следует заметить, что
функции ВТЗ, одну из которых мы вызывали в нашем примере Чтег.азт, также
часто оказываются не повторно входимыми. В частности, этим отличаются обра-
ботчики программных прерываний 5, 8, 9, ОВЬ, ОСЬ, ОБЬ, ОЕБ, 10, 13}, 14, 16Ъ,
175. Поскольку ВТО$ не предоставляет какого-либо: флага занятости, придется
создать его самим: в
110_пап1ег — ргос таг на | ВВ Е а
1пс сз: Буфе рег: ‘1п110-Бизу ; Увеличить: флаг занятости.
ризйЕ ; Передать управление старому
. и ; обработчику. МТ. 101,
са 65: мог. рег. 019_17110 ; эмулируя команду МТ.
"дес сз: Буфе рег .1п{10.Бузу `; Уменьшить флаг занятости.
1гет | ..
1110_Бизу 9 о _ ий
11110_пайа1ег епдр
Теперь обработчики аппаратных прерываний могут пользоваться командой’
ПМТ 10В, если флаг занятости ш10_Бизу равен нулю, и это. не приведет к ошиб-
кам, если не найдется чужой обработчик прерывания, который тоже станет обра-.
щаться к ПМТ 10 и не будет ничего знать о нашем флаге.занятости.
РЕЗИШШИШИНИИШИИ!! — Сложные приемы программировани
5.9. Резидентные программы |
Программы, остающиеся в памяти после того, как управл
ение возвращает‹
в ОО$5, называются резидентными. Превратить програ
мму в резидентную просто
достаточно вызвать специальную системную функц
ию ОО$5.
Функция 0О5 311: Оставить программу резидентной
Вход: —АН = 31В `
АТ, = код возврата ,
ОХ - размер резидента в 16-байтных параграфах (больше
06}), счита
’ отначала Р5Р
Кроме того, существует и иногда используется предыдущая
версия этой фун
кЦИи - прерывание 278:
1№Т 27: Оставить программу резидентной
Вход: АН=27Ь
- ОХ = адрес последнего байта программы (считая от начала
РБР) + 1
Эта функция -не может оставлять резидентными программы
размером больш
64 Кб, но многие программы, написанные на ассемблере, соотве
тствуют этому усло
вию. Так как резидентные программы уменьшают объем основн
ой памяти, их все
гда пишут на ассемблере и оптимизируют для достижения минима
льного размера
`Никогда не известно, по каким адресам в памяти оказываются
загруженные
в разное время резидентные программы, поэтому единственным
несложным спо.
собом получения управления является механизм программных
и аппаратных пре:
рываний. Принято разделять резидентные программы на активн
ые и пассивные
в зависимости от того, перехватывают ли они прерывания от
внешних устройсте
или получают управление, только если программа специа
льно вызовет команду
ПМТ с нужным номером прерывания и параметрами.

_ 5.9.1. Пассивная резидентная программа


В качестве первой резидентной программы рассмотрим
именно пассивный
резидент, который будет активизироваться при попытке
программ вызывать
ПМТ 21В и запрещать удаление файлов с указанного
диска.
; Т3г. азт >. .
; Пример пассивной резидентной программы.
; Запрещает удаление файлов на диске, .указанном в командной строке, всем
‚ программам, использующим средства 00$.
.104е1 1пу
.соде
огд 2Св . ;
епузед [6 ? ; Сегментный адрес копии окружения 00$.
0г9 8оН..
ста_1еп ЧБ ? ; Длина командной строки.
ста_11пе [619] ? ; Начало командной строки.
0гд 100н | | ; СОМ-программа.
эфагт:
_ 029 1пЕ21Н:
Зтр зНогт 11ате : Эта команда занимает 2 байта, так что
м 0 ; вместе с ними получим
$, 019 1пе21в 99 7. =
772 М_Напд ег ‚ ргос Таг '; Обработчик прерывания 211.
ризНЕ ;р Сохранить флаги.
стр ап, 411 , Если вызвали функцию 411 (удалить
3е Ро ‚,; файл) |
стр ах, 71411 ;, или 71418 (удалить. файл с длинным. именем),
]е Рп4 , начать наш обработчик.
зар Вог пот_ 0418 , Иначе - передать управление
предыдущему обработчику.
Гп41н:
ризН ах , Сохранить модифицируемые
ризй Ьх регистры.
оу ьх,ах
стр Буте рёг 93:[6х+1],':’_ Если второй символ АЗСТ2-строки,
переданной ТМТ 211, двоеточие - первый
символ должен быть’ именем диска.
Ри1]_зрес
ал, 198. . ; Иначе -.
218 ;, ‘функция 005 191- определить текущий диск.
а], ’А’. Преобразовать ‘номер диска
к заглавной букве.
.- М зВоге сотраге ; Перейти к сравнению.
Ри] _зрес:
тоу а1,Буте руг [6х] АС = имя диска из АЗСТР-строки.
апа а1, 110111115 Преобразовать к заглавной букве.
сотраге:
стр а?,Буте рег. с5:ста_11е[1] ; Если диски
]е ассезз_4еп1еа ‚ совпадают - запретить доступ.
рор Ьх | Иначе`- восстановить
рор ах регистры
пот_Тп41В:
рорт и флаги
тр нога рег с$:014_11%211 и передать управление
; предыдущему обработчику ТТ 218.
ассезз_деп1ед;
_ рор Ьх ; Восстановить регистры.
рор ах.
рорР
ризй Бр
мо\у

ог ога рег `[6р+6},1 : Установить флаг’ переноса


(бит. 0) в регистре флагов,
; который поместила команда Т№Т в стек
' перед адресом возврата.
рор Бр

9 Зак. 459
_ ИИ Сложные приемы программирован:
_ МОУ. ах, 5. а ; Возвратить код ошибки “доступ:; запреще,
„‚ 1гет Вернуться в. программу.
111211 _Вапа]ег.. епар
111 1а117е ргос пеаг
| стр Бубе ртг смд_1еп,3 ; Проверить’ размер командной строки
пе пот _1п51а11 ; (должно быть 3 - пробел, диск, двоеточие
`: стр Буте руг ста_11пе[2],':’; Проверить третий
символ |
Зпе поТ_1п$1а11 | ; командной строки (должно быть двоеточие
МОУ а1, усе руг ста_11пе[1]
апа а1, 110111115 ; Преобразовать второй
символ к заглавной букве.
стр `а1, ‘А’ 7’ : Проверить, что это не
76 по 1п$1а11 Г. м меньше “А” и не больше
стр . ат, '7' ;
"7"...
.]а. .. по{_1п31а11 о Если хоть одно ‘из этих условий
не выполняется - выдать информацию
© программе и выйти. И:
Иначе .- начать процедуру инициализации.
ах, З521Н | ; АН = 351, АЁ = номер прерывания.
218 ° у ; Получить адрес обработчика ТТ: 211
мог рег 0191121,6х `; и поместить его`в 014 11218.
мога ртг 014 _1п121Н+2,ез

`ах, 2521! . АН = 251, АЁ = номер прерывания.


‘х, оЕРзеЕ 1пЕ211_папа1ег 05:0Х - адрес нашего обработчика.
211 | ; Установить обработчик ТМТ 211
ав, 498 _ _; АН = 491.
е$, мога рфг епузед ; Еб = сегментный адрес блока с нашей
копией окружения 00$.
в о Освободить память из-под окружения.
9х, оРРзет 1и1а112е ; „ОХ - адрес первого байта за концом
резидентной части программы.
2тъ `; Завершить выполнение, оставшись
резидентом.
пОТ_1п$1а1]:
ей ан, 9. ; АН = 091
тоу 9х, оРРзет изаде ^ ; 0$:0Х = адрес строки с информациеоб
й
использовании программы.
17 211 ; Вывод строки на экран.
гет
Нормальное завершение программы.
; Текст, который выдает программа при запуске с неправильной командн
ой строкой:
изаде [6] "Использование: Тэг. сом 0:^”, ООН, ОАВ
[6 “Запрещает удаление на диске 0:”, ООВ, ОАВ
45 "$"
11 1а112е епар
епа ЗТагт
_Резидентные программы ПАО ООО ОИНЕССЯ
Если запустить эту программу с командной строкой П:, никакой файл на дис-
ке О нельзя будет удалить командой Ое|, средствами оболочек типа Мо{оп
‚Сотталпаег и большинством программ для ОО$. Действие этого запрета, однако,
не будет распространяться на оболочку Еаг, которая использует системные функ--
ции УЛп4до\з АРТ, и на программы типа О15К ЕЧКог, обращающиеся с дисками при
помощи функций ВТО$ (ПУТ 13В). Несмотря на то что мы освободили память,
занимаемую окружением РОЗ (а это могло быть лишних 512 или даже 1024 бай-
та), наша программа все равно занимает в памяти 352 байта потому, что первые
256 байт отводятся для блока РР. Существует возможность оставить программу
резидентной без РУР— для этого инсталляционная часть программы должна ско-
пировать резидентную часть с помощью, например, тоуз в начало РР. Но при
этом возникает сразу несколько проблем: во-первых, команда ТМТ 27Ь, так же как
и функция ОО$ 316, использует данные из Р$Р для своей работы; во-вторых, код
резидентной части должен быть нанисан для работы с нулевого смещения, а не со
100Ъ, как обычно; и, в-третьих, некоторые программы, исследующие выделенные
блоки памяти, определяют конец блока по адресу, находящемуся в РУР програм-
мы — владельца блока со смещением 2. С первой проблемой можно справиться
вручную, создав отдельные блоки памяти для резидентной и инсталляционной
частей программы, новый РУР для инсталляционной части и завершив програм-
му обычной функцией АСВ или ПМТ 20}. Реальные программы, делающие это, су-
ществуют (например, программа поддержки нестандартных форматов дискет
РУ_1700), но мы не будем чрезмерно усложнять наш первый пример и скопиру-
ем резидентную часть не в позицию 0, а в позицию 801, то есть, начиная
с середины Р$Р, оставив в нем все значения, необходимые для нормальной рабо-
ты функций ОО5.
Прежде чем это сделать, заметим, что и номер диска, и адрес предыдущего |
обработчика ПМТ 21Ь изменяются только. при установке резидента и являются.
константами во время всей его работы. Более того, каждое из этих чисел исполь-
зуется только по одному разу. В таких условиях оказывается, что можно вписать _
номер диска и адрес перехода на старый обработчик прямо в код программы.
Кроме того, после этого наш резидент не будет больше ссылаться ни на какие
переменные с конкретными адресами, а значит, его код становится перемещаемым,
то есть его можно выполнять, скопировав в любую область памяти.
; Тэгрер. азм
; Пример пассивной резидентной программы с. переносом кода в РЭР.
; Запрещает удаление файлов на диске, указанном в командной строке,
; всем программам, использующим средства 00$.

.тоде} —11пу
.соде _
ог ° Св |
@епузед дм ? . ; Сегментный адрес копии окружения 00$.
0г9 вов
стд_]еп [5 ? ‚; Длина командной строки.
стд_11пе [61°] ? ; Начало командной строки.
ог9 - 1008 - ; СОМ-программа,
Сложные приемы программировани
зТтагт:
019 111211:
Зтр ВогЕ 1101{1а117е : Переход на инициализирующую часть.
1121 _Папа]ег ргос о. Фаг , Обработчик прерывания 211.
ризВЕ Сохранить флаги.
стр ‚ ав, 411. Если вызвали функцию -418
(удалить файл)
Ро41В
ах, 71411 или 71418 (удалить файл
С длинным именем),
Ра4А начать наш `обработчик.
ЭПогЕ пос _Рп41И Иначе - передать
управление предыдущему обработчику.
Ро4лн:
ах Сохранить модифицируемые
Ьх регистры. | |
6х,ах Можно было бы использовать
адресацию [е9х+1], но.в старшем
„, слове ЕБХ совсем необязательно 0.
Вузе рег [5х+1],’: ; Если второй символ АЗСТ7-строки,
переданной ТМТ 218, двоеточие, первый
символ должен быть именем диска.
_ Ри зрес
- ав, 198 Иначе: :
211 функция 00$ 191 - определить
текущий: Диск.
ада а1,*А’ Преобразовать номер диска
к заглавной букве.
Зир ЗПогЕ сотраге Перейти к сравнению.
71] зрес;
поу а1, буфе рёг [6х]; , АЁ = имя диска из АЗСТ7-строки.
апа а1, 11011111. В Преобразовать к заглавной букве.
‘сотраге:
6 ЗСВ Начало кода команды СМР А,. число.
9г1ме_Теттег: 95 '7’ Сюда процедура инициализации
впишет нужную букву.
рор Бх Эти регистры больше не
рор ах понадобятся. Если диски совпадают -
]е ассезз_деп1еа запретить доступ.
пот_Тп41В:
рорР Восстановить флаги и передать
управление предыдущему
обработчику ТМТ 21п:..
а ОЕав Начало кода команды
УМР, число РАВ.
014_111218 Сюда процедура. инициализации
запишет адрес’ предыдущего
обработчика’
ТМТ 211.
\

Резидентные программы: |
ассезз_депед: х
. рорЁ
„ризй Ьр .
тоу Бр, зр . : ; Чтобы адресоваться в стек
; в реальном режиме,
ог могд рег [6р+6],1 р — ; установить флаг
‚ переноса (бит 0) в регистре А
; флагов, который поместила команда ТМТ
. ‚ в стек перед адресом возврата.
‚ рор Бр
моу ах, 5 ; Возвратить код ошибки “доступ запрещен”.
1гет р Вернутьея в программу.
114211_Папд]ег епдр

13г_1епотв еди ` $-17(211_папоЛег

11 1а112е ргос пеаг


стр Буте руг стд_Теп, 3 - ; Проверить размер
| | о ° ; командной строки
дпе пот_1п51а11 : (должно быть3 -
. . .. ; пробел, диск, двоеточие).
стр Буте рег ств_11пе[2},’:'’ ; Проверить .
‚. ` р Третий символ командной
пе по{_1п51а11 ; строки (должно быть двоеточие).
во\ а1, Буте рег стд_11пе[1] |
апа а1, 110111116 ; Преобразовать второй
; символ к заглавной букве.
стр а], ‘А’ ° ; Проверить, Что это не меньше “А”
35 пот_1п3{а11 . ; и не болые
стр а1, '2' | $ "2". ,
да пот_1п$1а11 ; Если хоть одно из этих условий
‚ не выполняется - выдать
; информацию с программе и выйти.
‚ Иначе - начать процедуру
..; инициализации.
моу Буде рег дг1\е_Тфеттег,а1-; Вписать” имя
` ; диска в код резидента.
ризп — ез
оу ах, 35218 * | ; АН = 351,
, °; А = номер прерывания.
111 218 р ; Получить адрес |
и ‚ обработчика ТМТ 211
МОУ мога рфг 019111218,5х ; и вписать его в код резидента.
моу мог руг 014. 1п1211+2,ез
рор 25
с13 ` ‚ ‘Перенос кода. резидента,
ре 31, ОРР5ет 1пт211_Валд1ег ; начиная’ с этого ‘адреса,
мо 91, 801 — ; в РЗР: 00808.
гер МОУ$Б - .
ШИН! Сложные приемы программиров
ань
‚ МОУ ах, 25218 . ; АН =. 258,
| у ; АЁ = номер прерывания.
му дх,00808 ; 05:0Х. - адрес нашего обработч
и 2 ика.
| ; Установить обработчик ТМТ
- МОУ ап, 49в 218.
; АН = 491 В
тоу — ез,мога рег епузев. ; ЕЗ = сегментный адрес блока
И ; С нашей копией окружения 005.
‘19 21 ` ; Освободить память из-под
: ; окружения.
моу 9х, ВОп+Езг_1епдти _ ; 0Х - адрес первого байта
‚ за концом резидентной части
; программы.
и 278 ° | ; Завершить выполнение,
‚ оставшись. резидентом.
по_11${а11: . --
по\
|
ан, 9 ‚ АН = 091.
оу -
@х, оТРзей изаде | ‚ `05:0Х = адрес строки
| ‚, С информацией об
‚ использовании программы.
ТП ‚ 218
; Вывод строки на экран.
гет у ‚ Нормальное завершение
‚ Программы.
; Текст, который выдает прог
рамма при. запуске
‚ С неправильной командной
строкой :.
изаде 96 “Узаде: 15г.сом 0:", ООВ, ОАВ
45. “Беп1ез де1ете оп Чг1уе 0:”, ООН, ОАВ
а "$"

111 а117е епёр . }


епа ЗТагт
Теперь эта резидентная программ
а занимает в памяти только 208
байт.
5.9.2. Мультиплексорное прерыв
ание
Если вы запустите предыдущий пример
несколько раз, с разными или даже оди-
наковыми именами дисков в кома ндной строке, объем свободной памя
ти РОЗ -вся-

случае это не приводит ни к каким


последствиям, кроме незначительного
шения объема свободной памяти, умень-
но во многих чуть более сложных
гут возникать различные проблемы; случаях мо-
например многократное срабатывание
актив-
-Резидентные программы: _
вводили дополнительную функцию в используемое прерывание. Например: наш
резидент мог бы проверять в.обработчике ИМТ 21 АН на равенство какому-ни-
будь числу, не соответствующему функции ОО$, и возвращать в, например, АТ.
код, означающий, что резидент присутствует. Очевидная проблема, связанная
с таким подходом, — вероятность того, что кто-то другой выберет то же неисполь-
зуемое прерывание или что будущая версия ОО$ станет использовать ту же фун-
кцию. Именно для решения этой проблемы, начиная с версии РОЗ 3.3, был пре-
дусмотрен специальный механизм, позволяющий разместить до 64 резидентных
программ в памяти одновременно,— мультиплексорное прерывание.
МТ 2Ей: Мультиплексорное прерывание
Вход: —АН= идентификатор программы —,„
008-— 7ЕЁ зарезервировано для РОЗ АИпйомз
ОВ8Ь — ОВЕН зарезервировано для сетевых функций
_ ОСОБ — ОЕЕЪ отводится для программ _.
АТ. = код функции |
00 — проверка наличия программы
остальные функции — свои для каждой программы
ВХ, СХ, ОХ- 0 (так как некоторые программы выполняют те или иные
действия в зависимости от значений этих регистров)
Выход:
Для подфункции АТ.= ООВ, если установлен резидент с номером АН, он дол-
жен вернуть ОЕЕЬ в АГ. и какой-либо идентифицирующий код в других регист-
рах, например адрес строки с названием и номером версии. Оказалось, что такого
уровня спецификации совершенно недостаточно и резидентные программы по-
прежнему работали по-разному, находя немало способов конфликтовать между
собой. Поэтому появилась новая спецификация — АМ!$ (альтернативная снеци-
фикация мультиплексорного прерывания). Все резидентные программы, следую-
щие этой спецификации, обязаны поддерживать базовый набор функций АМП5,
а их обработчики прерываний должны быть написаны в соответствии со стандар-
том 1ВМ [5Р, который делает возможным: выгрузку резидентных программ из
памяти в любом порядке. в.
Начало обработчика прерывания должно выглядеть следующим образом:
+001: 2 байта-ОЕВЬ,10Ъ (команда упр зВог на первый байт после этого блока)
+021: 4 байта — адрес предыдущего обработчика: именно по адресу, хранящемуся
здесь; обработчик должен выполнять ‘са или лар
+06: 2 байта - 424ВЬ - сигнатура 1$Р-блока .
_ +085: байт — - 801, если это первичный обработчик аппаратного прерывания (то
о ‚ есть он посылает контроллеру прерываний сигнал ЕОГ)
00Ъ, если это обработчик программного или дополнительный об-
работчик аппаратного прерывания
+091: 2 байта:— команда пр Вот на начало подпрограммы аппаратного сброса -
’. =. обычно состоит из одной команды ТВЕТ _
+0ВВ: 7байт — зарезервировано
№! Сложные приемы программирован
Все стандартное общение с резидентной прог
раммой по спецификации АМ
происходит через‘прерывание 20. При
установке инсталляционная часть ре.
дентной программы должна проверить, нет
ли ее копии, просканировав все ид
тификаторы от 00 до ОЕЕБ, и, если нет, устан
овить обработчик на первый своб.
ный идентификатор.
ИМТ 201: Мультиплексорное прерывание АМ!$
. р
Вход: АН - идентификатор программы
АТ. = 00: проверка ‘наличия
АТ. - 01: получить адрес точки входа
АГ = 02: деинсталляция
АТ. = 03: запрос на активизацию (для «всплыва
ющих» программ)
АТ.= 04: получить список перехваченных преры
ваний
АЕ = 05: получить список перехваченных клави
ш
АТ. = 06: получить информацию о драйвере
(для драйверов устройст
АЕ = 07 - ОЕВ - зарезервировано для АМ1$
|
АР = 1ЕВ - ОЕЕЬ = свои для каждой программ
ы
Выход: АГ. = 001, если функция не поддержива
ется
Рассмотрим функции, описанные в специфик
ации АМ!$ как обязательные.
МТ 208 АГ = 008: Функция АМ — проверка
наличия резидентной программ;
Вход: -АН = идентификатор программы
АТ. = 00
Выход: АТ, = 00}, если идентификатор не занят
АЕ. = ОЕЕБ, если идентификатор занят
"СН = старший номер версии программы
СТ. = младший номер версии программы
ОХ:ПР = адвес АМ!Г5-сигнатуры, по перв
ым 16 байтам которой и про
исходит ‘идентификация. |
Первые 8 байт - имя производителя программы;
следующие 8 байт -
имя программы; затем или 0 или АЗС[-строка
с опи
санием программы, не больше 64 байт.
МТ 201 АГ, = 021: Функция АМ! — выгрузка
резидентной программы из памяти
Вход: АН - идентификатор программы
АГ = 02. со
РХ:ВХ = адрес, на который нужно передать управ
ление после выгрузки
Выход:
АТ. = 01В - выгрузка не удалась
АТ. = 02, - выгрузка сейчас невозможна, на
произойдет чуть позже
АТ. = 03 - резидент не умеет выгружаться сам,
но его можно выгрузить,
„ резидент все еще активен |
ВХ -сегментный адрес резидента ``.
АТ = 04 - резидент не умеет выгружаться
сам, но его можно выгрузить,
_ резидент больше неактивен
ре
Резидентные программы = = ММС.
ВХ - сегментный адрес резидента:
АТ. = 05 -— сейчас выгружаться небезопасно — повторить запрос позже
АТ. = 06}- резидент был загружен из СОМЕГС.5У$ и выгрузиться не-
может, резидент больше неактивен
АТ.== 07Ь - это драйвер устройства, который не умеет выгружаться сам
ВХ - сегментный адрес
АТ, = ОЕЕВ с передачей управления на ОХ:ВХ - успешная выгрузка.
Т№Т 201 АТ. - 028: Функция АМ!$ - запрос на активизацию
Вход: АН= идентификатор программы
АТ,= 03с |
` Выход: АГ.= 004- резидент — «невсплываю щая» программа _
АТ. = 01 -— сейчас «всплывать» нельзя — ‘повторить запрос позже
АТ. = 02, - сейчас «всплыть» не могу, но «всплыву» при первой возмож-
ности
` АТ, = 03 — уже «всплыл»
АТ. = 048 - «всплыть» невозможно
ВХ, СХ - коды ошибки
АТ. = ОЕЕЪ - программа «всплыла», отработала и завершилась
ВХ - код завершения. о

№Г2ЬР АЕ- 041: Функция АМГ$ — получить список перехваченных прерываний


Вход: АН- идентификатор программы
АТ.= 04В
Выход: АТ,= 045 .. - 5
ОХ:ВХ- адрес списка прерываний, состоящего из 3-байтных структур:
байт 1: номер прерывания (20 должен быть последним)
байты 2, 3: смещение относительн о сегмента, возвращенного
в ОХ обработчика прерывания (по этому смещению должен
находиться стандартный . заголовок 15Р)
МТ 208 АЕ = 058: Функция АМ[$— получить список ‘перехваченных клавиш
Вход: АН= идентификатор. программы
‚ АГ = 05
Выход: .
АГ.= ОЕЕВ — функция поддерживается
ОХ:ВХ - адрес списка клавиш:
„_ +00Ъ: 1 байт: тип проверки клавиши:
бит 0: проверка до обработчика ПМТ 9
бит 1: проверка после обработчика ПУТ 9
бит 2: проверка до. обработчика ПМТ 15В/АН- 4ЕЬ
бит 3: проверка после обработчика ПМТ 15В/АН= АРВ .
бит 4: проверка при вызове ПМТ 16В/АН- 0, 1,2
бит 5: проверка при вызове ПМТ 16Б/АН = 101, 11, 126
бит 6: проверка при вызове ПМТ 16В/АН= 20}, 215, 226
бит 7: 0
ИЗИНШИШИНИИИ |— Сложные приемы программировани
+01Ъ: 1 байт: количество перехваченных клавиш
+025: массив структур по 6 байт: |
байт 1: скан-код клавиши (старший бит -— отпускание клавиши, 00/80
если срабатывание только по состоянию $ВЁ-Сы1-А№и т. д.)
байты 2, 3: необходимое состояние клавиатуры (формат тот же, что и
в сл.
ве состояния клавиатуры, только бит 7 соответствует нажати
‚любой клавиши 5$) | ,
байты 4, 5: запрещенное состояние клавиатуры (формат тот же) .

байт 6: способ обработки клавиши


бит 0: клавиша перехватывается до обработчиков
бит 1: клавиша перехватывается после обработчиков
бит 2: другие обработчики не должны «проглатывать» клавишу
бит 3: клавиша не сработает, если, пока она была нажата, нажима
ли или отпускали другие клавиши |
бит4: клавиша преобразовывается в другую
бит 5; клавиша иногда «проглатывается», а иногда передаетс:
дальше
биты 6, 7: 0
Теперь можножанисать резидентную программу, и она не загрузится дваждь
в память. В этой ‘ирограмме установим дополнительный обработчик на
аппарат
ное прерывание от клавиатуры [ВО1 (ПМТ 9) для отслеживания комбина
ции кла
виш АН-А; после их нажатия программа перейдет в активное состояние,
выведе'
на экран свое окно и среагирует уже на большее количество клавиш, Такие
про:
граммы, активизирующиеся при нажатии какой-либо клавиши, часто
называю"
«всплывающими» программами, но наша программа на самом деле будет
толькс
казаться «всплывающей». Настоящая «всплывающая» программа после
активи:
зации в обработчике ВМТ ЭВ не возвращает управление до окончания
работы
пользователя. В нашем случае управление возобновится после каждого
нажатия
клавиши, хотя сами клавиши будут поглощаться программой, так что
ей можно
пользоваться одновременно с работающими программами, причем на скорост
и их
работы активный азсй.сот никак не скажется.
Так же как и с предыдущим примером, программы, не использующие средства
2О5/ВТО$ для работы с клавиатурой, например файловый менеджер
РАБ, будут
получать все нажатые клавиши параллельно с нашей программой, что
приведет
к нежелательным эффектам на экране. Кроме того, в этом упрощенном
примере
отсутствуют некоторые необходимые проверки (например, текущий видеоре
жим)
и функции (например, выгрузка программы из памяти), но тем не менее
это ре-
ально используемая программа. С ее помощью легко посмотреть, какой
символ
соответствует какому АЗСП-коду, и ввести любой символ, которого
нет на клави-
атуре, в частности псевдографику.
; а$с11. азм
`; Резидентная программа для просмотра и ввода АЗСТ1-символов.
НС
Резидентные программы = ^_ |257]
А1Т-А - активизация программы.
Клавиши управления курсором - выбор символа.
‚ Емфег. - выход из программы, с вводом символа.
Езс >- ‘выход из. программы без ввода символа.
; АРГ:
Программа занимает первую свободную функцию прерывания’ 20
в соответствии со спецификацией АМТЗ 3.6.
Поддерживаются функции АМТ$ 00н; 021, "08; 04Н и 058.
Обработчики прерываний построены. в соответствии с ТВ ТР.

‚ Адрес верхнего левого угла окна (23-я позиция ‘в третьей строке).


ТАЯТ _ РОЗТТТОМ еди (80*2+23)*2

.тоде] 1пу
‚ соде . . а | | р
-.186 | . ; Для сдвигов и команд ризпа/рора.
ог9 2сп ` о |
епузед м 2? О: Сегментный адрес окружения 00$.
` огд °° 1001 о; Начало‘ б0м-программы. `
этагт: |
"р 11а 7е ; Переход на инициализирующую часть.

Ни_гезе{9: - , ,
гесг | о” ; ТР: минимальный
пм’ гезет.

; Обработчик. прерывания 098 ‘авт

1п1091_Папд]ег ргос ° Таг


. Этр } ЗПОГЕ асфиа1 1п09Н_ ап ег ; ТЗР: пропустить блок.
019111098 99 _? : 1$Р: старый обработчик.
ди 4248 : Т5Р: сигнатура.
95 ов ` ; 13Р: вторичный обработчик.
Этр ЗПогт Им_гезет9 ; ТЗР: ближний тр на пм гезет.
, 96 7 ир (0) = ; ТУР:. зарезервировано.‘
астиа1_1п$091_пап ег: ; Начало обработчика. ТМТ. 09п.

; Сначала вызовем предыдущий обработчик, чтобы дать 8105$ возможность


; обработать прерывание и, если это было нажатие клавиши, поместить’ код
в клавиатурный буфер, так как мы пока не умеем работать с ‚Портами клавиатуры
; и контроллера прерываний.
ризПЕ о,
:ва1} Фиога руг ‹с3:014. Алфо9в _:

По этому адресу обработчик‘ Т№Т 208 запишет код’ команды ТВЕТ


‚ для дезактивизации программы:
915а51е_ро1п{ ]}аБе] Буте

. ризпа ^ ; Это аппаратное прерывание - надо


ризй 95 ; сохранить все регистры.
ризй е5
_ с14 , ‚ Флаг для команд строковой обработки.
РЕЗИНЕ
ИИНИ Сложные приемы программировань
0в800н
ез ; Е5 = сегментный адрес видеопамяти.
00408
95 5 0$ =‘сегментный адрес. области данных ВТ0$.
91, мог@ рег 43: ОО1АВ ; Адрес головы буфера клавиатуры.
91, мога. рег 95:001С1 ; Если он равен адресу хвоста,
ех11_09п_напа1ег ; буфер пуст и нам делать нечего‘
; (например если прерывание пришло по
‚ отпусканию клавиши),
ах, мога ртг [91] `; Иначе: считать символ. из головы буфера.
Буте рак С5:ме.аге_ ас{1уе, 0 ; Если программа уже
а]геаду_аст1уе ‚ активизирована’ - перейти
‚ К обработке стрелок и т.п.
ан, 1ЕН ; Если прочитанная клавиша не А
‘ех1_О9н_папод1ег ; (скан-код ЛЕВ) - выйти. ^

а1,Буте рг 950017! ; Иначе: считать байт


; состояния клавиатуры.
21,081 ; Если не нажата любая А1Т,
ех1т 09 _папд]ег ; ВЫЙТИ. `
мога рег '95:001Сй, 91 ; Иначе: установить адреса
‚ Головы и хвоста буфера одинаковым
и,
‚ Пометив его тем самым как пустой.
зауе_5сгееп ; Сохранить область экрана, которую’
‚ Накроет всплывающее окно.
сз
95° ; 0$ = наш сегментный адрес.
915р]ау_а11 ; Вывести на экран окно программы.
руте р\г ме_аге_ас1уе, 1
Установить флаг
Зтр ЗВоГЕ ех11 -О9Н_папд]
ег и выйти из обработчика.
; Сюда передается управление, если
программа уже активизирована.
; При этом Еб = 088001, (0$ =
0040Н,ОТ = адрес’ головы буфера клавиатуры
; АХ = символ из головы буфера. ,
а] геа4у_аст1уе:
` пом могГа ‘рег 93:001СН91
,- ; Установить адреса
‚ Головы и’хвоста буфера одинаковым
и,
‚ пометив его тем самым как пусто
ризН 65 й.
рор 9$ ; 0$ = наш сегментный адрес.
во\ а],ав ; Команды стр а1, ? короче команд стр ай, 2.
пом БН, Буфе рук сиггепт_спаг ; Номер выделенного в данный момент
; АЗСТТ-символа.
стр а], 481 ; Если нажата стрелка вверх (скан-код 488),
ле пот _ир
ЗиБ БВ, 16 ‚ Уменьшить номер символа на 16.
Резидемтные программы‘. о 265
пох ир:
стр аг, 50и . с: Если нажата стрелка вниз (скан-код 508),
пот_бомп . .
дпе
206 Л, 16 -. о; увеличить номер символа на 16. `
..
пот_домп: .
спр ` 21,488 ; Если нажата стрелка влево,
3пе пот_1е+т . -
дес БВ | : ‚: Уменьшить номер символа на 1.
пот_1е1т: ° .
стр. ат, 408 ‹ Если нажата стрелка вправо,
пе пот_ гаи |
1пс ЫИ . ; увеличить номер символа на 1.
пот _г19В*: |
стр а1, 1Св ; Если нажата Ептег (скан-код 18),
3е ептег_ргеззей` . ; перейти к его обработчику.
дес - а1 - 7.7’; Если не нажата клавиша Езс (скан-код 1),
п ех1{_м1тп_915р1ау ; выйти из обработчика, оставив ^
; окно нашей программы на экране.
ех1+_аРтег_ептег: —. - ; Иначе: —
са11 гезтоге_зсгееп ; убрать наше окно с экрана,
мо\ Буфе руг ме_аге_аст1уе,0 ; обнулить флаг активности,
тр ЗПогф ех1{_0О9п_пап ег ; выйти из обработчика.

ех1+ м1 ТН, 91зр]ау: ; Выход с сохранением окна


. . ; (после нажатия стрелок).
моу Буте рёг сиггепт_спаг,6й ; Записать новое значение
_* . , ‚ текущего символа.
са11 41$р1ау_а11 | : Перерисовать окно.

ех11_09Н_папд1ег: _; Выход из обработчика ТМТ 091.

рор е5 `
рор 9$ | . : Восстановить ‘регистры
` рора |
1гет - ; и вернуться в прерванную программу.

ме_аге_ас+1уе 95 0 ; Флаг активности: равен 1, если


: программа активна.
сиггелт_спаг 45 З7И . Номер АЗСТТ-символа, выделенного
; В данный момент.

. Сюда передается управление, если в активном состоянии была нажата Ептег.


еп{ег_ргеззед:
моу ап, 051 ‚ Функция 051
поу , С1,0 о ; (Н=о0
пом с1,Буфе рфг сиггепе_сваг ; СЁ = АЗСТТ-код
т 161 `_ ‚ Поместить символ в буфер клавиатуры.
Эмр ЗПОГЕ ех1т_а1тег_ептег ; Выйти:из обработчика, стерев окно.

: Процедура зауе_зсгееп. .
; Сохраняет в буфере зсгееп_риРег содержимое области экрана, которую
; закроет наше окно.
Сложные приемы программирован,
зауе_всгееп ргос . о пеаг
[8 $1, ЗТААТ_РОЗТТТОМ
ризН 08800Н. ; 05:51’- начало этой области
; В видеопамяти..
рор 9$
ризй е5
` ризв с3
рор е$
том 91, оРРзет $сгееп_Би!Тег ; ЕЗ:0Т - начало буфера в программе.
мо\ 9х, 18 ; ОХ = счетчик строк.
зауе_зсгееп_1оор:
оу сх,33 ; СХ = счетчик символов в строк
гер том е.
; Скопировать строку с экрана в
а94 $1;(80-33)»2 буфер.
; Увеличить ЭТ до начала следующей
дес 9х строк!
; Уменьшить счетчик строк.
м2 зауе_зсгееп_1оор ; Если он не ноль - продолжить

_
ро
Ге
` е3 цикл,

заме_зсГееп епар
‚; Процедура гезтоге_зсгееп.
‚ Восстанавливает содержимое област
и экрана, которую закрывало наше
‚ всплывающее окно данными из буфера зсгееп_БиЕЁег.
гезтоге_зсгееп ргос пеаг |
моу 81, ЗТАВТ_РОЗТТТОМ ; Е8:0Т - начало: области
моу 31, ОРРзет зсгееп_риРТег в видеопамяти,
; 03:51 - начало буфера.
моу Хх, 18 ; Счетчик строк,
гезтоге_зсгееп_1оор:
оу сх, 33 ; Счетчик символов в строке.
гер МОУЗм ; Скопировать строку. |
ааа 91, (80-33}=2 ; Увеличить ОТ до начала следующей
дес 9х строки.
; Уменьшить счетчик строк.
12 гезТоге_зсгееп_1оор ; Если он не ноль - продолжить.
ге. .
гезТоге_эсгееп епар
; Процедура 41$р1ау_а1].
; Выводит на экран текущее состо
ян ие всплывающего окна нашей программы.
91$р]ау_а1] ргос пеаг
‚ Шаг 1: вписать значение текущего выдел
енного байта в нижнюю строку
тоу окна.
а], буте рег сиггепт_спаг ; АЁ
= выбранный байт.
ризН ах
ЗВг а1,4 ; Старшие: четыре байта.
стр а1,10 ; Три команды,`
59) а1, б9н ; Преобразующие цифру в А.
аз
; В её АБС1Т-код (0-9, А-Р).
тоу Буте рёг Нех_вуте1,а1 Записать символ на его
:
‚ место в нижней строке.
`рор ах
Резидентные программы. `.^
апа а1, ОИ ; Младшие четыре бита.
стр а1, 10 ; То же преобразование.
$6 ^ а1, 691 .
да$ у дот
моу Буте руг пех_ву{е2,а1 ‘; Записать младшую цифру.

; Шаг 2: вывод на экран окна. было бы проще хранить его как массив И выводить
‚ командой тоузм, как и буфер в процедуре гезтоге_зсгееп, но такой массив займет еще
: 1190 байт в резидентной части. Код этой части процедуры_Ч4зр1ау_а11 - всего 69 байт.
‚; Шаг 2.1; вывод первой строки. | |
том ан, ЕВ ; Атрибут белый на синем. .
тоу = = 91, ЭТАВТ_ РОЗТТТОМ __`; Е8;0Т - адрес в видеопамяти.
- моу ЗЕ, ОРРЗет 41зр]ау_14пе1 ; 05:51 - адрес строки.
| моу сх, 33 , ; Счетчик символов в строке.
91зр]ау_1о0р1: - о
тоу а], Буте ртг [$1] .. ; Прочитать символ в АЁ-
3105м . | ; и вывести его с атрибутом из АН.
пс $1 - ; Увеличить адрес символа в строке’.
10ор 913р]ау_100р1 '
; Шаг 2.2: вывод собственно таблицы
оу дх, 16 .. ; Счетчик строк.
| мо\ а], -1 : ; Выводимый символ.
941зрТау_1оор4; : Цикл по. строкам.
ада 91, (80-33) *2 ; Увеличить ОТ до начала
ризп ах | ; следующей строки.
тоу, — а1,0ВЗВ , |
З10$м | ‚ Вывести первый’ символ (0ВЗП).
рор ах .
ОУ сх, 16 ; Счетчик символов в строке.
91$р]ау_100р3: ``; Цикл по символам в строке.
{пс 81 ’.; Следующий АЗСТТ-символ.
$то5м ‚ Вывести его на экран.
ризв ах . у °
мом а1, 201 ; Вывести. пробел.
$103
рор ах .
1оор 91зр1ау_100р3 ; И так. 16 раз;
ризй ах |
36° ‘91,2 . ; Вернуться назад на 1 символ
`_ по а], ОВЗВ | ; и вывести ОВЗИ на месте
5105\ В ; последнего пробела.
рор ах .
дес 9х . | ; Уменьшить счетчик строк.
912 91зр3ау_1оор4

; Шаг 2.3: вывод последней строки.-


аа 91, (80-33) *2 ; Увеличить ЭТ до-начала следующей строки.
поу сх, 33 . : Счетчик символов в. строке.
поу $1, ОЕРзет 41зр1ау_11пе2 ; 05:51 - адрес’ строки.
РЕРИИИИШИШИИ! |— Сложные приемы программирован
915р]1ау_100р2:
том а1, уфе рте [31] — ; Прочитать символ в АЕ.
$Р03м - | ’ ; Вывести его с атрибутом
"пс 9. на экран.
- ‚ Увеличить адрес символа
1оор 915р1ау_100р2 в строке.
.
`
; Шаг 3: подсветка (изменение атрибута
) у текущего выделенного
моу символа,
а], Бубе ртг сиггепт_ спаг
; АЁ = текущий символ.
оу ап,0
поу Ч1, ах.
‚ апа 91. ОР; ; ОТ = остаток от деления на
$11 = 91,2 16. (номер в строке).
‚; Умножить его на 2, так как на экран
е
‚ используется слово на симво
л, и еще раз на 2,
‚Так как между символами
Пг - пробелы,
ах, 4 ; АХ = частное от деления
1ти] на’ 16 (номер строки).
ах, ах, 80*2 - ;Умножить его: на длину строки на экране,
а99 91, ах ‚ сложить результаты,
294` 91, ЗТАВТ_РОЗТТТОМ+-2+80*=2+1
; добавить адрес начала окна + 2,
‚ чтобы пропустить первый столбец, + 80 х 2,
‚ чтобы пропустить первую
строку, + 1, чтобы
‚ Получить адрес атрибута,
тоу а не символа,
а], 071н . ’‚ Атрибут - синий на сером.
зто ` ; Вывод на экран.
гет р .
941зр]ау_а11 епар`
1и09в_папа]ег епар ‚ ; Конец обработчика ТАТ эн.
‚; Буфер для хранения содержим
ого части Экрана, которая накрывается нашим окно
зсгееп_БиЕег 96 1190 дир(?) м.
: Первая строка окна.
913р1ау_11пе1 ° 4. ОБАН,21 Чир (064в):
*+ АЗСТТ *',11 бир (0648), ОВЕВ.
; Последняя строка окна.
913р1ау_11пе2 `
96° ‘ 0бон,11 Фир (0641),'* Нех.”
пех_Буфе1 а ? р | ; Старшая’ цифра текущего
Рех_Буте2 ‚ ЧБ байта.
? ; Младшая цифра текущего
95. байта.
” *", 10 дир (об4н), оо9в
Ри_гезет20:. гетЕ
; ТЗР: минимальный Рым_гезет.
; Обработчик прерывания
ТАТ 208. |
; Поддерживает функции АМТЗ
3.6 001, 028, 03н, 048 и 05Н:
1иЕ20Н папа ег ргос Таг
тр ЗНоге астиа] _1пЕ20н_папа] ег
019_1пЕ20Н ; ТЗР: ‘пропустить блок..
94 2?
; ТЗР: старый обработчик.
Чи - 424ВВ : ; 15Р: сигнатура.
[1 ов : ; 1$Р: программное прерывание.
тр ЗПОГЕ Вм_гезет20
“;’ТЗР:. ближний тр на вм_гезет.
96 7 дир (0) ; 1$Р: зарезервировано.
Резидентные программы ` ОИ
ОНО
астиа] 11120 _папф ег: ; Начало собственно обработчика: ТМТ 201.
96 ВОВ, ОЕСН : Начало команды СМР АН, число.
их, 19 96 ?. . ; Идентификатор программы.
де 1180$ ; Если вызывают с чужим АН - это не нас.
тр Чиогд руг с$:014_1п1208
$ ив: ,
стр 21.06 ; Функции ОбН и выше
]ае 11120_по с} №8 поддерживаются. -
Ге] о ; АХ = номер функции.
ЮУ 91, ах ; ОТ = номер функции.
$11 91,1 ``: умножить его на 2, так как )итртаб]е -
| `_; таблица слов.
Эр мог@ рег с$: дитр®а61е[91}; Косвенный ‘переход на. обработчики функций.
}утруаб1е @м оЁРзет 11120:00, оРРзеё 11120_по
т 9% —` оРРзет 11820.02, оТЕзет” 11120_03
ом ответ 11120-04, ‚ответ 11120_05
11120_00:.., . . ; Проверка наличия.
ЮУ - а1, бЕЕВ ; Этот номер занят.
воч. сх, 01001 и ; Номер версии 1.0.
ризН 6$ ,.
рор ‘ ах ; 0Х;01 - адрес АМТ5-сигнатуры.
ей 91, от зет ат. 81 9п.
1гет
11120_по: ; Неподдерживаемая функция.-
[0 а}, бов. ; Функция не - поддерживается.
, 1гет -` .
11120_02: — ; Выгрузка программы.
мо Буте рЕг. сз: 91заб1е_ро1пт, СЕВ ; Записать код команды ТВЕТ.
; ПО ‘адресу 91заб1е_розпт в обработчик ТМТ 09В.
моу а], 04 ; Программа’ дезактивизирована, но сама
| ; выгрузиться не может. |
оу Ьх, с$ - сегментный адрес программы.
ВХ
‚ лет } |
1120_03: - ; Запрос на. активизацию для “всплывающих”. программ,
стр буте рЕг ме_аге-ас уе, 0 ; Если окно не на экране,
}6 а] геаду_рорир
са] 1 `зауе_эсгееп ; сохранить область экрана,
ризи 65
рор 95 | от
са11 91$р]ау_а11 | ; вывести окно
МОУ Буте руг. ме аге_аст1уе,1 ; и поднять флаг.
а]геаду_рорир: о |
оу а1, 03й ; Код 03: программа активизирована.
1ге |

11520.04: , й | ; Получить список перехваченных прерываний.


_ У дх, сз | ‚' Список в ОХ:ВХ..
Ьх, орет ат1$_Поок113{
И _ Сложные! приемы программирования
11120_05: . ; Получить список “горячих” клавиш.
„ ОУ „. а1, ОРЕВ ; Функция поддерживается.
тоу 9х, сз ; Список в ОХ:ВХ.
° МОУ Вх, оРРвет ат1з осквув
1гет
1120. _папа1ег пар
; АМТ5: сигнатура для резидентных „Программ:
ат1$_319п Ч "Сиьёт.. ; 8 байт - имя автора.
ЧБ ^"АЗСТТ.. ; 8 байт - имя программы.
в. “АЗСТТ Ч1зр1ау ап 1приф и{1111у",0
; АЗСТ2--комментарий
. ; не более 64 байт.
; Мб: список перехваченных преры
ваний.
ап _100К1131 = 05 ОЭ
"би оРГзет 1птО9в._лапбЛег
ЧЬ.. 20н .
би оЕРзет 1пЕ20в_паполег
.
; АМТ$: список "горячих" клавиш. _
‚ат1з_По+Кеуз ЧЬ ов ; Клавиши проверяются после стандартного
; обработчика: Т№Т о9в.
.: 1 ; Число клавиш,
ЧБ ЗЕВ ; Скан-код клавиши (А). .
ди ОЗ ; Требуемые флаги (любая Ат).
Чи 0 ; Запрещенные флаги,
% 1 ^ ; Клавиша проглатывается.
; Конец резидентной части.
; Начало процедуры инициализации.

тп аН2е ргос. пеаг


ав, 9
@х, отзет иваде ; Вывести информацию о программе.
171 в
; Проверить, не ‘установлена
4
ли уже наша программа.
тоу ав, -1 ; Сканирование номеров от ОЕЕВ ‚до
| 00п.
тоге_пих:
а1,.001 ; Функция ООН - проверка наличия’ програ
208 ммы.
; Мультиплексорное прерывание АМТ$.
а1, 00 ; Если идентификатор свободен,
пот_Ргее ^
7
Буте. рЕг. пих_19,ав записать его номер прямо в. код
обработчика 1пт. 20н.
Зтр зпоге пехе_мих
ПОТ _ТГгее:
тому ез,9х Иначе - ЕЗ:0Т = адрес их сигнатуры,
то $1, ОТзе{ ат1$_з10п 05:51 = адрес нашей сигнатуры.
оу сх, 16 Сравнить первые 16 байт.
гере стрзь
`
Эехг а1геаду_1оадед Если они не совпадают,
пехе_тих: ^^^
дес ай ; перейти к следующему ‘идентификатору,
_ 312 моге_тих : ; пока это не 0
.; (на самом деле в нашем примере сканирование яроисходит от СЕРА до оли,
; так как 0 мы используем в качестве признака отсутствия свободного номера
; в следующей строке).
+гее_мих.`Тоип@: —› . о
сир Буте рег тих 19,0 `: Если мы ничего не записали,
3е ° по_моге_тмих- | ; идентификаторы кончились.

воу ах, 35201 ла -з АН =; 351, "АЕ = номер прерывания.


т 218 .“ ^” ; Получить адрес обработчика ТНТ 20.
моу мог рег 016 зим, хо ги поместить его в 014_17120Н. |
во мог рег о14_1п120Н+2, ев | |
оу ах, 35091 ; = 351, АЁ = номер Прерывания.
т 24н тей ть адрес обработчика ТМТ 098
МОУ мог@ рег ^о19_111091,6х —; и поместить его в 019_1п09в.
во мог рег о19_1п11094+2,6°° ^^ у
воу .ах, 2520 . ; АН = 258, АЁ = номер прерывания.
ту ‘ @х, оРзет 11201. папёег : 0$:0Х - адрес нашего °
111 218 ..; обработчика.
[2 ах, 25091 ° ; АН= 258, (А = номер прерывания.
во\ Чх, оТТзет 1п509н_пап@1ег _; 05:0Х - адрес нашего `
т 21в ; обработчика.
тоу ап, 498 ‚у А = 49. `
МОУ е5, ога рёг епузе д _ ; Е$ = сегментный адрес среды 005.
тж 2 | ; Освободить память. |

оу ав, 9
ОУ вх, ответ улзта 14_ 050 ; Вывод строки` об успешной
1 21 ; инсталляции.

ОУ ах, оттзет чае ; ОХ - адрес первого байта за


` . .- ; койцом- резидентной части.
1 27 7..2 Завершить выполнение, оставшись’ —
| | ; резидентом. |
; Сюда передается управление, ‘если ‚наша: программа обнаружена в памяти.
а] геабу_10аде0: р, |
оу ай, -. р. = 091
МОУ 9х, от Гзет «гово. м вост сообщение об ошибке
471 218 | ..
гет | а. 2+ И Завершиться нормально.

‹ Сюда- передается управление, если все 255 функций мультиплексора заняты


; резидентными програимами.
по. тоге_мих:
оу ап,9
оу Зх, оРР5ет ‘по_тоге_тих_т59
111 218
гет в
ШЕРИИИИИИИНИНИИ |— Сложные приемы
; Текст; который. выдает:
программирования
программа при запуске;
иза9е : 10:46 2. АЗС 918р1ау апа. фприф ргодгат“.
г: 4.“
` р
\1.0”, 00, ОАК, .. .
95, ^АЗТ-А :
‚ т. активизация”
он, ,
ОА
% — "Стрелки - выбор символ0бн,
а",ОАН
аБ “Еег - ввод символа" ‚ОБН, одН
Ч “Езсаре - выход“ ООН,;ОАК
; Текст,; который. выдает программа,
«если она уже. загружена:
а] геаду_мз9 ;... ‚Ч: (1.
. "Ошибка: ‹программа уже заг
‚: Текст, котерый: выдает программа; ружена ОБН,",
ОАН, ' $.
„если. все функции мультиплексора
по_моге_мих_ 159 „96... заняты:.
“Ошибка; ‚ Слишком много резид
ентных программ”, .
о 6: ООВ, АВ,
; Текст’ который выдает программа "$ и
при успешной ‘установке:
11эта11е4_пз9 а |
“Программа ‘загружена В память", 00,
ОА}, $’
111 1а117е епдр
епд ЗТаге

ютерных игр, которые задействуют все


ресурсы компьютера по максимуму. Здес
резидентным программам приходится ь
размещать данные, а иногда и часть
в старших областях памяти, пользуяс кода
ь спецификациями НМА, ОМВ, ЕМ$
или

хваченные векторы прерываний, и нако


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

вектор прерывания не указывает на наш


обработчик, выгружать резидентную про-
грамму нельзя. Это всегда было глав
ным вопросом, и спецификации АМ
5 и1ВМ
в
соо ООО
проблемы. Если вектор прерывания не указывает на нас, имеет смысл проверить,
не указывает ли он на 15Р-блок (первые два байта должны быть ОЕВВЬ 10, а бай-
тыби7-КиВ), и, если это так, взять в качестве вектора значение из этого блока
ит. д. Кроме того, программы могут изменять порядок, в котором обработчики од-
_ ного и того же прерывания вызывают друг друга. _
_ Последний шаг в выгрузке программы - освобождение памяти — можно вы-
полнить вручную, вызывая функцию РО$ 498 на каждый блок памяти, который
программа выделяла через функцию 48}, на.блок с‘окружением РОЗ, если он не
освобождался при загрузке, и наконец, на саму программу. Однако есть способ
заставить 0О$ сделать все это (а также закрыть открытые файлы и вернуть код
возврата) автоматически, вызвав функцию 4СВ и объявив резидент текущим про-
цессом. Посмотрим, как это делается на примере резидентной программы, зани-
мающей много места в памяти. Кроме того, этот пример реализует все йриемы,
использующиеся для вызова функций 00$ из обработчиков аппаратных преры-
ваний, о которых рассказано в разделе 5.8.3.
; эсгагЬ. азт
; Резидентная программа, сохраняющая” изображение ' с’‘экрана в файл.
‚ Поддерживается только видеорежим 138 (320х200х256) и только. один’ файл.

‚ НГ: = - . : ,
; Нажатие А1т- 6 создает файл зсгдгь „Бяр в текущей директории с изображением,
‚; находившимся на экране в момент нажатия клавиши.
‚ Запуск с командной строкой ГА выгружает программу из памяти.

; АР:
; Программа занимает первую свободную. функцию прерывания 208. (кроме нуля)
; в соответствии со спецификацией АМТ 3.6.
; Поддерживаемые подфункции АМТЗ: бОЛ, .02н, озн, 048, 051.
: Все обработчики прерываний построены в соответствии с ТВ ТР.

; Резидентная часть занимает В памяти 1056 байт, если присутствует ЕМЗ,


; и 66 160 байт; если ЕМ5 не обнаружен: -

.тоде] т1пу
.с0де : `
. 186 . ; для слвигов и команд ризла/рора.
0г9 2св ол
епузед би 7... ; Сегментный адрес окружения.
ог9 801 ая .
стб_1еп 46 ‚3. с: блина командной строки.
стд`141пе 4 °_ : Командная. строка.
год. 1000 у `СОМ-программа.
таг: | й " Во Го
дир 11 1а112е° в Переход на ‚ инициализирующую часть.

; Обработчик. прерывания 09в (тол).

17о9н_напатег ргос | Таг


тр: —- зНоге асфиа1 1пе09п_вапа1ег - ; Пропустить: ТЗР.
|| Сложные приемы программирования
014. 311098 94 ?
дм 42481
46 сов
Эр ЗПОГЕ Ни_гезет
96° 7 дир (0)
астиа] _1п109и_Напа]ег: ; Начало собственно обработчика ТМТ 09н. ‹
рызпЁ о
са] дога рег с$:019 Чтт09в ; Сначала вызвать старый : !
. у ‚ обработчик, ‘чтобы он завершил аппаратное
; Прерывание и передал код в буфер.
ризпа | ` —. ; Это аппаратное прерывание - надо
„ризН 9$ ; сохранить все регистры.
„ ризв _ © -
ризн 00401
рор 98 у ; 0$ = сегментный адрес области данных ВТОб.
моу Ч1,мога рфг 43:001АВ ; Адрес головы буфера клавиатуры:
стр 91, могФ рег `45:001СВ ; Если он равен адресу хвоста, -..
де ех1{_О9в_папа1ег ; буфер пуст и нам делать нечего,
пои ^ "ах, мога рег [91] у ; Иначе: считать символ.
стр. ав, 221 ; Если это не. 6 (скан-код 228),
ле ех1+_О9В_папд1ег ` ; выйти. о
моу а1, Буте руг 95:0017Н ; Байт состояния клавиатуры.
Тезт а], 08Н ”, ; Если А1{ не нажата,
ру ех1{_О9Н_Пап1ег ; выйти.

мо мога рег 93:00168,91 ; Иначе: установить адреса головы и хвоста


. ; буфера равными, то есть опустошить его.
са11 о дгаб ; Подготовить ВМР-файл с изображением.°
оу Футе рёг с$:10_пеедей,1 ; Установить флаг |
| . ‚ требующейся записи на диск.
С] 1 .
са11 заРе_сНеск . ; Проверить, можно ли вызвать 005.
3с ех1{_О9Н_Папа1ег.
$11 . |
са11 90_10 | ; Если да - записать файл на диск.
ех11_О9Н_Папд]ег:
рор 2$
рор 9$ | ; Восстановить регистры
рора р
- 1гет ; и вернуться в прерванную программу.
1п1091_Пап@1]ег епар = 7
рм_гезет : гетЕ ..

; Обработчик ТМТ”08в `(1800)


ИиО8Н Пап ег рес Фаг | :
Этр ЭВогт астиа]_1п108Н_папд]ег ; Пропустить 15Р.
22
Резидеитные программы
014_1п108В 99 ?
9 424вВ
. 6 ов ,
зтр зВогт пи _гезет .
[*1°) 7 дур (0) , . .
астиа} 115081. Вапё1ег: .. ; бобственно обработчик.
ризпЕ '
са11 ФиогФ рег с$;014_1п1081. ; Сначала вызвать стандартный обработчик,
| ;. чтобы. он завершил аппаратное прерывание
; (пока оно не завершено, запись на диске невозможна)._
ризпа р
ризй 93 . .
с11 ; Между любой проверкой глобальной переменной и принятием‘
; решения по ее значению - не повторно входимая’ область,
. ° ; прерывания. должны быть запрещены.
стр Бу рёг с$:10_пеедев,0 р Проверить,
} по.10_пеедед о ; Нужно ли писать на диск.
са11 заРе_спеск ор Проверить, _
5’ '`- по 10 пеедед ` ^; ; можно.ли писать на диск.
511 . | ; Разрешить прерывания на. время записи.

са11 40_10 ``: Запись на диск.


по_1о_пеедед:
рор 93
рора
1гет
}1108п_пала]ег° епар_
; Обработчик ТМТ 131. ,
; Поддерживает флаг занятости 1МТ 131, который тоже надо проверять перед записью на диск.
11113/_пай@]ег ргос Таг
Эр ЗПогЕ асфиа1_1п113А._Вапд]ег ; Пропустить ТЗР.
014111131 94 ?
би 4248 '
-в5 о0в
р ЗПогЕ Пм_гезет
[*[ 7 Чир (0)
астиа1 Зи 13н_папё1ег: ; Собственно обработчик. `
„ ризвЕ
116 Буте рёг сз:5105..Бизу ; Увеличить счетчик занятости ТМТ 131.
С11 И -
са11 биога рег с3:019 1п13В
рызНЕ а о: `
дес Буре риг с3:610$_Бизу = ; Уменьшить счетчик.
рорЁ
гет 2 ; Имитация команды ТАЕТ, не восстанавливающая флаги из стека,
‚ Так как обработчик 1М№Т 13№ возвращает некоторые
: результаты в регистре флагов, а не в его копии,
; хранящейся в стеке. Он тоже завершается командой гет 2.
1п1131_Папд]ег епдр . т:
;

| Сложные приемы программирования


; Обработчик ТМТ 281.
; Вызывается 00$, когда она ожидает ввода с клавиатуры
‚ пользоваться. и функциями 00$ можно

111281 _Вала]ег = ргос Таг


тр
-
ПОГ асфиа] 11281 _Вапа1ег
019111281 ; Пропустить ТЗР.
39 _?
.^ Фи 424ВН
Ч. оон
тр
|
зом Ли_гезет
о 95 7 ар (0)
астиа] _1п128Н_Напа]ег:
ризВЕ
ризй 91
ризН 9$
ризп с3
рор 9$
с
стр Буте рг 10_пеедед, 0 ; Проверить,
]е по_10_пеедеЧ2 ‚ Нужно ли писать на диск
193 91, дога руг 1п_403_адаг
стр
| и
Буте рёг [91+1],1 ; Проверить,
фа по_10_пеедед2 ‚ Можно ли писать на диск (флаг
| ‚ занятости 00$ не должен быть
$ больше 1).
|
`са11 Ч99_10 —. ; Запись на диск.
по_10_пеедеа2:
рор 9$
`рор о 91.
рорг
тр Чмога ртг с3:014_1п+28н ; Переход на бтарый обработчик
1п1281_папод ег _епар ТМТ 281.

; Процедура ‘до_дгаь.
; Помещает в буфер палитру и содержимое видеопамяти, формируя ВМР-файл.
; Считает, что текущий видеорежим - 131.
Ч0_дгаб ргос `пеаг
ризН 6$
рор 9$ |

са11 ет$_ 1111 ; Отобразить


наш буфер в окно ЕМ$.
моу 9х, ога рег сз:БиЕРег_зед
тоу е$, Чх ; Поместить. сегмент с буфером
тому 4$, 9х в Еб и 0$
‚ т Аля следующих щагов процедуры.
моу ах, 1017Н . ; Функция 1017в - чтение палит
оу | фх, 0 ры `УбА
` ‚ Начиная с регистра палитры
моу СХ, 256 0.
о . ; Все 256 регистров.
моу 9х, ВМР_пеадег_1епдтп ; Начало ‘палитры в ВМР.
ИЕ о 10 ; Видеосервис ВТ0$.
Резидеитные программы
; Перевести палитру из формата, в котором ее показывает, функция 10778
; (три байта на цвет, `в` каждом байте‘6 значимых бит),
; в формат, используемый в ВМР-файлах
: (4 байта на цвет, в каждом байте 8 ‘значимых бит)
319 , Ю ; Движение
-от конца`к началу.
во 51, ВМР_Пеадег_1епдтп+256*3-1 ; ЭТ - конец З-байтной палитры.
‚ МОУ 91, ВМР_неадег_]епд11+256*4-1 ; ОТ - конец 4-байтной палитры.
- МОУ сх, 256 ; СХ - число цветов.
ад) ра]: моу а1,0 .
то$Ь , ; Записать четвертый байт (0).
10936 | ; Прочитать третий байт.
$1] а1,2 - ; Масштабировать до 8 бит.
ризй ах
10956 . . ; Прочитать второй байт.
$81 а1,2 . ; Масштабировать. до 8 бит.
ризй ах . .. -.
10955 ; Прочитать третий байт.
$1] а1,2 - =. | ,: Масштабировать.до 8 бит
$1055 ; и записать эти три байта
рор ах ` ; В обратном. порядке.
$1056 р й
рор ах
ЗТоЗЬ -
1о0ор ад} _ра1
; Копирование видеопамяти в ВМР. ,
; В формате ВМР строки изображения записываются’
от последней к первой, Так что
; первый байт соответствует нижнему левому пикселу. `
с14 ; Движение от начала к концу (по строке).
риузВ О0АОООН
рор 4$ . . |
оу $1,320*200 | _ ; 0$:5Т - начало последней строки ‘на экране.
поу 91, БРоР61т$ ; Е5:0Т - начало данных в ВМР.
поу . дх, 200 ; Счетчик строк. .
Бтр_мг1{е_1оор: | | .
‘ МОУ сх, 320/2 . ; Счетчик символов в строке.
гер МОУ$М . ; Копировать целыми словами, так быстрее.
$46 51,320*2 ; Перевести 5Т на начало предыдущей строки.
дес 9х ‚; Ууменьшить счетчик строк.
112 Бтр_мг1Те_1оор - .;’ Бели 0 - выйти из цикла.

са11 етз_гезет ‚ Восстановить состояние ЕМ$ до вызова 4о_дгаб.


гет |
Ч9о_дгаБ епар

; Процедура 9о_10. на .
; Создает файл и записывает в него: содержимое буфера.

0_10 ргос пеаг


ризн с$
рор 4$
Сложные приемы программирования `
моу Буре руг 10_пеедед, 0 ^ ; Сбросить флаг требующейся записи на диск.
са11 ет$_17п{ ; "Отобразить в. окно ЕМ$ наш буфер.
оу ав, всп ; Функция 00$ 6сн.
моу ьх, 2 ; Доступ - на чтение/запись.
оу сх, 0 ; Атрибуты - обычный файл.
моу 9х, 128 ° . ; Заменять файл, если он существует:
; создавать, если нет. |
МОУ - $1, ОЕРзеё Е11езрес ; 0$:5Т - имя файла.
17 211 ; Создать/открыть файл.
тоу Бх,ах . ; Идентификатор файла - в_ВХ.
тоу ай; 408 ; Функция 00$ 408. —
моу сх, 57$17е ; Размер ВМР-файла.
ЮУ 95; мога ртг БиЁРег.$е9
‚ МОУ дх, 0 . ; 0$:0Х - буфер для файла.
1 211 ; Запись в файл или устройство.
оу ‚ап, 68 | ; Сбросить буфера ‘на диск.
11 211 ,
А ан, ЗЕ ; Закрыть файл.
т. 211

са1] етз_гезе{

ге -
до_10 епар

; Процедура етз Лит.


; Если буфер расположен в ЕМ$, подготавливает его для чтения/записи.

етз_1111 ргос пеаг

стр. дх, мого рЕг етз_Вап@]е ; Если не используется ЕМ$


стр 9х,0_ _ _; (Е№З-идентификаторы начинаются с 1),
3е ° @тз_111* ех1т ; ничего не делать.

по\ ах, 4700н ^ ; Функция ЕМЗ 47:


17 671 ; сохранить ЕМ$-контекст..

тоу ах, 41008 ; Функция ЕМС дв:


т 671 ‚ определить адрес окна ЕМ$,
моу мог@ руг БиЁТег_зе9,
5х ; Сохранить его.

му ах, 44001 ; Функция ЕМЗ 448:


ое . 5х,0 ‚ Начиная со страницы 0,
17 б7Н ; отобразить страницы ЕМ$ в окно.
Мом ах, 44018 , :
1пс Ьх ,
1 671 ; Страница 1.
моу ах, 44021
пс Ьх
1пт 67н_ ; Страница 2.
мо\ ах, 44038 : .
46 5х
19% 67 _ | ; Страница 3;°.
ет$_ 1111 ех{т:
гет
ет$_111* ‘епар
; Процедура етз_гезет.
; Восстанавливает состояние Е№.
етз_гезее ‘ргос пеаг
тоу @х, чога рег с3: етз_ папо1е
стр 9х, 0 . ,
]е ет$_гезет_ех11 И

мои ах, 48001 се: ; Функция ЕМ$ 481:


101 б7н 2 °__ ; восстановить ЕМ5-контекст.
ет$_гезет ех11т: : ``
ге | о:
етз_гезет . епар | в
; Процедура заТе_спеск: | ., С
; Возвращает СЕ= 0, если в данный. момент. можно’ пользоваться функциями 005,
; ИСЕ = 1, если нельзя. ‘
заРе_спеск ргосе —. пваг
| ризв ез у
ризв с8
рор 93
1е5 81, Чнога `руг 1п_90$_а4аг ; Адрес флагов занятости 00$.
стр мог@ рег. ез:[91],0 ; Если один из них не 0. ` р +
`рор. 65$ :
пе заРе_спеск_Га{1еа ‚ пользоваться 00$ нельзя.
стр Буте рАг 6103_Бизу, 0 ; Если выполняется прерывание 131,
пе заГе_спаск_Га11еа _ ; тоже нельзя.
с1с | о и 4, СЕ =
гет |
заРе_спеск_Га1]ед: |
$1с р о; Е =1.
_ ге
заРе_спеск епдр

1п_908_а09г 94 ? ; Адрес флагов занятости 00$.


10_пеедед |. ООООИВИ: ЗОВ ира ; 1, если надо записать. файл на диск.
5105_Бизу 4 ’ 0 ; 1, ебли выполняется ‘прерывание ЛМТ 138.
„БигРег“ зе9 =. ди 0 - “го 2 ; Сегментный адреб` ‘буфера. для файла.
етз_Кап41е м о. ; Идентификатор -ЕМ$;
ЕПезрес Г‘) ' зсгогь. Бтр',0 ; Имя файла.
; Обработчик ТМТ 208 и
лм_гезет20 :ге
111201_пап@1ег ргос Таг
тр ЗЙОГЕ астиа1 11208 _папа]1ег ; Пропустить. Т5Р;.
\
| — Сложные приемы программирования
014_1п+208 ._ 94 ?
ди ` 42481
95 оов
тр ВОГ Нм_гезет20
_ 0 7 ашр (0) :
_ асфиа1 171208 _Вапа1ег: : ; Собственно обработчик.
| 5 808, ОРСК ; Начало команды `СМР` АН, число.
мих_19. Ге ? ; Идентификатор программы.
]е 13—48 ; Если вызывают с’чужим АН - это. не нас.
зтр' Омог9 рег с$:014 111208 . ` .
11843: | |
стр а1, 06 `_; Функции АМТ$ ОбН и выше
Уае 11120_по ; не поддерживаются.
сби .
; АХ. = номер функции.
моу 91,ах . ; ОТ = номер функции.
3181 91,1. ; х2, так как ]итреаБе - таблица слов.
. Эр могд рег сз: )итртаб1е[ 91] ; Переход на обработчик Функции.
Эотртае Зи ОРР5еф 11120_00, ответ 1п120_по
р 9 оЁР5ее 1112002, оРРзет 1п120_по
9 ОРРзеЕ 1п120_04, оРРзет.'1п1120_05
11120.00: “ ; Проверка. наличия.
моу а1, ОРЕВ ; Этот номер занят.
моу сх, 01008 ; Номер версии программы 1.0.
ризй [е-
рор 9х. | ; ОХ:0Т - адрес АМТ$-сигнатуры.
МОУ 91, оЁРзеф ат1$_$10п
1ге+
- 1120 _по: ; Неподдерживаемая. функция.
моу а1, бон ; Функция не поддерживается.
1ге+
ип1оад_а1]ед: ; Сюда передается управление, если хоть один из векторов
‚; прерываний был перехвачен кем-то после нас.
моу ат,ОВ ; Выгрузка программы не удалась.
1гет
11120_02: | ; Выгрузка программы из памяти.
но ; Критический участок.
ризН о. ‘т
рор 4$ — В ; 0$ - сегментный ‘адрес
| в й - | ; таблицы векторов прерываний.
тоу `вх,с5 ; Наш сегментный адрес.
; Проверить, все ‚ли перехваченные прерывания по- прежнему указывают на нас.
; Обычно достаточно проверить. только сегментные адреса (00$ не загрузит другую
‚; программу с нашим сегментным адресом).
стр ах, мога рег 4з:[091*4+2]
пе иупоад_Га11е4
стр ах, мога рег 98:[138*4+2]
дпе уп? оад_Газ]е9
стр ах, мог ртг 03:[088*4+2]
Резидентные программы; ......-..
зле ип1оа4д_Га11е4
Сар ах, мого ртг 9$3:[281*4+2]
‚ пе иуп10ад_Га11ед
стр ах, могд рег. 99:[208*4+2 ]
Зе ил1оад_Га11е9
ризй ьх. ; Адрес возврата - в стек.
ризй дх

; Восстановить старые обработчики прерываний.


_ МОУ ах, 2509
198 9х, дога ртг сз: 014 _1пе09н
.. ии 211
тоу ах, 25138 и
193 4х, диога руг с3:019_ 11138
п в ‘
‚ вом ах, 2508 В .
148. фх, Чиог@ рог с5:0149508Н :..
Чит 211 и. |
моу ах, 25281 ея .
19$ 9х, Чиога рег с3:019 1лЕа8В ,
уп 211 о
том ах, 25201 и
143 9х, биюга рег с3:019_111201
19 211 р

Мом 9х, мог@ рег сз:етз.ПепдТе; Если используется ЕМб.


стр 9х,0
}е по_етз_То_иппоок
тоу ах, 45001 ; Функция ЕМ$ 451:
1% 678 ; освободить выделенную память.
р -ЗПОГЕ 6т$_ иппоокед
по_етз_То_иппоок:
6тз_ипкоокей:

; Собственно выгрузка резидента, | ,


пом ап, 51. й ; Функция 005 518:
17 21н 1 ; получить сегментный адрес РЗР прерванного
; процесса (в данном случае Р5Р - копии
°; нашей программы, запущенной с ключом /и)..
моу мог@ рег .с3:[.168],
6х, ; Поместить его. в поле.
“сегментный адрес предка" в нашем Р5Р.
рор вх на ; Восстановить адрес возврата из стека
рор Ьх -
том. мог@ ртг..с$: [008], 9х _: и поместить ‘его `в поле
мо\ мог4 рег. сз: [ОАН],Бх “адрес перехода при
; завершении программы" в нашем РЭР. _,
ризп с$
рор ох ВХ = наш сегментный адрес РЭР.
ЮУ ав, 508 ; Функция 005 501:
1 211 ; установить текущий РР.
Сложные приемы программирования
Теперь 00$. считает наш резидент текущей программой, а зсгогь.сот /и - вызвавшим
‚ его процессом, которому и передаст управление после вызова следующей функции.
поу ах, СЕРА ; Функция 00$ 461:
1 21 ; завершить программу.
11120_04: - ; Получить список перехваченных _
‚. прерываний.
оу 9х, с5 ; Список в ОХ: ВХ.
МОУ Ьх, оЕР5е{ ат1$_Ноок11$1
1гет
11120_05: ^ | ; Получить список “горячих” клавиш.
моу а1, ОРЕВ : Функция поддерживается. р
тоу Ох, сз у Список в .ОХ:ВХ.
оу —. -Бх, оРРзет ат1з_поткеуз
ге
1п1201_Палд]ег епар

; АМТЗ: Сигнатура для’ резидентной программы.


ат1$_510п 95 "Сибьт...” ; -8 байт.
в “Эсгабгаь” - ; 8 байт. '
° "З1ир1е зсгееп дгабег иуз1пд ЕМЗ”,0
; АМ: Список перехваченных прерываний.
ай13_1оок1 151 [е] о9в
у дм ОТЁзет 1п109Н_папд]ег
46. овв
м ОРЕ5ет 1пт08Н_Вапо1ег
35 281
9 ОРР5ет 1п28Н_Наго1ег
Г] `20Н
би ОТР зет 1пт20н_папа?ег
; АМТ$: Список “горячих” клавим,
ат1$_ПотКеуз 5 1
дь 1
Ч 228 ; Скан-код клавиши (6).
[# [9 ; Требуемые флаги клавиатуры.
ам 0
Г’) 1
; Конец резядентной части.
; Начало процедуры мищиализации,
затчаН те ргос мваг.
тр ЗНОгФ 1111а112е_ептгу
ролпт ; Пропустить различные
‚ варианты выхода без установки резидента, помещенные здесь
`; Потому, что на них передают управление’ команды условного.
‚ Перехода, имеющие короткий радиус действия.

ех11_м1{Н_теззаде”
‚ МОУ ав, 9 - | ; Функция вывода строки на экран.
т 238. |
гех ° ; Выход из программы.
Резидемтные программы: `. аа

а]геаду_1оадед: - г. ‚ Если программа уже ‘загружена -В память.


сар. -^Буе рег итюоалб, 1 ; Если мы не были. вызваны с 2
3е 0_ип10оад - к:
ЮУ 9х, оГРзег а}геаду_т$9:.
)тр зпогЕ ех1{_м11И_меззаде’
по_моге_мих: ; Если свободный идентификатор ТМТ 201 не найден.
ту 9х, оГГэет по_тоге_мих_т39
„ Зтр зпогХ ех1{.
м1 _пеззаде

сап*_ип10а91; И : Если нельзя выгрузить программу. .


оу х, оРР5ет сапе_ип1оа41_
№39 |
тр” эВогГт ех1{.и1Тй_меззаде. й

до_ип1оад: ; Выгрузка резидента: при передаче управления сюда‘АН содержит


; идентификатор программы - 1. |
1пс ай т". :
оу а], о2н : ; АМГ5-функция выгрузки. резидента. -
тоу дх, с$ - ; Адрес возврата .
мо\ БхуоРГзет ех1“_розпх $; в 0х: ВХ. ° ,
11 20% : -.; Вызов нашего резидента через мультиплексор.

ризп с | | ; Если управление пришло сюда -.


; выгрузки не было.
рор 9$ `
оу 9х, оРГзет салт_ип10а42_п$9
` р ЗНогЕ ех1{ мА _теззаде
ех1{_ рот: ; Если управление пришло сюда - выгрузка произошла: _
ри сз |
рор 93
оу 9х, о7Рзет ип1оадед_м39 : |
рип 0 | .; Чтобы сработала команда ВЕТ для выхода.
}ир ЗпогЕ ех_мЕВ_пеззаде ° . И .
пииНаНе_ептгу_ро1пт: ° ; Сюда передается управление в самом начале’.
с16: : и

стр Буте руг ста_11пе[1],


'/*
пе пот_ип10а9
стр Буе рег сид 14пе[2], 'и’.; Если нас вызвали с/у,
пе пот_ип10оа9 : а и
воу Буфе рег. ип1оад1лу,1 ; выгрузить резидент.
пот_и11089: | | |
воу ` ав, 9 о. и
ОУ вх, оРРзеё изаде ... о о; Вывод. строки с информацией о программе.
10 218 В : т. |
МОУ ап, -1 . ; Сканирование от ЕЁЕй до 011..
моге_тих: Зы р
воу а], (ОН ; Функция АМТ$ 001 - проверка наличия
‚ резидента.
ШИ! Сложные приемы программирования
11. 208 ‚; Мультиплексорное прерывание.
стр а1, ов Если идентификатор свободен,
Зе. по{_Ргее›
моу Буфе рег мих_19,аН вписать его сразу в код обработчика.
тр пог пехе_мих
ПОЁ_Ггее:
поУ —^ е5, ах Иначе - ЕЗ:0Т = адрес АМТ5-сигнатуры
вызвавшей программы,
моу $1, ОРРзет ат1з_$10п 05:51 = адрес нашей сигнатуры.
мо\ сх,16 ; Сравнить первые 16 байт.
гере стрзь
7схг а]геаду_]оадед Если они не совпадают, .
пехт тих:
дес - ав ‚ перейти к следующему идентификатору.
12 тоге_мих Если это 0
Егее_мих_Роипа: :
стр Буте руг уптоад1ид,1 и если нас вызвали для выгрузки,
де сап_ип]оа91 а мы пришли сюда - программы нет
в` памяти. к
стр Буте рег тих_19,0 Если при этом тих_19 все еще 0,
]е по_тоге_тих идентификаторы кончились.
; Проверка наличия устройства ЕММХХХХО.
том 9х, оРРзет етз_дг1мег
МОУ . ах, 30001
11 214 ; Открыть файл/устройство.
3° по_‘елих
тоу Ьх,ах
том ах, 44001
11 218 ; ТОСТЬ: получить состояние файла/устройства.
с по_етз
Тез ах вон ; Если старший бит ОХ = 0, ЕММХХХХО - файл.
ру о_ 95 ,
; Выделить память под ‘буфер в ЕМ$.
по\ ах, 41008 | ‚ Функция ЕМЗ 41Н:
1 67Н получить адрес окна ЕМС,
моу 6р,5х ; Сохранить его пока в ВР.
моу ах, 43001
Функция ЕМЗ_43В: ^
моу ьх,4 ; Нам надо 4 х 16 Кб.
1 67Н Выделить ЕМЗ-память . (идентификатор в 0Х).
стр ав,0 Если произошла ошибка {нехватка памяти?),
912 етз_Га11ед ` не будем пользоваться ЕМб.
моу мог рег етз_папд]е,ах Иначе: сохранить идентификатор
; для резидента.
моу ах, 44008 ; Функция 441 - отобразить
ЕМ$-страницы в окно.
моу ьх,0
17 671 ; Страница 0.
моу ах, 44011 `
Резидентные программы
1пс Ьх
10. 671 ; Страница 1..
то ах, 44025
1пс Ьх
11 67н ; Страница 2. `#
моу ах, 44038 . `
116 5х |
1% 671. . ; Страница 3.
моу ав,9
мо Чх, оРзет етз_мз9; Вывести сообщение об установке в ЕМЗ.
11° 21и | у

оу ах,Бр
Этр ЗПогЕ етз_изед

етз_Га11е9: .
по_емз: | ; Если ЕМб нет или он не работает,
моу ав, ЗЕВ ` -. ‘ °
17 218 . -; Закрыть файл/устройство ЕММХХХХО.
по_еттх: °
; Занять общую память.
моу ав, 9 | :
тоу ° ах, оРРзет сопи_мзд ; Вывод сообщения об этом.›
1% 218

тоу зр, 1епотп_оТ.ргодгат+100Н+2001 ; Перенести стек.

поу ав, 4АВ ; Функция 00$ 4АП.


пех{_зедтеп{ = 1епд\П_оР_ргодгам+1001+2001+0Р1
пехЕ_зедтепт =. пех _зедтепт/16 ; Такая запись нужна только для
| ; МАЗМ, остальным ассемблерам это
; можно было записать в одну строчку.
му Ьх, пех{_зедтепт ; Уменьшить занятую память, оставив
; текущую длину нашей программы +1000
; на РЭР +2001 на стек.
11 218

мо\ ай, 481 ; Функция 481 .- выделить память.


Ь1517е_р = 61$12е+0РА
61$17е_р = БЕз1хе_р/16 `. | ,
моу Ьх, 61317е_р ; Размер ВМР-файла 320х200х256 в_16-байтных
11 211 ; параграфах.

етз_изед:
моу могд руг БиРГег_зед,ах ; Сохранить адрес буфера для резидента.

; Скопировать заголовок ВМР-файла в начало буфера. |


поу сх, ВМР_Пеадег_1епд{п
моу $1, ОЕЕзет ВМР_Пеадег
тоу 31,0
мо ез, ах
гер моу$6
ИТИИШИШИИИИИ | — Сложные приемы программирования
; Получить адреса флага занятости 003 и флага критической ошибки
‚ (считая, что версия 008 старше 3.0).
- оу ап, 348 ‚ Функция 34 - получить флаг занятости,
11 211 1

дес 5х ; Уменьшить адрес на 1, чтобы он указывал


‚ на флаг критической ошибки,
МОУ ога рег 1п_903_аадг,5х
моу мога рег. 11_90$_а007+2,ез; и сохранить его для резидента.
‚ Перехват прерываний.
оу ах, 35201 ;' АН = 351, АЁ = номер прерывания.
11 211 , Получить адрес обработчика ТАТ 20н
том мога рег 014_1п1201,6х , и поместить его в 014_1п1208.
мо мога ртг 014_1п11201+2,е$
ОУ ах, 35281 АН = 351, АС = номер ‘прерывания.
111 211 Получить адрес обработчика 1МТ 28Н
том. мога рег 019 _1п1281,5х и поместить:
его. в 019_1п128В,
оу мога ртг 0149_111281+2,е5
тоу ах, 35081 АН = 351, АЁ = номер прерывания.
‚1 211 Получить адрес обработчика ТМТ 081
1 мога руг 019 _1п108В,5х и поместить его в 0149114081.
тоу мога рег 019_111081+2,ез
тмо\ ах, 35131 АН = 358, А. = номер прерывания,
пт 218 Получить адрес обработчика ТМТ 131
оу мога ртг 019_1п13н,6х и поместить его в 019 11138.
тоу мог рег 014_111131+2,ез
том, ах, 35098 АН = 358, АЁ =; номер прерывания.
11 21Н Получить адрес обработчика ТМТ 09н
ПОМ. мога ре 014_1п5098,Бх и поместить его в 014911098.
оу мога рфг 019_111091+2,ез

тмоу ах, 25208 АН = 251, А. = номер прерывания.


оу ах, оРРзет 111201_папа]ег 05:0Х - адрес обработчика.
11 211 Установить новый обработчик ТМТ 208.
тоу ах, 25281 АН = 251, АЁ = номер прерывания.
тоу 9х, оЕРзет 11128В_Папа]ег 05:0Х - адрес обработчика.
177 РА! Установить новый обработчик ТМТ 281.
оу `ах, 25088 АН = 251, А]. = номер прерывания.
по\у 9х, оРРзет 11108 _Папа1ег 05:0Х - адрес обработчика:
1 218, Установить новый. обработчик ТМТ 081.
моу ах, 25131 АН = 251, АЁ = номер прерывания.
оу 9х, оРРзет НУЗВ_вапа1ег 05:0Х - адрес обработчика.
111 21н Установить новый дбработчик ТМТ 131.
тоу ах, 25091 АН = 251, АЁ = номер прерывания. .
Де Чх, оР5ет 1п1091_Папд1ег 05:0Х - адрес обработчика. |
11 211 Установить новый обработчик ТМТ 09Н.
; Освободить память из-под окружения 00$.
поу ап, 498 Функция 00$ 491.
тоу ез, мог рфг епузед Е$ = сегментный адрес окружения 006.
111 218. Освободить память.
| Резидентные программы
; ‚Оставить программу резидентной.
моу дх, ОРТ зет 1п111а112е ° : 0Х - адрес первого „байта за концом
. . ‚ резидентной части.
Ра 271 ` ; Завершить выполнение, оставшись
‚ резидентом. `
11 а112е епар |
етз_@г1уег 5 ' ЕММХХХХО" ‚0 ; Имя ЕМ5-драйвера для проверки.

; Текст, который выдает программа при запуске:


иузаде [ 'Простая ‘программа для копирования экрана только из’
Ч ` ' видеорежима 138’, ООп, ОА
95 '’.АК-6 - записать копию экрана в эсгодгь. Бр”
[ее 00в, ОАВ
96 ’ эсгогб.сом /и.- выгрузиться из памяти’, Об, ОАВ
[#9 ‚$
‚ Тексты, которые выдает программа при успешном выполнении:
етз_т$9 ЧЬ 'Загружена в ЕМЗ’, ОБА, ОА®, '$'
сопу_т$0 . [ео 'Не загружена в ЕМ5’, ООН, ОАН, '$"
уп10а4е9_т$9 Ге] ° 'Программа успешно выгружена из памяти’, ООВ, ОА, '$'
; Тексты, которые выдает программа‘ при - ошибках:
а} геаду_т$9 ЧБ ‚Ошибка: Программа уже загружена’ ‚ООВ, ОА, ' $*
по_тоге_мих_
м9 46 'Ошибка: Слишком ‘много резидентных программ’
в 00, Ан, ' $
сап{т_ип]о0а91_м$9 45 Ошибка: Программа не. обнаружена в памяти’, ООВ, ОАН, ’$’
сапт_ип10а92.т$9 96 ’Ошибка: Другая программа перехватила прерывания’
Ч Он, ОАВ, '$*
уп]0а91п9 6 0 ; 1, если нас запустили с ключом /ц

: ВМР-файл (для изображения 320х200х256)


ВМР_Пеадег ‚ 1а6е1 руте
; Файловый заголовок. ._
ВМР_#11]е_Неадег 96 “ВМ” | ; Сигнатура.
99 Ь1512е ; Размер файла.
[6 0,0 , 0
04 РОТ *; Адрес начала ВМР дата,
; Информационный заголовок
ВМР_1пРо_Пеадег 94 61_$12е ; Размер ВМР_1пРо_пеадег.
: 99 320 | ; Ширина.
99 200 ; Высота.
[6] 1 - ; Число цветовых плоскостей.
9 8 , ; Число битов на пиксел.
94 0 ; Метод сжатия данных.
99 320*200 и ; Размер данных.
94 ОВ13А : Разрешение по Х (пиксел на метр).
39 ОВ13В | ‚ Разрешение по У (пиксел на метр).
94 0 ; Число используемых цветов (0 - все).
| 94 0 ; Число важных цветов (0 - все).
61_517е = $-ВМР_1пР0_пеадег ; Размер ВМР_1пРо_Пеадег.
ВМР_Пеадег_}епоти = $-ВМР_пеадег ‚ Размер обоих. заголовков.
БРОТЕЬ143 = $-ВМР_[1]е_пеа4ег+256*4 : Размер заголовков +! размер палитры.
ЕЕРИШШИШИШНИИИ! Сложные приемы программирования
Ь1312е = $-ВМР_Р11е_пеадег+256*4+320*200 : Размер заголовков + .
| ‚ размер палитры + размер: данных.
1ТепдтИ_оР_ргодгат = $-зтаге -.
епа ЗТагт

В этом примере, достаточно сложном из-за необходимости избегать всех слу-


чаев повторного вызова прерываний РОЗ и ВТО$, добавилась еще одна мера пре-
досторожности - сохранение состояния ЕМ$-памяти перед работой с ней и вос-
становление в исходное состояние. Действительно, если наш резидент
активизируется в тот момент, когда какая-то программа работает с ЕМ$, и не
выполнит это требование, программа будет читать/писать уже не в свои ЕМ$-
страницы, а в наши. Аналогичные предосторожности следует предпринимать вся-
кий раз, когда вызываются функции, затрагивающие какие-нибудь глобальные
структуры данных. Например: функции поиска файлов используют буфер ОТА,
адрес которого надо сохранить (функция 2О$ 2ЕЬ), затем создать собственный _
(функция РОЗ 1АВ) и в конце восстановить ОТА прерванного процесса по со-
храненному адресу (функция 1АВ). Таким образом. надо сохранять/восстанавли-
вать состояние адресной линии А20 (функции ХМ$ 07Ь и 035), если резидентная
программа хранит часть своих данных или кода в области НМА, сохранять состоя-
ние драйвера мыши (ГУТ 33}, функции 16 и 17), сохранять информацию о пос-
ледней ошибке РО$ (функции РО$ 598 и 5Р0АЪ), и так с каждым ресурсом,
который затрагивает резидентная программа.
Писать полноценные резидентные программы в ОО$З очень сложно, но, если
не выходить за рамки реального режима, это самое эффективное средство управ-
ления системой и реализации всего, что только можно сделать в 2О$5.
5.9.4. Полурезидентные программы |
Полурезидентные программы - это программы, которые загружают и выпол-
няют другую программу, оставаясь при этом в памяти, а затем, после того как за-
груженная программа заканчивается, они тоже заканчиваются обычным образом.
Полурезидентная программа может содержать обработчики прерываний, которые
будут действовать все время, пока работает загруженная из-под нее обычная про-
грамма. Так что, с точки зрения этой дочерней программы, полурезидентная про-
грамма функционирует как обычная резидентная. Эти программы удобно исполь-
`зовать для внесения изменений и дополнений в существующие программы, если
нельзя внести исправления прямо в их исполняемый код. Так создаются загруз-
чики для игр, которые хранят свой код в зашифрованном или упакованном виде.
Такой загрузчик может отслеживать определенные комбинации. клавиш и об-
манывать игру, добавляя игроку те или иные ресурсы, или, например, находить
код проверки пароля и выключать его. й
В качестве примера напишем простой загрузчик для игры «Те ЕеЩет», кото- .
рый устранит ввод пароля, требующийся при каждом запуске игры. Разумеется,
это условный пример, поскольку игра никак не шифрует свои файлы, и того же
эффекта можно было достигнуть, изменив всего два байта в файле #опф.оу1. Един-
ственное преимущество нашего загрузчика будет заключаться в том, что он под-
ходит для всех версий игры (от Х-УЙп& до Пе Е1Мег: Оеепдег оЁ Ве Етшрие).
Резидентные программы | 1:1 12931
; {1е1юад. азт
_; Пример полурезидентной программы - загрузчик, устраняющий проверку пароля
. для игр компании Тисазагтз;
; Х-\4па, .Х-М1пд: Ттрег1а1 Ригзи1{, В-М№19, |
; Т1е Ромбег, Т1е Рлойтег: ОеРепдег от 1пе Етртге

.поде] 11пу
.соде
. 386 ; Для команды 15$.
0г9 1008 ; СОМ-программа.
эТагт:
:; Освободить память после конца программы (+ стек).
моу зр, 1епа1И_оР_ргодгам ; Перенести стек,
Мом ай, 4АВ ; Функция 00$ 4АВ.
° МОУ Ьх, раг_1епдти ; Размер в параграфах.
11% 21п . ; Изменить размер ‘выделенной памяти.

; Заполнить поля ЕРВ, содержащие `сегментные адреса.


‹ _ по\ ах, с ь
| мо\ мог@ руг ЕРВ+4,ах
моу мог ртг ЕРВ+8, ах
моу мог руг ЕРВ+0СП, ах. |

; Загрузить программу без. выполнения.


моу Ьх, оЕЕзет ЕРВ _. ; Е3:ВХ - ЕРВ
мо дх, о зет Р11епаще1 ; 09:0Х = имя файла (ТТЕ.ЕХЕ).
поу ах, 4ВО1П ; Функция 00$ 4В01А.
1 21 ; Загрузить без выполнения.
тс ргодгат_10оадед : ; Если ТТЕ.ЕХЕ не найден,
пом буте руг ХиТКе,1 ‚ установить флаг для Е1п9 _раззиа
по\ ах, 48018 |
му 9х; оЕЁЕзет Г11епаме2 ; и попробовать ВМТ№ .ЕХЕ.
111 ав : |
9 пс ргодгат_]оадед ; Если он не. найден,
то ах, 48011 |
мо 9х, оРРзет Г1епате3 ‚ попробовать ХИТМЕ. ЕХЕ.
1 218 | |
3с еггог_ех11т ; Если и он не найден (или не загружается
: по какой-нибудь другой причине) -
; выйти с сообщением об ошибке.

ргодгат_ 1оадед:
; Процедура проверки пароля не находится непосредственно в исполняемом файле
; 1е.ехе, 6м1пд.ехе или хи1пд.ехе, а, подгружается позже из оверлея гопт. 0\1,
. БЕгоп®.о\1 или Ргоптепа, оу] соответственно. Найти команды, выполняющие чтение
; из этого оверлея, и установить на них наш обработчик #1п4_раз$м4. ,
с19
ризй 65 \
рор ах
а69 ах, раг_1епотп
МОУ 4$,ах
ВУЗЕ ИИ! — Сложные приемы программирования
хог $1, $1 ; 05:51 - первый параграф после конца нашей программы
; (то есть начало области, в котор
ую была загружена
. ‚ модифицируемая программа).
моу .
91, оЕРзет геаЧ_111е_соде : ЕЗ:ОТ
- код для сравнения.
оу сх, г соде_1 ; СХ - его длина.
са11 119317119 ‚ ; Поиск кода.
с еггог_ех1{2 ; Если он не найден - выйти
. ; С сообщением об ошибке.
‚ Заменить 6 байт из найденного кода
командами са11 1119 разм и пор.
тоу Бубе руг [51], ЗАВ’ ; САЦЕ (дальний).
пом мога ртг [31+1], оРРсет 1119 _раззм
а
Ве могд ртг [31+3], с$ _^
тоу Буте руг [$1+5], 90, ; МР.
; Запустить загруженную программу.
; Надо записать правильные начальные
значения в регистры для ЕХЕ-программы
; и заполнить некоторые поля ее РУР.
_ МОУ ай, 518 ‚ Функция 00$ 51Н.
11 218 ; ВХ = Р9УР-сегмент загруженной прогр
моу 9$, 6х аммы.
; Поместить его в 05
моу ез, 6х ги ЕЗ. Заполнить также поля Р$Р:
оу мог рег 03: [ОАН], оРРзет ех11_мА По 30 `
му \ога ‘рег 93: [ОСН],с5 ; “адрес: возврата"
том. мог рег 93:[161],сз ‚И "адрес РЗР предка”.
]38 эр, Чмога рег с$:ЕРВ_$55Р ; Загрузить $$:5Р
тр @мог4 ртг. сз: ЕРВ_С$ТР ‚ И передать управление на
; Точку входа программы.
ХиТЮ6 9 0 ‚ 1/0: тип защиты Х-и1пд/Т1е-Е1оптег
ЕРВ дм 0. ; Запускаемый файл получает среду 00$ от
; Не]оад. сом,
[в] 00801,27. : и командную строку,
Чи 005С1,? ; и первый ЕСВ,
[А 006С1,? ; и второй ЕСВ.
ЕРВ_$$5Р .
94 7? -.;: Начальный 5$:5р - заполняется:
ЕРВ_С$ТР 00$.
: 99 ? °; Начальный С$:1Р - заполняется 00$.
11епате1 . ЧБ "Е1е.ехе", 0 ; Сначала пробуем запустить этот
РП епате2. файл,
9’ "Би1по.ехе”, 0 ; потом этот, :
71 1епате3 6 "хи1лд. ехе",0 —; а затем этот,
-; Сообщения об ошибках. |
еггог_тз9 [о “Ошибка: не найден ни один из ‘файло
в ТТЕ. ЕХЕ,
96 “ВИТАС. ЕХЁ, ХИТМ ЕХЕ", С.
ООН, ОАН, ' $’
еггог 1592 [6] “Ошибка: участок кода не найден
об",
“,ОАН, '$’
‚ Команды, выполняющие чтение оверлейного файла в {1е.ехе/Би1пд. ехе/хи1пд. ехе:
геад_111е_соде:
|
ЧБ ЗЗН, 0021 ‚ Хог. ах,9х
6 ` 0841, ЗВ ‚ Моу ап, ЗЕ!
96 осов, 218 ; 10 218
Резидентные программы _ 1:(| | 295 69%
5 728 ; 2
. ; (на разный адрес в Хм119 и {1е)
ГЕсоде_1 = $-геад_111е_соде
Команды, вызывающие процедуру проверки пароля. ,
набор команд встречается и в других местах, поэтому {1пд_раз3м9
; Аналогичный
; будет выполнять дополнительные проверки.
раззм9_соде:
96 891, 461, ОРСВ ; моу [6р-4],ах
95 891, 561, ОРЕЙ $ тому [6р-2], 4х
95 521 ; ризй ах
95 _ 50 | . ризН ах
|] ЭАП °_; са] Фаг
раззи4_1 = $-разема_соде
еггог_ех1*: .
тому ах, отГзет еггог_ 159 ; Вывод сообщения об ошибке 1.
Этр ЗВогЕ мАТП_
ех11 _м59
еггог_ех112: ,
том 9х, оРРзет еггог_м92 ; Вывод сообщения об ошибке 2.
ех1{_и1И_м50: |
моу ав, 9 ; Функция 003 091;
111 21 ; вывести строку на экран.
ех11_э1ТВоит_пз9; .. : Сюда также передается управление после
; завершения загруженной программы (этот адрес был
. . вписан в поле РЗР “адрес возврата”)
моу ап, 4Св ; Функция 00$ 4СП:
17 241 ; конец. программы.

вызывает программа 1е. ехе/5м1п9.ехе/хи119.ехе каждый раз, когда


; Эту процедуру
. она выполняет чтение,из оверлейного файла.
Е119_разз\а ’ргос фаг
: Выполнить три команды, которые мы заменили на са11 Е1п9д_раззма.
хог ах,9х
моу ав, ЗЕ . Функция 005 ЗРИ:
111 21и ; чтение из файла или устройства.

; По этому адресу мы запишем код команды ВЕТЕ,


деаст1уа{1оп_ро1пт:
| ;. когда наша задача будет выполнена.
ризйР ; Сохраним флаги
ризв 9$ ; и регистры.
ризп е5
ризпа
ризП 63
рор _ез .
$1, 9х ‚ 0$:0Х - начало только что прочитанного участка
моу
‚ оверлейного файла. .
моу 91, О(Рзе{ раззмЧ_соде ‚ ЕЗ:0Т - код для сравнения.
дес $1 . Очень скоро мы его увеличим обратно.
‚ В этом цикле найденные вхождения эталонного кода
зеагсн_Фог_рма:
; проверяются на точное соответствие коду проверки
; пароля.
29611 |] 111 Сложные приемы программирования
тс $1 Процедура Р1п9_.31г1п9 возвращает 05-51
указывающим на начало найденного кода - чтобы
искать дальше, надо увеличить 51 хотя бы на 1.
поу сх, разм_1 ; Длина эталонного кода.
са11 Е1п9_$1г1п9 Поиск его в памяти.
9с р\уЧ_пот_Роцпа Если он не найден - выйти.
‚ [119 _$1г1п9 нашла ‘очередное вхождение нашего эталонного. кода вызова
‚; процедуры - проверим, точно ли это вызов процедуры проверки’ пароля
стр руде рег [$1+10],001 ; Этот байт должен быть 00.
пе зеагсп_Фог_рмд
стр Бусе рег сз: Хиб, 1 ; В случае Х-и1па/В-м1пд
пе спеск_Рог_11е
стр мог рфг [$1+53], 07748 команда ]е должна быть здесь,
ле зеагсй_Фог_рмд
тр зпогЕ руд Роипа
спеск_Рог_11е: ‚ ав случае Т1е Радйтег -
стр мог рег [31+42], 07748 ; здесь.
пе зеагсй_Рог_рма
рид_ Роипа: ; Итак, вызов процедуры проверки пароля найден - отключить его
ем мюга рфг 93:[$1+8], 90901 ; МОР МОР
оу мог рфг 9$:[31+10], 90901 ; МОР МОР
ОУ Буте рег 93:[$1+12],
901 ‚; МР

‚ И дезактивизировать нашу процедуру 11п49_раз$ма.
Де Буте рфг с$:Чеас(1уат1оп_розпт,
ОСВн : ВЕТЕ

рмд. пот_Тоипд:
рора ; Восстановить регистры
рор
рор 45
рорЁ ; и флаги
ге ; и вернуть управление в программу.
{119 _раззма епар

‚ Процедура Г1п4_зтг1п9д.
: Выполняет поиск строки от заданного адреса до конца всей общей памяти.
; Вход: ЕЗ:0Т - адрес эталонной строки.
; СХ - ее длина
; 05:51 - адрес, с которого начинать поиск
; Выход: СЕ = 1 если строка не найдена,
‚ иначе: СЕ = би 1053:531 - адрес, с которого начинается найденная строка.

Е1п19_$1г119 ргос пеаг


ризв ах
ризй Ьх,
ризИ ах : Сохранить регистры.
90_стр: мо\ ах, 10008 ; Лоиск блоками по 10001 (4096 байт).
стр_1]оор:
ризй 91
рузв $1
рузв сх
Резидентные программы И: | 297
гере стрзБ | ; Сравнить 05:31 со строкой.
рор сх... , ‚ |
рор $1
рор 91 ,
3е _ Тоипа_соде | ; Если совпадение. - выйти с СЕ =
1пс $1 . : Иначе. - увеличить 05:5Т на 1,
дес 9х ; уменьшить счетчик в 0Х
пе стр_1оор ; и, если он не ноль, ‘продолжить.
‚ Пройден очередной 4-килобайтный блок.
816 34, 1000. _ ; Уменьшить 5Т на 10008
пом `ах, 4$
з 1пс ап :и увеличить 0$ на 1.
оу 93, ах ` . .
стр ах, 90008 . . . ; Если мы добрались до
у - до_стр ; сегментного. адреса 90000 -

рор: 9х : восстановить регистры.


рор х
рор ах .
- 81с ^ — ; Установить СЕ = 1
гет | ; И выйти.
Сюда передается управление, если строка найдена.
Тоипд_соде: й
рор 9х : ; Восстановить регистры.
рор.. Ьх
рор ах . `
с1с ; Установить СЕ =
гет ори выйти.°
Е1пд_51г1п9 епдр
еп4_от_ргодгам:
1епо1Н_оР_ргодгат = $-эТагт+1001+1008 ; Длина программы в байтах.
раг_1епдзн= 1епдН_о{_ргодгат + ОРВ .
раг_1епатн= раг_1епдти/16 р ; Длина программы в параграфах.
‚ епб этаге |

5.9.5. Взаимодействие между процессами


Даже несмотря на то, что ОО$ является однозадачной операционной системой,
в ней одновременно могут быть задействованы несколько процессов. Это означа-
ет, что сама система не предоставляет никаких специальных возможностей для их
одновременного выполнения, кроме возможности оставлять программы резиден-
тными в памяти. Следовательно, чтобы организовать общую память для несколь-
ких процессов, надо загрузить пассиЕную резидентную программу, которая будет
поддерживать функции выделения блока памяти (возвращающая идентифика-
тор), определения адреса блока (по его идентификатору). и освобождения блока —
приблизительно так же, как работают драйверы ЕМ5$ или ХМ5.
Чтобы реализовать многозадачность, придется запустить активную резидент-
ную программу, которая перехватит прерывание 1В.О0 и по каждому такту систем-
ного таймера будет по очереди отбирать управление от каждого из запущенных
2981 111111 Сложные приемы программирования
процессов и передавать следующему. Практически никто не реализует полно-
ценную многозадачность в 2О$, когда каждый процесс имеет собственную па-
мять и не может обращаться к памяти другого процесса, -- для этого существует
защищенный режим, но встречаются довольно простые реализации для облегчен-
ного варианта многозадачности - переключение нитей. |
Нить - это процесс, который использует тот же код и те же данные, что и ос-
тальные такие же процессы в системе, но отличается от них содержимым стека и ре-
гистров. Тогда резидентная программа (диспетчер) по каждому прерыванию
таймера будет сохранять регистры прерванной нити в ее структуру, считывать ре-
гистры следующей нити в очереди и возвращать управление, а структуры и стеки
всех нитей будут храниться в какой-нибудь специально выделенной общедоступной
области памяти. Указанная программа также должна поддерживать несколько вы-
зовов при помощи какого-нибудь программного прерывания - создание нити,
удаление нити и, например, передача управления следующей нити, пока текущая `
нить находится в состоянии ожидания.
Эта простота оборачивается сложностью написания самих нитей. Так как все
они используют общий код, абсолютно все в коде нити должно быть повторно
входимым. Кроме того, нити создают множество проблем, связанных с синхрони-
зацией, приводящих к тому, что либо в коде всех нитей, либо в основном резиден-
те придется реализовывать семафоры, очереди, сигналы, барьеры и все остальные
структуры, которые встречаются в реальных пакетах для работы с нитями.
Попробуем создать элементарный прототип такой многозадачности в РОЗ (все-
`то с двумя нитями) и посмотрим, со сколькими проблемами придется столкнуться.
зсгзуг. азм
‚ Пример простой задачи, реализующей нитевую многозадачность в 00$.
‚ Изображает на. экране две змейки, двигающиеся случайным образом,
; каждой из которых управляет своя нить.

‚ Передача управления между нитями не работает в окне 00$ (\М1п4омз 95).


‚09е]1 11пу
. соде
.386 — ; ГСЧ использует 32-битные регистры
ог9 1008 ; С0М-программа.
таг: .
тоу ах; 138 ; Видеорежим 1ЗН:
111 101 ‚ `320х200х256.

са11 1111 _{Игеад$ ; Инициализировать наш диспетчер.


‚ С этого места и до вызова зПи{Чомп_1Нгеа4$ исполняются две нити с одним и тем
; Же кодом и данными, но с разными регистрами и стеками
; (в реальной системе здесь был. бы вызов Фогк или аналогичной функции).

поу ьх, 1 .; Цвет (синий).


ризй Бр
то Бр, зр ‚ Поместить все локальные переменные в стек,
; чтобы обеспечить повторную входимость.
ризН 1 ; Добавка к Х на каждом шаге.
х_1пс еди мога рёг [6р-2]
Резидемтные программы: _ Г:
рузв 0 - 1 Добавка к У на каждом шаге.
у_1пс еди мога рг [6р-4]. .
ризй 128-4- ; Относительный адрес головы буфера 11пе_соогаз$.
соогаз_пеад еди мог@ рфг [6р-6]
ризв 0 _; Относительный адрес хвоста буфера 11пе_соогвз.
с00г43. а11 еди мога руг [6р-8]
зи зр, 64*2 ; Пле_соог4$ - кольцевой буфер координат точек.
‚ МОУ -91,зр
МОУ сх, 64 |
[А ах, 10 ; Заполнить его координатами (10, 10).
'ризй 9$
рор е5
гер т08м | :
11пе_с00гд$ еди могд руг. [6р-(64*2)-8]
ризВ 040008
рор ез ; Е - адрес видеопамяти.
ма1п_1оор: . ; Основной цикл.
са11 913р1ау_11пе ; Изобразить текущее состояние змейки.

; Изменить направление движения случайным образом.


ризп Ьх
поу еБх, 50 ; Вероятность смены направления 2/50.
са11 2_гапдот ; Получить случайное число от 0 до 49.
том ах, мога р{г х_1пс_ .
[1 Бх, мога ртг у_1пс
тет 9х, 9х ; Если это число - 0,
32 гот_г19йт _ ; повернем направо,
дес 9х | ‚ а если 1 -
917 ех1т_го{ - ‚ налево.
; Повороты
пед ах : налево на 90 градусов.
хсп9 ах, 6х ' $ би = -9Х, 9 =.
тр пог ех1{_гот.
гот г19т:.
пед Ьх | ; Направо на 90 градусов.
хспд ах, 6х | ‚ ЧУ = 9Х, А9Х = 9%.
ех1т_гот:
оу мога рег х_1пс,ах у ; Записать новые значения инкрементов.
по\ мога рег у_1пс,Бх
рор Ьх ; Восстановить цвет в ВХ.

; Перемещение змейки на одну позицию вперед.


МОУ 91, могд рег. соогаз_пеад ;: 01 - адрес головы.
е сх, ога руг 11пе_со0г4$[91] `^ ; СХ - строка.
оу Чх, мога рЁг 11пе_с00г9$[91+2] .; ОХ - столбец.
ада сх, мога рег у_1пс ; Добавить инкременты.
ад4 Чх,могЧ рег х_1пс
ада 91,4 ; ОТ - следующая точка в буфере.
апа 91, 127 ; Если ОТ > 128, ОТ = 01 - 128.
том мог руфг соогз_Пеад,41 ; Теперь голова здесь.
3001 11111 Сложные приемы программирования
поу мога рЕг ,11пе_с00га$[91],сх ! : Записать ее координаты.
му могЧ рЕг 11пе_с00га$[91+2],ах
том 91, мога рег с00г43_Та11 ; Прочитать адрес хвоста.
ад9 91,4 ; Переместить его на одну
апа 91, 127 _. ; позицию вперед ^
моу мога ртг соога$_та11,91 ; И записать на место.
‚ Пауза.
; Из-за особенностей нашего диспетчера (см. ниже) мы не
можем пользоваться
‚ Прерыванием ВТО$ для паузы, поэтому сделаем просто пустой
цикл. Длину ‚цикла
‚ Придется изменить в зависимости от скорости процессора:
ОУ сх, -1
1о0ор $ ; 65 535 команд ор,
МОУ сх, -1
1оор $.
вом сх, -1
Тоор $

мо ап, 1
.
17 161" ; Если ни одна из клавиш не была нажата,
ву па1п_1оор ‚ продолжить основной цикл.
МОУ ал, 0 . ; Иначе - прочитать ‘клавишу.
‘1пс - 6 .
1еауе ' ; Освободить стек от локальных переменных.
са11 Пит домп_ТИгеадз ; Выключить многозадачность.
; С этого момента у нас снова только один процесс.
оу ах, 3 ; Видеорежим 3:
п 108 . : . ; 80х24.
1щ 201 : ‚ Конец программы.
; Процедура вывода точки на экран в режиме 13Н.
; СХ = строка, 0Х = столбец, В: = цвет, Еб = 0А000Н
рифр1хе1 ргос пеаг
ризв. 91
]еа есх, [есх»*4+есх] ; СХ = строках 5.
$11 сх, 6 ; СХ = строка х 5х 64 = строках 320.
ада 9х, сх ; и строка х 320 + столбец
=>> =. адрес.
Це 91, 9х |
том а1, 6]
$036 ; Записать байт в видеопамять.
рор 91
гет
ритр1хе] епдр

; Процедура 91зр]ау_11пе.
; Выводит на экран нашу змейку по координатам из кольцевого буфера 11пе_соогаз,
915р1ау_11пе ргос пеаг
тоу 91, мог рег соогдз_+а11 ; Начать вывод с хвоста,
соп1пие_11пе _Ч1зр1ау:
стр 91, мог@ рёг соогаз реад ; Если 01 равен адресу головы,
3е 1пе_91зр1ауед ‚ вывод закончился.
Е
Резидентные программы . .

Иначе. = вывести точку на экран.


са1} 913р]ау_ро1п&
следующую точку.
‘ааа 91,4 . Установить ОТ:на
ата = 01,127
зпогЕ соп1лие_11пе_41зр1ау ; И так далее.
зтр.
11пе_91зр1ауед:
са11 91зр]ау_ро1пе
Вывести точку в хвосте
моу 61, мог руг соогаз_фа11
ризв Ьх
моу Ьх,0 ; нулевым цветом,

ба} 61зр1ау_ро1пт ‹ то есть стереть.

рор ьх
ге
91р1ау_111е ° епар

- Процедура 91зр1ау_ро1п®.
. Выводит точку из буфера 11пе_соог@з с индексом ОТ.
93 зрТау_ро1пе ргос пеаг
оу сх, мога рег 11пе_с00г93[91} : Строка.
оу вх, мога рАг 11пе_соог4з[91+2] ‚ Столбец.
са] 1 ритр1хе? ; Вывод точки.
гет
941$р1ау_ро1пт епдр

; Процедура 2_гапфот.
‹ Стандартный конгруэнтный генератор случайных чисел (неоптимизированный }
‚ Вход: ЕВХ - максимальное число.
:; Выход: ЕОХ - число от 0` до ЕВХ-1..
2_гапдом: .
ризй ебх
стр Буте рёг 2г_1п1*_11а9,0 Если еще не вызывали,
де гп инициализироваться.
‚; Иначе - умножить предыдущее
поу еах,гг_ргеу_гапа
ГСО:
и] гп _питбег на множитель
и разделить на делитель.
ФУ - гПа путфег2
‚ Остаток от деления - новое число.
оу гг _ргем_гапа,
едх
рор е5х
тому еах, едх
хог едх, едх
ЧУ ебх Разделить его на максимальное
гет и вернуть остаток в ЕДХ.
тг ЗП:
ризй 00401 Инициализация генератора.
рор #5 ;. 00408:006СВ -
мо\ еах, 5: [006С8] счетчик прерываний таймера ВТОЗ,
том 2г_ргем_гапд, еах он и’будет первым случайным числом.
тоу Буте раг 2г_1п_Р1а9,1
. тр 7г_сопт
гпд_питбег 399 16807 ; Множитель.
99 2147483647 ‚ Делитель.
гпд_путбег2
ЕСУЖИИИИИИИ | Сложные приемы программирования
2Г_1111_Е]ад [96] 0 ; Флаг инициализации генератора:
2г_ргеу_гапд 99 0 ; Предыдущее случайное число,
‚ Здесь начинается код диспетчера, обеспечивающего многозадачность.
‚ Структура данных, в которой мы храним регистры для каждой нити.
{Нгеад_з1гис зтгис
_ах 9 ?
6х — Чи ?
_сх Чи ?
_ах ом ?
_81 дм . 7
_91 [в ?
_бр м ?
вр ет ?
Тр Чи ?
_Е1а9$ Чи ?
{Нгеаа_эгис еп43
; Процедура 111 _{Агеадз,
; Инициализирует обработчик прерывания О8Н и заполняет структуры, описывающие
‚ обе нити,
11 _1Нгеадз ргос пеаг
ризНР
ризра
ризН е$ :
моу ах, 35081 . ; АН = 351, АЁ = номер прерывания.
11 211 ; Определить адрес обработчика.
оу мога рег 014_1п108В,6х ‚ Сохранить его.
то могЧ рег 014_1п11081+2,ез
оу ах, 2508 В ‚ АН = 251, АЁ = номер прерывания.
тоу 9х, оРРзеЕ 1пт08н_вапа1ег ‚ Установить наш.
111 ` 211 .
рор ез
рора ; Теперь регистры те же, что и при вызове процедуры
рорР
р
мо {Пгеад1.._ах, ах ; Заполнить структуры
тоу {Пгеад2. _ах, ах ‚ ТАгеад1 и ТПгеад2,
моу {Пгеад1. _Бх, Бх ‚ В которых хранится содержимое
оу {пгеад2. _6х, Бх ‚ всех регистров (кроме сегментных -
пом Твгеад1. _сх, сх . ‚ ОНИ в этом примере не изменяются)
оу ТИгеад2.
_сх, сх
моу ’ Нгеад1.
_ах, дх
по — 1лгеад2.
ах, 9х
моу {Пгеад1._31,$1
моу {Пгеад2. _$1, 31
оу {Нгеад1. _91, 91
моу {Нгеа42, 91,91
моу {Вгеад1. _6р, Бр
моу ЕНгеад2. _Бр, Бр.
й
Резидемтные программы:
пом ^ тпгеад1. _зр, ответ {Нгеад1. заск+512
поу {Пгеа92. -8р ответ +Нгеад2_5таск+512
рор ах . Адрес возврата (теперь стек пуст).
мо 1игеад1. _1р, ах |
моу ^ {Агеа92. _1р, ах
ризпЕ
рор ах ‚ Флаги.
моу 1Нгеад1. _1]а9$, ах
оу 1Нгеад2. _Ё]адз, ах
‘ ОУ зр, "Пгеад1. _$р ; Установить стек нити 1
Этр мог@ руг 1Игеад1. _1р , и передать ей управление.
111{_1Агеад$ епдр

сиггеп{_тАгеад 6 1 Номер: текущей нити.

: Обработчик прерывания ТМТОЗВ (1800)


; переключает нити
11%081_Папа1ег ргос Фаг
рузВР Сначала вызвать старый обработчик.
95 ЧАЙ Код команды са11 Фаг.
019 114081 . 99 0 . Адрес старого обработчика.
произошло ли прерывание в момент исполнения нашей. нити ИЛИ
; Определить,
: какого-то обработчика другого прерывания. Это важно, так как мы не собираемся
‚ возвращать’ управление чужой программе, по крайней мере сейчас.
; Вот почему нельзя пользоваться прерываниями для задержек в наших нитях
.; и программа не работает в окне 00$ (\1пд0\з 95).
воу заме_91, бр ;, Сохранить ВР.
МОУ _ Бр,р
риузв ах
ризй ьх
ризВР .
оу ах, мога ртг [5+2] Прочитать сегментную часть
. МОМ Ьх, с$ обратного адреса.
стр ах,5х Сравнить ее с 6$.
пе са11е9_Раг Если они не совпадают - выйти.
рорЁ
рор Ьх Иначе - восстановить регистры.

рор ах
моу Фр, зауе_491

оу заме_91,91 Сохранить ОТ, $1.


моу зауе_$1, 31
ризН ' и флаги..
; пределить, с какой нити на передать управление.
какую надо
стр Буте рфг сиггепт_<пгеаб,1; Если с первой,
.]е 1Пгеад1_То_1Игеа42 перейти на 1Вгеад1_{о_{Нгеад2.
поу Буе ртг сиггепт_{пгеад,1; , Если с 2 на 1, запивать в номер 1
моу $1, оРЕзет тПгеаа1 и установить ЗТ и ОТ,
моу 91, оРРзет {пгеад2 на соответствующие структуры.
тр ПогЕ огдег_зе1естед
304 ТОРТ Сложные приемы программир
ТВгеа91_то_{Вгеад2:
ования
; Если с 1 на 2,
мо уфе рег Сиггеп{_ТНгеаа, 2 ‚ записать в номер.
мо\у $1, оРРзе{т т1Пгеад? нити 2
` ‚ И установить ЗГТ и 01.
тому 91, оРЁзет {пгеаа1 ,
огаег_зе1естед:

‚ Записать все текущие


регистры в Структуру по
‚ И загрузить все регистры адресу [01]
из Структуры по адресу
‚ начать с ЗТи 01: [31].
п0У ах, [$1]._81 - ; Для МАЗМ все выражени
ризй зауе_$1 я [гед]. гед надо
‚ заменить (тВгеад_э+гис
рор [91]._$1 рег [гед]). _гед.
°
оу зауе_31,ах
моу ах, [31]. _91
ризН зауе_ 01
рор [91]. _91
оу зауе 41,.ах
; Теперь все основные регистры.
оу . [91._ах],ах
оу ах,[31._ах]
то , [91._6х],Ьх
том “6х, [31._5х].
тоу [91._сх], сх
том сх,[51._сх] ‹
моу [91._9х],ах
тому 4х, [$1._4х]
тому [91._6р], Бр
му Бр, [$1. Бр]
‚ Флаги... |
рор [91._11а9$]
риузН [$1._Е1а03]
рорР
‚ Адрес возврата.
рор ° [91.12] ‚ Адрес возврата из - стек
299. а. -
зр,4 . ; (Зи
; Переключить стеки. флаги из стека - теперь
он пуст.
Те [91._3р],зр
оу . 5р,[$1._5р]
ризН 131.12] ° ; Адрес возвратав отек’ (уже новы
поу — 91, за арг; й).
Загрузить ОТ и $1
то\ $1, за\уе. $1 —`
гетп р; И перейти по адресу в сте
; Управление переходит сюда,
ке..
если прерывание произошл
са]1е4_ Гат: о в чужом коде.
27
рорт В: Восстановить регистры
рор вх’
‘рор ах‘.
ей Бр, заме. 9:
1гет
.; И завершить обработчик,
111088 _ Вала] ег епар
.
Программирование на: уровне портов НАМИ НИЕТС
заме_41 9 9. т ; Переменные для временного хранения
заме_$1 ‘ [ 7 | ; ‘регистров.
; Процедура зпиу{домп_твгеадз.
; Выключает диспетчер.
зпитаомп_Нгеааз ргос пеаг
му ах, 2508 № °_; Достаточно просто восстановить прерывание.
_ 18$ х, нога рег 019_ оовв
и 211
гег
пит 9омп_1Агеад$ епдр

‚ Структура, описывающая первую. нить.


{пгеа@1 1Пгеад_${гис <>
: И вторую.
{пгеа42 Тигеад_зЕгис <>
‚ Стек первой нити.
{пгеад1_зтаск 65 512 дир(?)
; И второй.
ТНгеад2_этаск 96 512 9ир(?),
еп зат

Как мы видим, этот пример не. может работать. в УЙпдо\ 95 и в некоторых


других случаях, когда РО$ расширяют до более совершенной операционной сис-
темы. Фактически в этом примере мы именно этим и занимались — реализовыва-
ли фрагмент операционной системы, который отсутствует в РО5.
Действительно, применяя механизм обработчиков прерываний, можно создать
операционную систему для реального режима, аналогичную РО$З, но очень быст-
ро окажется, что для этого нужно общаться напрямую с аппаратным обеспечени-
ем компьютера, то есть использовать порты ввода-вывода.

5.10. Программирование
на уровне портов ввода-вывода
Как видно из предыдущей главы, использование системных функций РО5
и прерываний В1О$ может быть небезопасным из-за отсутствия в них повторной
входимости. Теперь самое время спуститься на следующий уровень и научиться
работе с устройствами компьютера напрямую, через порты ввода-вывода, как это
и делают системные функции. Кроме того, многие возможности компьютера мо-
гут быть реализованы только программированием на уровне портов.
5.10.1. Клавиатура
Контроллеру клавиатуры соответствуют порты с номерами от 60Ъ до 6ЕЪ, хотя
для всех стандартных операций достаточно портов 60 и 618.
64 для чтения — регистр состояния клавиатуры, возвращает следующий байт:
бит 7: ошибка четности при передаче данных с клавиатуры
бит 6: тайм-аут при приеме
бит 5: тайм-аут при передаче
ЕГТЗНШШИШИ ШИИШИ!! ‹ Сложные приемы программирования
бит 4: клавиатура закрыта ключом
бит 3: данные, записанные в регистр ввода, — команда
бит 2: самотестирование закончено
бит 1: в буфере ввода есть данные (для контроллера клавиатуры)
.
бит 0: в буфере вывода есть данные (для компьютера) |
При записи в этот порт он играет роль дополнительного регистра управл
ения
клавиатурой, но его команды сильно различаются для разных
плат и разных.
ВТО$З, и мы не будем его подробно рассматривать.
61Ё для чтения и записи - регистр управления клавиатурой.
Если в старший бит
этого порта записать значение 1, клавиатура будет заблокирован
а, если 0 —
разблокирована. Другие биты этого порта менять нельзя, так как
они управ-
ляют иными устройствами (в частности динамиком). Чтобы измени
ть состо-
яние клавиатуры, надо считать байт из порта, изменить бит 7 и снова
запи-
сать в порт 61Ь этот байт.
б0й для чтения - порт данных клавиатуры. При чтении из него
можно. получить
скан-код последней нажатой клавиши (см. приложение 1) -
именно так лучше
всего реализовывать резидентные программы, перехватывающие
прерывание
[801], потому что по этому коду можно определять момент нажати
я и отпус-
кания любой клавини, включая такие клавиши, как ЗЫ, СЫ1, А1ё
или даже
Раизе (скан-код отпускания клавиши равен скан-коду нажатия
плюс 801):
1пт09Н. Напа] ег:
1 - а1, 60 ; Прочитать скан-код клавиши.
стр а1, по{_кКеу ‚; Если это наша “горячая” клавиша,
ле ^ поф оиг_кеу `‚.Перейти к нашему обработчику.
. [..] °_; Наши действия здесь.
по{_оиг_Кеу: „7
„тр 014_1п09н ; Вызов старого. обработчика.
Мы пока не можем завершить обработчик просто командой 1ВЕТ,
потому что,
во-первых, обработчик аппаратного прерывания клавиатуры должен
установить
бит 7 порта 61Ъ, а затем вернуть его в исходное состояние, наприм
ер так:
11 а], 61Н
ризв ах.
ог а1, 801
: от 61Н,а1
рор ах
и 611,а1

Во-вторых, он должен сообщить контроллеру прерываний, что обработ


ка ап-
паратного прерывания закончилась командами |
по\ а1, 20Н
и 201,а1

‚ 60 для записи — регистр управления клавиатурой. Байт, записа


нный в.этот порт
(если бит 1 в порту 64В равен 0), интерпретируется как команда.
Некоторые
Программирование науровне портов || МНИНИИНЕТЯ,
команды состоят из более чем одного байта— тогда следует дождаться обну-
ления этого бита еще раз перед тем, как посылать следующий байт. Перечис-
лим наиболее стандартные команды.
Команда ОЕШВ 0? — изменить состояние <етодиодов клавиатуры. Второй байт
этой команды определяет новое состояние:
бит 0: состояние Зего| Г.осК (1 -— включена, 0 — выключена)
бит 1: состояние Мит ГосКк_
бит 2: состояние Сарз Г.осК
При этом состояние переключателей, которое хранитг 810$ в байтах состоя-
ния клавиатуры, не изменяется, и при первой возможности обработчик прерыва-
ния клавиатуры В1О5 восстановит состояние светодиодов.
Команда ОЕЕЁ - эхо-запрос: Клавиатура отвечает скан-кодом ОЕЕВ.
Команда ОЕЗВ 221 - установить параметры режима автоповтора:
бит 7 второго байта команды: 0 — |
биты 6-5: устанавливают паузу перед началом автоповтора:
00Ъ= 2505, 01Ъ= 500тз, 10Ъ= 7501з, 11Ъ = 1000$
биты 4-0: устанавливают скорость автоповтора (символов в секунду):
00000Ъ= 30,0 011116=8,0
00010Ъ- 24,0 10010= 6,0
00100Ъ = 20,0 10100Ъ = 5,0
00111Ъ = 16,0 101116 =4,0
‚ 01000Ъ = 15,0 11010Ъ= 3,0
-01010Ъ = 12,0 11111Ъ= 2,0
01100 = 10,0
Все промежуточные значения также имеют смысл и соответствуют промежу-
точным скоростям, например 00001Ъ= 26,7.
Команда ОЕ4В — включить клавиатуру.
Команда ОЕЗй — выключить клавиатуру.
Команда ОЕБЙ - установить параметры по умолчанию.
Команда ОЕЕЙ — послать последний скан-код еще раз.
Команда ОЕЕЁ — выполнить самотестирование.
Клавиатура отвечает на все команды, кроме'0ЕЕВ и ОЕЕВ, скан-кодом ОЕАВ
(подтверждение), который поглощается стандартным обработчиком ВТО$, поэто-
му, если мы не замещаем его полностью, об обработке ОРАВ можно не беспокоиться.
В качестве примера работы с клавиатурой напрямую рассмотрим простую про-
грамму, выполняющую переключёние светодиодов.
; М19.азт
; Циклически переключает светодиоды клавиатуры.

.Поде1 —11пу
.соде
ога 1008 ` ; СОМ-программа.`
ЕСЕУШИ
ШИ ВИНИШИ! — Сложные приемы программирования
эфаге „ргос пеаг и
МОУ ай, 2 ; Функция 02 прерывания Ап:
Чи ТАН” . ‚; получить текущее время.
моу сп, ЧА‘ ; Сохранить текущую секунду в. СН.
ОУ с1, 01006. ‚ СЁ= состояние светодиодов клавиатуры:

ма] п_1оор: .
` са11 спапде_(Е0$ ; Установить светодиоды в ‘соответствии с С.
$11 с1,1 ; Следующий светодиод.
тет с1, 1000 ‚ Если единица вышла в бит 3,
вр соп1пие | |
мо\ с1, 0001Ь ‚ вернуть ее в бит 0.
сопе1пие: . | | .
пом: ав, 1 ‚ Проверить, не была ли нажата клавиша. `
111 161 , |
912 ех1+_10ор ‚ Если да - выйти из программы.|
рузН сх ` ` :
оу ав, 2 ; Функция 02 прерывания: ЛАП.
11 ТАП ; Получить. текущее. время.
рор сх _ . : .
ср сп, ЧА ; Сравнить текущую секунду в ОН с СН.
пом СН, дп Сы ; Скопировать ее в любом случае.
]е ‚ сопЕ1лие ; Если это была та же самая секунда -
| ; не переключать светодиоды. |
Эр зНог{ та1п_10ор ; Иначе - переключить светодиоды.

ех1{_1оор: |
оу ав, 0 ; Выход из цикла = была нажата клавиша.
114 161 5’ Считать ее
' гет а ; и завершить ‚программу.
ЭТагт | епар

; Процедура спапде_1Е0$.
‚ Устанавливает состояние светодиодов клавиатуры в соответствии с числом в СИ.
спапде_[Е0$ ргос пеаг
. са11 мазт_КВ]п ; Ожидание возможности - посылки ‘команды.
тоу а1, ОЕОВ `
ош 601, а1 ; Команда клавиатуры ЕОН.
са11 ма1{_КВ1п ; Ожидание возможности посылки команды.
оу а1, с1
ощ бов, а] ; Новое состояние ‘светодиодов.
гет
спапде_1Е0$ епдр
‚ Процедура ма11т_КВлп. И:
‚ Ожидание возможности ввода команды для клавиатуйы.-
ма1{_КВ1п „ргос пеаг
1п а1, 641 ; Прочитать слово состояния,
тез1 а1, 00106 ; Бит 1 равен 1?
17 има1{_КВ1п ; Если нет - ждать.
гет ; Если да - выйти:
ма1т_КВ1п епар
епд зфагт
Программирование на’уровне портов |
5.10.2. Последовательный порт
Каждый из последовательных портов обменивается данными с процессором че-
рез набор портов ввода-вывода: СОМ1 - ОЗЕ8В — ОЗЕЕЪ, СОМ2 = 02Е8В - 02ЕЕБ,
СОМЗ = 0ЗЕВЬ -— ОЗЕЕВ и СОМА - 02Е8Ь - 02ЕЕЬ. Имена портов СОМ1 -
СОМА4 на самом деле никак не зафиксированы. ВТО$ просто называет порт
СОМ, адрес которого (ОЗЕВВ по умолчанию) записан в области данных ВТО$ по
адресу 00401:00008. Точно так же порт СОМ2, адрес которого записан по адресу.
0040Ъ:00028, СОМЗ - 00408:00041 и СОМА - 0040Ъ:0006Ъ. Рассмотрим назначе-
ние портов ввода-вывода на примере ОЗЕВЪ - ОЗЕЕЬ.
ОЗЕВЁ для чтения и записи — если старший бит регистра управления линией = 0,
то это регистр передачи данных (ТНВ или ВВК). Передача и прием данных через
последовательный порт соответствуют записии чтению именно в этот порт. |
ОЗЕВВ для чтения и записи - если старший бит регистра управления линией = 1,
` То это младший байт делителя частоты порта. _
ОЗЕЭЁ для чтения и записи - если`старший бит регистра управления линией - 0,
то это регистр разрешения прерываний (ТЕК):-
‚ бит 3: прерывание по изменению состояния модема
бит 2: прерывание:по состоянию ВКЕАК или ошибке
бит 1: прерывание, если буфер передачи пуст
бит 0: прерывание, если пришли новые данные
ОЗЕЭЁ для чтения и записи - если старший бит регистра управления линией = 1,
то это старший байт делителя частоты порта. Значение скорости порта определя-
ется по значению делителя частоты (см. табл. 20).
ОЗЕАЁ для чтения— регистр идентификации прерывания. Содержит информацию
о причине прерывания для обработчика:
биты 7-6: 00 — ЕГЕО отсутствует, 11 - ЕТЕО присутствует
. бит 3: тайм-аут ЕТЕО приемника
биты 2-1: тип произошедшего прерывания:
11Ъ — состояние ВВЕАК или ошибка.
Сбрасывается после чтения из ОЗЕОЬ
10Ъ— пришли данные.
'Сбрасывается после чтения из ОЗЕ8Ь
01Ь— буфер передачи пуст.
Сбрасывается после ‘записи в ОЗЕ8Ь
00Ь — изменилось состояние модема.
Сбрасывается после чтения из ОЗЕЕВ
бит 0: 0, если произошло прерывание; 1, если нет
ОЗЕАР для записи- регистр управления ЕТЕО (ЕСК) .
биты 7-6: порог срабатывания прерывания о приеме данных:
00 - 1 байт _ ‚
01Ь- 4 байта
10Ъ - 8 байт
11Ь -— 14 байт
'ЕТОЗИ ИИ ИИ: ’ Сложные приемы программирования
бит 2: очистить ЕГРОпередатчика
бит 1: очистить ЕГЕО приемника
бит 0: включить режим работы через ЕГЕО
ОЗЕВА для чтения и записи - регистр управления линией (ГСК)
бит 7: если 1 - порты ОЗЕ8В и ОЗЕЭЬ работают, как делитель частоты порта
`бит 6: состояние ВВЕАК - порт непрерывно посылает нули .
биты 5-3; четность:
720 - без четности
001 - контроль на-нечетность
011 - контроль на четность
101 - фиксированная четность 1
111 - фиксированная четность 0
7?1 - программная (не аппаратная) четность
бит 2: число стоп-бит:
0-1 стоп-бит
1-2 стоп-бита для 6-, 7-, 8-битных; 1,5 стоп-бита для 5-битных слов
биты 1 — 0: длина слова:
00-5 бит
01-6 бит
10-7 бит
11-8 бит
ОЗЕСЯ для чтения и записи - регистр управления модемом (МСК)
бит 4: диагностика (выход СОМ-порта замыкается на вход)
бит 3: линия ОПТ2 — должна быть 1, чтобы работали прерывания
бит 2: линия ООТ1 - должна быть 0
бит 1: линия ВТ$
бит 0: линия ОТВ.
ОЗЕБВ для чтения - регистр состояния линии (1.58)
бит 6: регистр сдвига передатчика пуст
бит 5: регистр хранения передатчика пуст — можно писать в ОЗЕ8Ь
бит 4: обнаружено состояние ВВЕАК (строка нулей длиннее, чем старт-бит +
слово + четность. + стоп-бит)
бит 3: ошибка синхронизации (получен нулевой стоп-бит)
бит 2: ошибка четности
бит 1: ошибка переполнения (пришел новый байт, хотя старый не был прочи-
тан из ОЗЕВЬ, при этом.старый байт теряется)
бит 0: данные получены и готовы для чтения из ОЗЕ8Ь
0ЗЕЕЙ для чтения - регистр состояния модема (М$В).
бит 7: линия РСР (несущая)
бит 6; линия ВТ(звонок)
бит 5: линия ОЗВ. (данные готовы)
бит 4: линия СТ$ (разрешение на посылку)
бит 3: изменилось состояние РСО
бит 2: изменилось состояние В]
Программирование на’уровне портов | ММИНЕ
бит 1: изменилось состояние О5К.
бит 0: изменилось состояние СТ$
ОЗЕЕВ для чтения и записи — запасной регистр. Не используется контроллером
последовательного порта, любая программа может им пользоваться.

Таблица 20. Делители частоты последовательного порта

о эжм м
мр 000св
м
9 600
|
„_ 00101 7 200
00188 4 800
00208 3 600

Итак, первое, что должна сделать программа, работающая с последовательным


портом, — проинициализировать его, записав в регистр управления линией
(ОЗЕВЬ) число 801, делитель частоты — в порты 0ЗЕВ и ОЗЕЭЪ, режим — в порт
ОЗРВЬ, а также указав разрешенное прерываниев порту ОЗЕЭВ. Если программа
вообще не пользуется прерываниями — надо записать в этот порт 0,
Перед записью данных в последовательный порт можно проверить бит 5, а перед
чтением - бит 1 регистра состояния линии, но, если программа использует преры-
вания, эти условия выполняются автоматически. Вообще говоря, реальная серьез-
ная работа с последовательным портом возможна только при помощи прерываний.
Посмотрим, как может быть устроена такая программа на следующем примере:
; Тегт2.азт
; Минимальная терминальная программа, использующая прерывания.
; Выход - АМ-Х

‚00де1 11пу
. соде
. 186
огд 1008 ; СОМ-программа.

; Следующие четыре директивы определяют, для какого последовательного порта


; скомпилирована пропрамма (никаких проверок не выполняется\- не запускайте этот.
; пример, если у вас нет модема на соответствующем порту}. Реальная программа
; должна определять номер порта из конфигурационного файла или из командной строки.
| Сом еци О2Е8Н ‚; Номер базового порта (С0М2).
ТВО еаи ОВИ ; Номер прерывания (ТМ№Т ОВ для 1403).
Е_ВТТМАЗК еди 111101115 г Битовая маска для разрешения ТНОЗ.
0._.ВТТМА$К еду 000010005 ; Битовая маска для запрещения 1903.
ЕР ШШШШИИ Сложные приемы программирования
эТаге:
са11. И еуегути1п9 ; Инициализация линии и модема.
па1п_1оор: ; Основной цикл.
‚;Реальная терминальная программа в этом цикле будет выводить данные из буфера
; Приема (заполняемого из обработчика прерывания) на экран, ‘если идет обычная
; работа, в файл, если пересылается файл, или’ обрабатывать как-то по-другому.
; В нашем примере мы используем основной цикл для ввода символов, хотя лучше это
; делать из обработчика прерывания от клавиатуры.
по\ ап, 8 ; Функция 00$ 081:
1 218 . ; чтение с ожиданием и без эха.
Тезт а1, а1 ‚ Если введен -обычный символ,
9п2 зеп4д_спаг . ; послать его.
171 алн ; Иначе - считать расширенный АЗСТТ-код.
стр . а1, 20Н ; Если это не А1Т-Х,
пе та1п_1оор ; продолжить цикл.

са11 зПитдомп_еуегут!1п9 ; Иначе - восстановить все в


‚ исходное состояние
ге ` ; И завершить программу.
зеп4_сваг:.. ; Отправка символа в модем.
. ; Реальная терминальная программа должна здесь только добавлять символ в буфер
, ‚ Передачи и, если этот буфер был пуст, разрешать прерывания “регистр передачи
; пуст”. Просто- пошлем символ напрямую в порт.
ие ах, сом ; Регистр ТНВ.
ох 9х,а1 |
Этр зпогЕ та1п_1оор
019_1га 99 ? . ‚ Здесь будет храниться адрес. старого
; обработчика.
; Упрощенный обработчик прерывания от последовательного порта.
1га_Папа]1ег ргос Раг р
ризпа ; Сохранить регистры.
моу 9х, с0м+2 ‚ Прочитать регистр идентификации
11 -.а1,9х | ; прерывания.
гереат_пап4] ег; ,
апа ах, 000001105. ; Обнулить все биты, кроме Ти 2
оу. ^ 91, ах ‚ отвечающие за 4 основные ситуации.
са11 мог@ руг сз:Пап91ег$[91] ; Косвенный вызов процедуры
| ‚ для обработки ситуации.
то 9х, С0М+2 ‚; Еще раз прочитать регистр идентификации
п а1, ах . ; прерывания.
Тезт а1, 1 . ; Если младший бит не 1,
92 гереа{ _Папд1ег ; надо обработать еще одно прерывание,
поу а1, 200. : ; Иначе - завершить аппаратное прерывание
041 20Н, а] ‚ посылкой команды ЕОТ (см. раздел 5.10.10).
рора `
1гет
‚ Таблица адресов процедур, обслуживающих разные варианты прерывания,
Вапа]егз [в оРТэзет 11пе_в, оТЁзеф 1гапз_п
9\ оГРзет гесм_п, оЕЁзет подет_п
Программирование на уровне портов
й Эта . процедура вызывается при изменении состояния линии.
11пе_п ! ргос пеаг
моу 9х, С0М+5 . ; Пока не будет прочитан ЕЗ8,
п а1, 9х ; прерывание считается незавершившимся.
: Здесь можно проверить, что случилось, и, например, ‘прервать связь, если
: обнаружено состояние ВВЕАК.
. гет .
11 пе_п епдр
; Эта процедура вызывается при приеме новых данных.
гесу_П ргос пеаг
мо\ ах, сом " Пока не будет прочитан ВВВ,
11 а1, дх | ; прерывание считается незавершившимся.
; Здевь следует поместить принятый байт в буфер приема для основной программы,
: НО мы просто сразу выведем его на экран.
1м 29 , ; Вывод на экран.
` гет
гесу.Н епар |
‚ Эта процедура вызывается по окончании’ передачи данных.
|гапз_й ргос пеаг
‚ Здесь следует записать в ТНВ следующий символ из буфера передачи и, если
‚ буфер после этого оказывается пустым, запретить этот тип прерывания.
гет
Тгап$_П епар
; Эта процедура вызывается при изменении состояния модема.
модет_В ргос пеаг
мо\ дх, С0М+6 ; Пока МСВ не будет прочитан,
1п а1, 9х ; прерывание считается незавершившимся. ^
‚ Здесь можно определить состояние звонка и поднять трубку, определить
‚ ; потерю несущей и перезвонить, и т. д.
гет
тодет_п епар
`1г9_Вапа] ег епар

‚ Инициализация всего, что требуется инициализировать.


1111 еуегутй119 ргос. пеаг
; Установка нашего обработчика прерывания.
моу ах, 35004+ТАЙ . ; АН = 351, АЁ = номер прерывания.
17 218 ; Получить адрес старого обработчика
моу мога рег о19_1гд,6х ; и сохранить в 019_1г4.
моу мога рег о19_1г9+2,е$
оу ах, 25001+ТВ@ ; АН = 251, АЁ = номер прерывания.
моу 9х, оРРзет 1г9_ палазег ; 05:0Х - наш обработчик.
1 218 ; Установить новый обработчик.
‚ Сбросить все. регистры .порта.
моу дх, СОМ+1 ‚Регистр ТЕН.
оу а1,0 - ‘
° од 9х, 21 \ : ; Запретить. все
в прерывания.
оу 9х, С0М+4 | ; МСА.
ОШ 9х, а1 ‚ Сбросить все линии модема в 0
оу ° ОХ, С0№+5 ‚ и выполнить чтение из Ё98,
и Сложные приемы программирования
п. а1,9х
Де ах, С0м+0 из НВЯ
1п а1,вх
ЮУ ах, СОМ+6 и из МВ |
п 81,9х на тот случай, если они недавно изменялись,
оу ах, С0М+2 а также послать. 0 в регистр ЕСВ,
оу а1,0 чтобы выключить ЕТЕО.
ОШ 9х, а1

‚ Установка скорости СОМ-порта.


тому ах, С0м+3 Записать в регистр (СЯ
оу а1, 801 любое число со старшим битом 1.
оси . ах, а]
тому дх, С0М+0 Теперь записать в регистр ОМ
ей а],2 младший байт делителя скорости,
[ее дх,а]
тому ах, С0М+1 ав ПИН -
поу а1,0 старший байт
ош ах,а1 (мы записали 0002Н - скорость порта 57 600).

‚ Инициализация линии. 1

оу 9х, С0М+3 Записать теперь в [СВ


то\у а1, 00116 число, соответствующее режиму 811
оне 9х, а1 (наиболее часто используемому).
; Инициализация модема,
моу ах, С0М+4 Записать в регистр МСЕ
ом а], 10116 , битовую маску, активизирующую ОВТВ, АТЗ
о 9х,а] , и 92.
Здесь следует выполнить проверку на наличие модема на этом порту (читать
регистр МЭН, пока не будут установлены линии СТЗ ‘и ЗВ или ‘не кончится время),
а затем послать в модем (то есть поместить в буфер передачи) инициализирующую
‚ строку, например “АТ?” 0Вй,
‚ Разрешение прерываний.
оу @х, С0М+1 Записать в ТЕН битовую' маску, разрешающую
оу ` а1, 11016 все прерывания, кроме “регистр передачи пуст”.
| Чх,а]
11 а], 218 Прочитать 0СМ1 (см, раздел 5.10.10).
апа а1,Е_ВТТМАЗК Размаскировать прерывание.
от 218,а1 Записать ОСИ1. | 7
гет
1111 еуегу{1т9 епар

‚ Возвращение всего в исходное состояние,


Ни домп_еуегуИ1п9 ргос пеаг
‚ Запрещение прерываний.
11 а1, 218 Прочитать ОСИ.
ог а1,0_ВТТМАЗК Замаскировать прерывание.
[39 211,а] Записать ОСИ.
му ах, С0м+1 Записать в регистр ТЕЯ
моу а1,0 ноль.
Программирование на уровне портов |
ош 9х,а1 .
‚ Сброс линий модема ОТВ и СТ$. |
му ах, С0М+4 ; Записать в регистр МСА
‚ МОУ а]1,0 ; Ноль.
оу 9х,а1
‚ Восстановление предыдущего обработчика прерывания.
тому ах, 25001+ТА@ `. АН = 256, АЁ = номер. прерывания.
19$ 9х, 019_1г4 . : 0$:0Х - адрес обработчика.
11 ан |
гет
элит домп _емегу1пд ‘епдр
епд эзтагт

5.10.3. Параллельный порт


ВГО$ автоматически обнаруживает только три параллельных порта - с адреса-
ми 0378 — 037АВ (ЕРТ1 или ГРТ2), 02781 -— 027 АЪ (ЕРТ2 или ГРТЗ) и 0ЗВСЬ -
ОЗВЕРВ (Г.РТ1, если есть) - и записывает номера их базовых портов ввода-вывода
в область данных В1О$ по адресам 00401:0008Ъ, 0040Ъ:000Ъ, 0040Ъ:000СВ соот-
ветственно. Если в системе установлен еще один параллельный порт, придется до-
полнительно записывать его базовый номер в 00401:000ЕЪ, чтобы ВТО$ восприни-
мала его как ЕРТ4. Рассмотрим: назначение портов ввода-вывода, управляющих
параллельными портами на примере 0278 - 027 АВ.
0278 для записи - порт данных. Чтение и запись в этот порт приводят к приему
или отправке байта в принтер или другое присоединенное устройство.
02798 для чтения — порт состояния
бит 7: принтер занят, находится в оНше или произошла ошибка
_ бит 6: нет подтверждения (1 — принтер не готов к приему следующего байта)
бит 5: нет бумаги
бит 4: принтер в режиме опНпе`
бит 3: нет ошибок
бит 2: [ВО не произошло
биты 1-0: 0
027АЁ для чтения и записи— порт управления
бит 5: включить двунаправленный обмен данными (этот режим не поддержи-
вается В1О5$)
бит 4: включить генерацию аппаратного прерывания (по сигналу подтверждения)
бит 3: установить принтер в опПпе
бит 2: 0 в этом бите инициализирует принтер
бит 1: режим посылки символа Г.Е (0АБ) после каждого СК (00Ь)
бит.0: линия ЗТКОВЕ
Чтобы послать байт в принтер, программа должна убедиться, что линия ВИЗУ
(бит 7 порта состояния) равна нулю, а линия АСК (бит 6 порта состояния) — еди-
нице. Затем надо послать символ на линии ОАТА (порт данных), не ранее чем
Сложные приемы программирования
через 0,5 мкс установить линию ЗТКОВЕ (бит 0 порта управления) в 0, а затем,
не менее чем через 0,5 мкс, - в 1. В отличие от последовательных портов, парал-
лельные хорошо поддерживаются В1О$ и РОЗ, так что программирование их на
уровне портов ввода-вывода может потребоваться только при написании драйве-
ра для какого-нибудь необычного устройства, подключаемого к параллельному
порту, или, например, при написании драйвера принтера для новой операцион-
ной системы.

5.10.4. Видеоадаптеры УСА


УСА-совместимые видеоадаптеры управляются при помощи портов ввода-вы-
вода 03СОЬ — ОЗСЕВ, ОЗВАВ, ОЗВ5В, 03Р4В, 0305В, ОЗРАВ, причем реальное чис-
ло внутренних регистров видеоадаптера, к которым можно обращаться через это
окно, превышает 50. Так как В1ОЗ предоставляет хорошую поддержку для боль-
шинства стандартных функций, мы не будем подробно говорить о программиро-
‚ вании видеоадаптера на уровне портов, а только рассмотрим основные действия,
для которых принято обращаться к видеоадаптеру напрямую.
Внешние регистры контроллера УбА (03628- ОЗСЕН)
Доступ к этим регистрам осуществляется прямым обращением к соответству-
ющим портам ввода-вывода.

Регистр состояния ввода 0 (15К0) - доступен для чтения из порта 03С2.


бит 7: произошло прерывание обратного хода луча 1ВО2
бит 6: дополнительное устройство 1 (линия ЕЕАТ1)
бит 5: дополнительное устройство 0 (линия ЕЕАТО).
бит 4: монитор присутствует
Регистр вывода (МОК) - доступен для чтения из порта ЗССЬ и для записи как
ЗС2В
биты 7-6: полярность сигналов развертки: (01, 10, 11)= (400,350, 480) линий
бит 5: 1/0: нечетная/четная страница видеопамяти
биты 3-2: частота: (00, 01)= (25,175 МГц, 28,322 МГц)
бит 1: 1/0: доступ СРИ к видеопамяти разрешен/запрещен
бит 0: 1/0: адрес порта контроллера СВТ= 0324, /03ВАВ
‚ Регистр состояния ввода 1 (1561)- доступен для чтения из порта ОЗРАВ
бит 3: происходит вертикальный обратный ход луча
бит 0: происходит любой обратный ход луча
Лучшим моментом для вывода данных в видеопамять является тот, когда элек-
тронный луч двигается от конца экрана к началу и экран не обновляется, то есть
вертикальный обратный ход луча. Перед копированием в видеопамять 1полезно
вызывать, например, следующую процедуру:
; Процедура ма1т_ге{гасе.
; Возвращает управление в начале обратного вертикального хода луча.

ма1{_гетгасе ргос пеаг


ризв ах
Программирование
-науровне портов |ИИИВИИИШИЩЕТ
ризВ 9х т: | ".
поу: 9х, ОЗОАН........ .; Порт регистра 1581.
ма1{_гетгасе,
епд:
1п., а1, 9х .
тез* а1, 10006 `_; Проверить. бит 3.
, о; Если не ноль -
` 2 май гегасе_епд ; подождать конца текущего обратного хода,
ма1{_гетгасе_этагт:
11 а], 9х |
1951 а}, 10006 ; а теперь подождать начала следующего.
2 ма1{_гетгасе.:зфаг® _. . | |
рор. вх : ._ (1 р
_ рор ах | р
гет
ма1{_гетгасе с‘ епар у

Регистры контроллера атрибутов (овсон 03) = -


Контроллер атрибутов преобразовывает значения байта атрибута символа
в цвета символа и фона. Надо записать в порт 0ЗСОВ номер регистра, а затем (вто-
рой командой оц)— ‘данные для этого регистра. Чтобы убедиться, что ОЗСОВ на-
ходится в состоянии приема номера, а не данных, надо выполнить чтение из 1581
(порт 0ЗРАН). Порт 0ЗС1В можно использовать для чтения последнего записан-
ного индекса или данных.
008— ОЕБ: Регистры палитры ЕСА -
биты 5-0: номер регистра в ‘текущей странице УСА РАС, соответствующего
данному ЕСА-цвету
10в: `Регистр управления режимом
бит 7: разбиение регистров УСА ПАС для 16-цветных режимов:
1 = 16 страниц но 16 регистров, 0 = 4 страницы по 64 регистра
бит 6: 1 = 8-битный цвет, 0 = 4-битный цвет
бит 5: горизонтальное панорамирование разрешено
бит 3: 1/0: бит 7 атрибута управляет миганием символа/цветом фона
бит 2: девятый пиксел в каждой сТроке повторяет восьмой
бит 1: 1/0: генерация атрибутов для монохромных/цветных режимов
бит 0: 1/0: генерация атрибутов для текстовых/графических режимов
116: Регистр цвета бордюра экрана (по ‘умолчанию 001)
биты 7-0: номер регистра УСА РАС,
125: Регистр разрешения использования цветовых плоскостей
бит 3: разрешить плоскость 3
бит 2: разрешить плоскость 2.
бит 1: разрешить плоскость 1
бит 0: разрешить плоскость 0
136: Регистр горизонтального панорамирования' .
биты 3-0: величина сдвига по горизонтали в пикселах (деленная на 2 для ре-
жима 131)
146: Регистр выбора цвета (по умолчанию 001)
ЕЕЗИШИИШИШИВИИИ! Сложные приемы программирования
Функции ТМТ 10} АХ = 1000} -— 1009 позволяют исполь
зовать большинство
из этих регистров, но кое-что, например панорамирование, оказыв
ается возмож:
ным только при программировании на уровне портов.
-”
Регистры графического контроллера (0ЗСЕР - ОЗСЕН)
Для обращения к регистрам графического контроллера
следует записать ин-
декс. нужного регистра в порт ОЗСЕК, после чего можно
будет читатьи писать
данные для выбранного регистра в порт ОЗСЕЬ. Если
требуется только запись
в регистры, можно просто поместить индекс в АТ., посыл
аемый байт —в АН ивы-
полнить команду вывода слова в порт ОЗСЕВ. Этот контро
ллер, в первую очередь,
предназначен для обеспечения передачи данных между
процессором и видеопа-
мятью в режимах, использующих цветовые плоскости,
как, например, режим 12}
(640х480х16).
|
008: Регистр установки/сброса ,
биты 3-0: записывать ЕЕК в цветовую плоскость 3—0 соответственно
01: Регистр разрешения установки/сброса
,
биты 3-0: включить режим установки/сброса для цветов
ой плоскости 3-0
В этом режиме данные для одних цветовых слоев получ
ают от СРО,
а для других — из регистра установки/сброса. Режим
действует
( только в нулевом режиме работы (см. регистр 051).
02: Регистр сравнения цвета — |
биты 3-0: искомые биты для цветовых плоскостей
3—0
Используется для поиска пиксела заданного цвета, чтобы
не обра-
щаться по очереди во все цветовые слои.
038: Регистр циклического сдвига данных
биты 4-3: выбор логической операции:
00 — данные от СРО записываются без изменений
01 - операция АМО над СРИ и регистром-защелкой
10 - операция ОВ над СРО и регистром-защелкой
11 - операция ХОК над СРО и регистром-защелкой
биты 2-0: на сколько битов выполнять вправо циклически
й сдвиг данных пе-
ред записью в видеопамять
04: Регистр выбора читаемой плоскости
биты 1-0; номер плоскости (0-3)
Запиеь сюда изменяет номер цветовой плоскости, данные
из которой получа-
ет СРО при чтении из видеопамяти.
055: Регистр выбора режима работы
бит 6: 1/0: 256/16 цветов
бит 4: четные адреса соответствуют плоскостям 0,
2; нечетные - 1, 3
бит 3: 1 режим сравнения цветов у
биты 1-0: режим: `
00: данные из СРИ (бит на пиксел) + установка/сброс
+ циклический
сдвиг + логические функции
Программирование на. уровне портов АН ПО ЕТ
’ 01: данные в/из регистра-защелки (прочитать в него и записать в дру-
гую область памяти быстрее, чем через СРИ).
- 10: данные из СРО, байт на пиксел, младшие 4 бита записываются в соот-
ветствующие плоскости `
11: то же самое + режим битовой маски
06Ъ: Многоцелевой регистр графического контроллера
биты 3-2: видеопамять: |
00: 0А0000Ъ - ОВЕЕЕЕЬ (128 Кб)
01: 0А0000 — ОАЕЕЕЕН (64 Кб) _
10: 0800008 — ОВ7ЕЕЕБВ (32 Кб)
. 11: 0880006 — ОВЕЕЕЕВЬ (32 Кб)
бит 0: 1/0: графический/ текстовый режим
076: Регистр игнорирования цветовых плоскостей
биты 3-0: игнорировать цветовую плоскость 3—0
085: Регистр битовой маски
Если бит этого регистра 0, то соответствующий бит будет браться из регистра-
защелки, а не из СРЦИ. (Чтобы занести данные в регистр-защелку, надо вы-
полнить одну операцию чтения из видеопамяти, при этом в каждый из четы-
рех регистров-защелок будет помещено
по одному байту из соответствующей
цветовой плоскости.) |
Графический контроллер предоставляет весьма богатые возможности по управ-
лению режимами, использующими цветовые плоскости. В качестве примера на-
пишем процедуру, выводящую точку на экран в режиме 12Ь (640х480х16) с при-
менением механизма установки/сброса.
\
; Процедура рифрёхе112Н.
; Выводит на экран точку с заданным цветом в режиме 121 (640х480х16).
Вход: ОХ = строка
; СХ = столбец ^
; ВР = цвет
; Е = 0АОООП.

ритр1хе1 128 ргос пеаг


ризпа |
; Вычислить номер байта `в видеопамяти.
хог о Бх,Бх
моу ° ах, 9х $ АХ = строка.
`1еа ° вах, [еаж+еах+4] °; АХ = АХХ 5.
$11 ах,4 - ._ 1. АХ = АХх 16.
` ; АХ = строка х байт_в_строке
; (строках 80).
ризв сх` . `
ЭВг сх, 3 | ; СХ = номер байта в строке.
а99 ` ах, сх ; АХ = номер; байта в видеопамяти.
Мом 91, ах ; Сохранить его`в ВТ. -
‚ Вычислить номер бита в байте.
„ рор сх :
Сложные приемы программировани
апа ` сх, 078 ; Остаток от деления на 8
- номер
, ; бита в байте, считая спра
тоу ва налево.
Ьх, 00801
ЗВг ‘5х, с1 ‚ В ВЕ теперь нужный бит уста
| новлен в 1.
; Программирование портов.
моу 9х, ОЗСЕН ; Индексный порт
| ‚; графического контроллера.
оу ,
ах, оЕ01В ; Регистр Олн: разрешение
, ‚ установки/сброса.
оц 4х, ах ; Разрешить установку/сброс для
‚ всех плоскостей (эту часть лучше
‚ сделать однажды в программе,
например сразу после установки
; Видеорежима, и не повторять
каждый раз при вызове процедур
тоу ‹ ах, бр
ы).
$1] ах, 8 . ; Регистр 008: регистр
‚ установки/сброса,
‚ ОЕ 9х, ах . ; АН = цвет.
тому 21,08 — ; Порт 08В: битовая маска.
том ан, 6 ; Записать в битовую` маску нули
| | ; всюду, кроме
от. . @х,ах ; бита, соответствующего ВывоДимому пикселу.
мо\ ан, БУТе рёг ез:[491] ; Заполнить |
| ; регистры-защелки,
. МОУ ` Буте рг е5:[91] ав ; Вывод на экран:
‚ Выводится единственный бит
‚ В соответствии с содержимым
регистра битовой маски, остал
; биты берутся из защелки, то ьные
есть не изменяются, Цвет вывод
; бита полностью определяется имого
значением регистра установки/сб
рора роса .
гет
ритр1хе112Н епар
Регистры контроллера СЕТ (ОЗБ4В
- 03051)
Контроллер СВТ Управляет разв
ерткой и формированием кадров
Как и для графического контроллера, на дисплее.
чтобы обратиться к регистрам конт
СЕТ, следует записать индекс нужн роллера
ого регистра в порт 0304, после
будет читать и писать данные для чего можно
выбранного регистра в порт 0305
буется только запись в регистры, $. Если тре- `
можно просто поместить индекс
мый байт — в АН и выполнить кома в АГ, посылае-
нду вывода слова в порт 03О4В.
|
00: общая длина горизонтальной
развертки |
018: длина отображаемой части гори
зонтальной развертки минус один
028: начало гашения луча горизонт
альной развертки
03В: конец гашения луча горизонт
альной развертки
‚ биты 6-5: горизонтальное смещен
ие в текстовых режимах
биты 4-0: конец импульса
| —
041: начало горизонтального обра
тного хода луча
Программирование на уровне портов а
>

05Ъ: конец горизонтального обратного хода луча


биты 7, 4-0: конец импульса
биты 6-5: горизонтальное смещение импульса
06Ъ: число вертикальных линий растра без двух старших битов
97$: дополнительный регистр
бит 7: бит 9 регистра 108
бит 6: бит 9 регистра 128
бит 5: бит 9 регистра 06Ъ
бит 4: бит 8 регистра. 18В
бит 3: бит 8 регистра 15Ъ
бит 2: бит 8 регистра 10°.
бит 1: бит 8 регистра 126
бит 0: бит 8 регистра-06Ъ
085: предварительная горизонтальная развертка
биты 6-5: биты 5 и 4 регистра горизонтального панорамирования
биты 4-0: номер линии в верхней строке, с которой 1начинается изображение
09: высота символов
бит 7: двойное сканирование (400 линий вместо 200)
бит 6: бит 9 регистра 18
бит 5: бит 9 регистра 15Ъ
‘биты 4—0: высота символов минус один (от 0 до 31)
ОА: начальная линия курсора (бит 5: гашение курсора)
ОВЬ: конечная линия курсора (биты 6—5: отклонение курсора вправо)
ОСЬ: старший байт начального адреса
ООВ: младший байт начального адреса (это адрес в видеопамяти, начиная с кото-
рого выводится изображение)
ОЕЪ: старший байт позиции курсора
ОЕВ: младший байт позиции курсора
10Ъ: начало вертикального обратного хода ‘луча без старшего бита
11Ъ: конец вертикального обратного хода луча без старшего бита
бит 7: защита от записи в регистры 00-07 (кроме бита 4 в 071)
бит 6: 1/0: 5/3 цикла регенерации за время обратного хода луча
бит 5: 1/0: выключить/включить прерывание по обратному ходу луча
бит 4: запись нуля сюда заканчивает обработку прерывания
биты 3-0: конец вертикального обратного хода луча
125: число горизонтальных линий минус один без двух старших битов
1ЗВ: логическая ширина экрана (в словах/двойных словах на строку)
14В: положение символа подчеркивания =
бит 6: 1/0: адресация словами/двойными словами
бит 5: увеличение счетчика адреса регенерации на 4
биты 4-0: положение подчеркивания
15В: начало импульса гашения луча вертикальной развертки без двух старших битов
АбЗ: конец имнульса гашения вертикальной развертки
178: регистр управления режимом

| Зак. 459
ЕРШ Сложн ые приемы программировани
жные. ;
с
бит 7: горизонтальный и вертикальный ходы луча отключены.
бит 6: 1/0 - адресация байтами/словами`
бит 4: 1 - контроллер выключен '
бит 3: 1/0 - счетчик адреса регенерации растет на 2 /1 на каждый
символ
бит 2; увеличение в 2 раза разрешения по вертикали
181: регистр сравнения линий без двух старших битов‘
(от начала экрана до линии с номером из этого регистра отображается: нача:
ло видеопамяти, а от этой линии до конца — видеопамять, начиная с адреса
указанного в регистрах ОСВ и ООВ)
221: регистр-защелка (только для чтения) —
231: состояние контроллера атрибутов ро
биты 7-3: текущее значение индекса контроллера атрибутов
бит 2: источник адреса палитры
бит 0: состояние порта контроллера атрибутов: 0/1 = индекс/данные
ВТО$ заполняет регистры этого контроллера соответствующими значени
ями
` при переключении видеорежимов. Поскольку одного контроллера СВТ мало
для
полного переключения в новый видеорежим, мы вернемся к этому чуть
позже,
а пока посмотрим, как внести небольшие изменения в действующий режим,
на-
пример:-как превратить текстовый режим 80х25 в 80х30:
; 80х30.азт
‚у Переводит экран в текстовый режим 80х30 (размер символов
8х16.)
; {Ногтоп Соттапфег 5.0 в отличие от, например, РАВ восстанавливает режим ло
‚ окончании программы, но его можно обмануть, если предвари
тельно нажать А1{-Р9).
„ое Т1пу
.с04е
. 186 . | ; Для команды оитзм.
огд _ 1008 ; СОМ-программа.
$тагт: |
поу ах, 3 ; Установить режим ОЗН (80х25),
1% 10в ; чтобы только внести небольшие изменения.
му 9х, ЗС6п ‚ Порт ЗСС: регистр вывода (МОВ) на чтение.
1п а], 9х . . :,
тоу 91, 0628 | ; Порт 03021: регистр вывода {МОН) на запись.
ог а1, осон ; Установить полярности 1, 1 - для 480 строк.
оц 9х, а] |
. МОУ „ах, 0304в ; 0Х = порт 0304н: индекс СНТ.
` поу $1, оРРзет сгЕ480 ; 05:51 = адрес таблицы данных для СВТ,
оу сх, сг{480_1 _ ; СХ = ее размер. . . .
гер сим . ‚; Послать все устанавливаемые параметры в порты
; 03041 и 03058.
; Нельзя забывать’ сообщать 810$ об-изменениях в видеорежиме.
рызИ 00408 .
рор е5 ‚ Е$ = 00401.
Программирование на уровне. портов_ || |

\ оу — Буте рЕГ ез:[841]}, 29. ; 00401:00848 - число строк.


гет
; Данные для контроллера СЯТ в формате индекс в младшем байте, данные
в старшем - для записи при помощи. команды оитз\..
Сгт480 9\ | осн ; Регистр 111 всегда надо записывать первым,
; так как его бит 7 разрешает запись в другие
. 9\ ОВОбн, ЗЕОТН, ОЕАЗОН, ООЕ12Н, 0Е7158, 04161 ; регистры.
сгЕ480_1 = ($-сгт480)/2 .
еп зтаге
Еще одна интересная возможность, которую предоставляет контроллер СКТ, —
плавная прокрутка экрана при помощи регистра 08Ъ:
‚ Узсго.. азм . а
й
‚ Плавная прокрутка’ экрана по вертикали. Выход - клавиша Езс.

.тоде] 11ту
.соде - .
. 186 ` | ; Для ризп 084001.
. огд 1008 - ; СОМ-программа.
зтагт:
ризй 088001
рор ез
хог $1, $1 ; Е5:$Т
- начало видеопамяти:
моу 61, 80*25*2 ‚: Е$:0Т
- начало второй страницы видеопамяти.
моу сх, 91 .
гер тоуз ез:апу_1абе1, ез:апу_1абе] ; Скопировать первую страницу во вторую.
А 9х, оз048 . ; Порт 03048: индекс СВТ.
зсгееп_10оор: . ; Цикл по экранам.
тоу сх, 80*12*2 $; СХ = начальный. адрес - адрес середины экрана.
4пе_100р: ; Цикл по строкам,
мо а}, ОСА ; Регистр ОСп - старший байт начального адреса.
. МОМ ай, сн ; Байт данных - СН.
сие 9х, ах ; Вывод в порты 0304, 0305.
116 ах ; Регистр ООВ - младший байт начального адреса.
моу ан, с] ; Байт данных - С.
от дх,;ах . ‚ Вывод в. порты 0304, 0305.

мо Ьх, 15 . ; Счетчик линий в строке. 7


$46 сх, 80 ‚: Переместить начальный. адрес на начало
Г ; предыдущей строки (так как’это движение вниз),
ре1_1оор: ; Цикл по линиям в строке.
са1] - иа1{_гетгасе ; Подождать обратного хода луча,

мо а], 8 ; Регистр О8А`- выбоф номера линии в первой


| ‚: строке, с которой начинается вывод изображения
Мом ай, 61. ; (номер линии из ВГ).
оит 9х, ах '
ЕРУЧИШШИНИШИШИНИИИ | — Сложные приемы программирования
ес 6х _ ; Уменьшить число линий.
39е ре1_1оор ; Если больше или равно нулю - строка еще не’
‚; прокрутилась до’ конца и цикл по линиям
; продолжается: :
11 а1, 608 ; Прочитать скан-код последнего символа,
стр а], 818 ; Ебли это 81Н (отпускание клавиши Езс),
32 Чопе °; выйти из программы.

стр сх, 0 ‚ Если еще не прокрутился целый’ экран,


39е 1пе_1оор ; продолжить цикл по строкам.`
тр ЗВогЕ эсгееп_100р; Иначе: продолжить цикл по экранам

допе: ; Выход из программы.


пом ах, 8 | ‚ Записать ‘в регистр САТ 081
от 9х, ах ‚ ; байт 00 (никакого сдвига по вертикали),
ад ах, 4 ; а также 00 в регистр Осн
оц 9х, ах -
пс ах ; и ООН (начальный адрес совпадает
оц 9х, ах ‚ С началом видеопамяти).
ге?

ма1т_гетгасе ргос пеаг


ризН 9х
мо Чх, ОЗОАВ
УВТЕ1: п а1, 9х ; Порт ОЗОАН - регистр 1581,
тезт а1,8 |
п? УВТЬ1 ‚ Подождать конца текущего обратного хода луча,
УАТЕ2: т а,ах
тезт а],8
2. УВТЕ2 ; а теперь начала следующего.
рор 9х
гет
ма1{ гетгасе - епар . .
апу_1абе1. ^` 1абе] Буте. ; Метка для переопределения сегмента в то\з.
епд ЗТагт

Горизонтальная прокрутка осуществляется аналогично, только с-использова-


нием регистра горизонтального панорамирования 131 из контроллера атрибутов.
Регистры синхронизатора (0341 - 0ЗС5В) . в }

Для обращения к регистрам синхронизатора следует записать индекс нужного


регистра в порт 03С4В, после чего можно будет читать и писать данные для вы-
бранного регистра в порт 03С5В. Точно так же, если требуется только запись в ре-
гистры, можно просто поместить индекс в АТ,, посылаемый байт — в АН и Выпол-
нить команду вывода слова в порт ОЗСЕБ.
008: регистр сброса синхронизации
бит 1: запись нуля сюда вызывает синхронный сброс
бит 60: запись нуля сюда вызывает асинхронный сброс
Ц [2
уровне портов пони
Программирование на

01: регистр режима синхронизации


бит 5: 1: обмен данными между видеопамятью:и дисплеем выключен
бит 3: 1: частота обновления для символов уменыйена в два раза
бит 0: 1/0: ширина символа 8/9 точек.
02: регистр маски`записи
бит 3: разрешена запись СРО в цветовую плоскость 3 -
бит 2: разрешена запись СРО в цветовую плоскость 2
бит 1: разрешена запись СРО в цветовую плоскость 1
бит 0: разрешена запись СРО в цветовую плоскость 0
03Ъ: регистр выбора шрифта
бит 5: если бит 3 атрибута символа = 1, символ берется из шрифта 2
бит 4: если бит 3 атрибута символа= 0, символ берется из шрифта 2
биты 3-2: номер таблицы для шрифта 2 ‹
биты 1-0: номер таблицы для шрифта 1
(00, 01, 10, 11)= (0 Кб, 16 Кб, 32 Кб, 48 Кб от начала памяти шрифтов УСА)
048: регистр организации видеопамяти
бит 3: 1: режим СНАГ\-4 (используется только в видеорежиме 131)
бит 2: 0: четные адреса обращаются к плоскостям 0, 2, нечетные - к 1,3
бит 1: объем видеопамяти больше 64 Кб
Даже несмотря на то, что ВТО$ позволяет использовать некоторые возможно-
сти этих регистров, в частности работу\со шрифтами (ПМТ 10 АН - 111) и вы-
ключение обмена данными между видеопамятью и дисплеем (ПУТ 106, АН = 12,
ВТ.= 325), прямое программирование регистров синхронизатора вместе с регист-
рами контроллера СКТ разрешает изменять характеристики видеорежимов УСА,
вплоть до установки нестандартных видеорежимов. Наиболее популярными режи-
мами являются так называемые режимы Х с 256 цветами и с разрешением 320 или
360 пикселов по горизонтали и 200, 240, 400 или 480 пикселов по вертикали.
Поскольку такие режимы не поддерживаются ВТО$5, для их реализации нужно на-
` писать все необходимые процедуры-— установку видеорежима, вывод пиксела,
чтение пиксела, переключение страниц, изменение палитры, загрузку шрифтов.
При этом для всех режимов из этой серии, кроме 320х240х256, приходится также
учитывать измененное соотношение размеров экрана по вертикали и горизонта-
ли, чтобы круг, выведенный на экран, не выглядел как эллипс, а квадрат — как пря-
`моугольник.
Установка нового режима выполняется почти точно так же, как и в предыду-
щем примере,— путем модификации существующего. Кроме того; нам придется
изменять частоту кадров (биты 3—2‘регистра МОК), а это приведет к сбою синх-
ронизации, если мы не выключим синхронизатор на время изменения частоты
(записью в регистр 00Ъ): но -
.: Процедура зе{_тодех.
: Переводит видеоадаптер УбА в один из режимов Х ‚с..256 цветами.
; Вход: ОТ = номер’ режима
; 0: 320х200, соотношение. сторон 1,2:1
: 1: 320х400, соотношение сторон 2,4:1
<

2: 360х200, соотношение сторон 1


3: 360х400, соотношение сторон 2
4: 320х240, соотношение сторон 1:
; .5: 320х480, соотношение сторон `2:
6: 360х240, соотношение сторон 1
360х480,
7:
соотношение сторон 2
; 0$ = 65 |
; Для вывода информации на экран в этих режимах
‚ см. процедуру рир1хе1_х

зеттоде_х ргос пеаг


том ах, 128 ; Очистить все четыре цветовые
пи 10в ; плоскости видеопамяти,
Деу ах, 131 - ; Установить режим 138, который будем `
11 10н | ; модифицировать.
стр 91,7 .; Если нас вызвали с 01 > 7,
За ех1т_тодех ; выйти из процедуры
’ (оставшись в режиме ЗВ).
$81 91,1 ; Умножить на 2, так как х_тоде
з .-
; таблица слов.
оу - 91, мога рег х_тодез [91] ; Прочитать
адрес таблицы настроек для
выбранного режима:
моу 9х, 03641 ; Порт 03С4Н - индекс синхронизатора.
мо ах, 01001 .; Регистр ООН, значение 01.
ит Ч9х,ах у Асинхронный сброс.
МОУ ах, 06041 ; Регистр 04Н, значение 06н.
от Чх, ах ; Отключить режим СНАТМА.
моу 91,0628 ; Порт 03021 - регистр
МОВ на запись.
МОм а1,Буфе руг [91]: Записать в него
значение частоты кадров
ош дх, а1 ; и полярности развертки
для выбранного режима.
по\ 91,004 — ; Порт 03048 - индекс
контроллера СВТ.
пом $1, мога рёг озер [91+2]
Адрес строки с. настройками
; для выбранной ширины в 65:51.`
тоу сх, 8 ; Длина строки настроек в &Х.
гер 001 $\ ; Вывод строки слов
в порты 0304/0305.
Ом $1, мог рег оЕЁзет [91+4]; Настройки для
выбранной высоты в 05:51.
моу сх, 7 ; Длина строки настроек в СХ.
гер ОиЕ$м -
Программирование на уровне портов. пана
|

мо\ $1. мог рЕг оРРзет. [41+6]; Настройки


; для включения/выключения удвоения
- ; по вертикали (200/400 и 240/480 строк).
оу сх,3
‘гер сим

МОУ ах, мог рфг оРРзет [91+8] ; Число байтов в строке.


моу мог@ рёг х_ м1, ах - ; Сохранить в переменной х_м191И.

МОУ 91., 0С4Н ; Порт 03041 - индекс синхронизатора.


моу ах, 0300 : Регистр ООН, значение 03.
от 9х, ах ; Выйти из состояния сброса.
ех11_тодех: |
гет

; Таблица адресов таблиц с’ настройками режимов.


х_тодез [А ОРРзеЕ тоде_0, оРРзет тоде_1
9м ОТЁзет поде_2, оРРзет тоде_3
ди ОТРзет тоде_4, оРРзеф тоде_5
- м 9м от зет поде..6, огГзет моде_7

; Таблица настроек режимов: значение регистра `МОВ, адрес строки


; настроек ширины, адрес строки настроек высоты, адрес строки
; настроек удвоения’по вертикали, число байтов в строке.
тоде_0- 9“ 631, оГРзе{ тоде_320м, оЕРзе{ тоде..2001, оРзет". поде_доиб1е, 320/4
поде_1 ом бЗВ, отРвеЕ тоде_320, оРРзеё поде_4001, отТзет тоде_$1п91е, 320/4
тоде_2 м 67н, огРзет моде_360м, оРРзеЁ тоде_2001, оГРзет тоде_доць?е, 360/4
поде_3 9“ 67Н, оЕЁЕзеЕ тоде_360м, оРРзе{ щоде_4001, оГГзет тоде_з1п91е, 360/4
поде_4 9 ОЕЗН, отРзе{ тодез 320, оРРзеЁ тоде_2401, оРРзет тоде_доиБ1е, 320/4
моде_5 м ОЕЗН, оРРзе{ поде_320щ, оЁТзет тоде_4801, оРРзе{ тоде_з1п91е, 320/4
тоде 6 9“ ОЕ7Н, оРР5ет тоде_360м, отРзет тоде_240п, оРРзее тоде_доие, 360/4
тоде_7 дм ОЕ7Н, огЕзет тмоде_360и, оРРзет моде 4801, огРзет тоде_31п01е, 360/4

‚; Настройки СВТ. В каждом слове младший. байт - номер регистра,


; Старший - значение, которое в этот. регистр. заносится.
тоде_320м: ‚; Настройка ширины 320.
; Первый регистр обязательно’ 111, хотя он и не относится к ширине,
: но разрешает запись в остальные регистры, если она была запрещена (!).
дм ОЕТЛВ, $РООВ, 4РОЗВ, 50021, 82031, 54041, 80051, 28131
моде_360м: ; Настройка ширины 360.
. м ОЕЛЛН, 6ВООН, 59011, БАОЗН, ЗЕОЗН, 5ЕО АВ, ЗАО5Н, 20138
моде_2001:` . |
поде_ 4001: | ; Настройка высоты 200/400.
дм ОВЕОбН, 1ЕО7Н, 9С10Н: ОЕТЛН, 8212Н', 96151, 08916
тоде_240н; ,
поде_480': | `; Настройка высоты 240/480.
[ее оро6н, ЗЕ07п, ОЕАТОН: 0С11н, ООЕ12н, ОЕ715Н, 06168
тоде_51п91е: ; Настройка режимов без удвоения,
Чи 40098, 00141, 0ЕЗ17П
моде_доиБ1е; ‚ Настройка режимов с удвоением.
бм 41091, 00141, 0ЕЗ17В
зеттоде_х епар
ЕРЕИИШИИШИИ | Сложные приемы программирования
хи ди ` ? ; Число байтов‘в строке.
; Эту переменную инициализирует зеттюде_х, а использует ритр1хе] х.

; Процедура ритр1хе1_х.
; Выводит точку с заданным цветом в текущем режиме Х.
; Вход: 0Х.= строка
; СХ = столбец
; ВР = ‘цвет
ЕЗ = 0А000
; 0$ = сегмент, в котором находится переменная х_м1атВ
ри{р1 хе] х ргос пеаг
ризва
оу ах, вх
ми] мога рфг х ман : АХ = строка х число байтов в строке,
оу 91, сх ; ОТ = столбец.
"ЭЙР 91,2 ; ОТ = столбец/4 (номер байта в строке). .
_ ада 91, ах ; 01 = номер байта в видеопамяти.
тому ах, 01028 ; АЁ = 021 (номер регистра).
| ‚ ; АН=01 (битовая маска).
апа с1, ОВ ; СЕ = остаток от деления столбца на 4 =
; Номер цветовой плоскости.
$11 ай,с1 ; Теперь в АН выставлен в 1 бит
| ‚ соответствующий нужной цветовой Плоскости.
моу ах, 03С4н ; Порт 03048 - индекс синхронизатора. —
от Чх, ах ; Разрешить запись только ,
| ; в нужную плоскость.
поу ‘ах,р ; Цвет в А.
Зт03Ь ; Вывод байта в’ видеопамять.
рора
гет | —
ритр1хе] х епар

Регистры УСА ВАС (ЗС6В - ЗС9Н)


Таблица цветов УСА на самом деле представляет собой 256 регистр
ов, в каж-
‚ Дом изкоторых записаны три 6-битных числа, соответствующих
уровням. красно-
го, зеленого и синего цвета. Подфункции 1МТ 10 АХ = 10101
- 101ВЬ позволяют
удобно работать с этими регистрами, но, если требуется максим
альная скорость,
программировать их на уровне портов ввода-вывода не намного
сложнее.
ОЗСбЕ для чтения/записи: регистр маскирования пикселов (по умолча
нию ОЕЕН)
При обращении к регистру РАС выполняется операция АМО
над его номе-
ром и содержимым этого регистра.
|,
03С7® для записи: регистр индекса РАС для режима чтения
Запись байта сюда переводит РАС в режим чтения, так что следую
щее чте-
ние из ЗСЭВ вернет значение регистра палитры с этим индекс
ом.
Программирование на уровне портов И ММИИИЕРЕ
03С7Ё для чтения: регистр состояния РАС
биты 1-0: 005/11Ъ- РАС в режиме записи/чтения
ОЗСВЁ для чтения/записи: регистр индекса РАС для режима записи -
Запись байта сюда переводит РАС в режим записи, поэтому дальнейший
вывод в ОЗСЭВ будет приводить к записи новых значений в регистры палит- `
ры, начиная с этого индекса.
03С9й для чтения/записи: регистр данных ВАС
„Чтение отсюда считывает значение регистра палитры с индексом, помещен-
ным предварительно в 03СВ8$, запись— записывает новое значение в регистр
палитры с индексом, находящимся в ОЗСВЬ. На каждый регистр требуются
три операции чтения/записи, передающие три 6-битных значения уровня
цвета: красный, зеленый, синий. После третьей операции чтения/записи ин-
декс текущего регистра палитры увеличивается на 1, так что можно считы-
вать/записывать сразу несколько регистров
_. Команды тзЬ/оцЕзЬ серьезно облегчают работу с регистрами РАС в тех случа-
ях, когда требуется считывать ‘или загружать значительные участки палитры или
всю палитру целиком, — такие процедуры оказываются и быстрее, и меньше ана-
логичных, написанных с использованием прерывания ПМТ 104. Посмотрим, как
это реализуется на примере программы плавного гашения экрана.
; Тадесцт. азт .
; Выполняет плавное гашение экрана. '
„ое {1пу
. соде
. 186 - \ ; Аля команд 1п$Б/ситзЬ.
‚ 0гд 1008 . . ; СОМ-программа.
этаге: :
_ 619 ; Для команд строковой обработки.
МОУ 41, оРРзет ра1еттез . |
. са11 геад_ра]етте ; Сохранить текущую палитру, чтобы
; восстановить в самом конце программы,
поу 91, оРР5еф ра1е11ез+256*=3
са11 геад_ра1етте ; а также записать еще одну. копию
; текущей палитры, которую будем
; модифицировать. “
моу сх, 64 ; Счетчик цикла изменения палитры. ^
пазп_1оор: |
ризй сх .. .. о . .
са11. ма1Т_гетгасе — ;, Подождать начала обратного хода луча.
оу ЧТ, оевет ра1етеез+256*3 | |
ед $#, 91 |
са1] ес_ра1етте ; Уменьшить яркость всех цветов.
‚ са11 ма1{_ге{гасе ; Подождать. начала следующего
оу $1, ОРЕзет ра1е{{ез+256»3 ; обратного хода луча.
са11 - -- иг фе:ра1е {е ‚ Записать новую палитру.
рор сх’
ЕЕТИИИИНИШИИ | Сложные приемы программирования
1оор тма1п_1оор ' ; Цикл выполняется 64 раза - достаточно
; для обнуления самого яркого цвета
; (максимальное значение 6-битной
‚ компоненты - 63). _
му $1, ОРРзее ра1еттез
са11 иг! Те _ра]етте ; Восстановить первоначальную палитру.
гет ; Конец программы,
'
; Процедура ‘геа4_ра1ет{е. `
; Помещает палитру УбА в строку по адресу ЕЗ:0Т:
геад_ра1етте ргос пеаг
оу 9х, 03078 ; Порт ОЗСТп - индекс ОАС/режим чтения.
оу а1,0 ; Начинать с нулевого цвета.
ош 9х,а1
моу 91, 0С9в ; Порт ОЗСЭН - данные ВАС.
моу сх, 256*3 о. ; Прочитать 256 х 3 байт
гер — 1136 ; В строку по адресу ЕЗ:0Т.
гет ` з:
геад_ра1е{те епар
; Процедура мг Те_ра1е\те,
; Загружает в БАС УСА палитру из строки по адресу 05:51.
мг1Те_ра1ете ргос пеаг
оу ах, озс8п ; Порт ОЗС8Н - индекс БАС/режим записи. .
тоу а1,0 . ; Начинать с нулевого цвета.
о 9х, а1 | |
по\ 91, ос9в ; Порт 03С9н - данные ВАС.
мо СХ, 256*3 ; Записать 256 х 3 байт
гер ОТ$Ь . ; из строки в 05:51.
гет |
мг1Те_ра1етте епдр
; Процедура дес_ра1етте. |
‚ Уменьшает значение каждого байта на 1 с насыщен
ием (то есть, после того как
; байт становится равен нулю, он больше не уменьша
ется) из строки в 05:51
‚ И записывает результат в строку в. 05:51.

дес ра1етте ргос пеаг


тоу сх, 256*3 ; Длина строки 256 х 3 байт.
дес_1оор:
, о
1049$6 | ; Прочитать .байт.
тезт а], а1 ; Если он ноль,
2 а]геаду_гего ‚ пропустить следующую команду.
дес ах ` ; Уменьшить. байт на 1. - |
а1геаду_тего:
. :
ТозЬ ‚ Записать его обратно. ;
1оор дес_1оор ; Повторить 256 х 3 раз.
гет
|
Чес_ра1етте епар
‚ Процедура ма11-гетгасе. ;
‚; Ожидание начала следующего. обратного хода луча.
Программирование на уровне портов
/

- ма. гетгасе ргос пеаг


рузй ах
_ МОУ 9х, ОЗОАВ
УВТЕ: т а], 9х ; "Порт ОЗБАВ - регистр 1581.
те51 а1,8 = ^^.
772 УВТЕ1 ; ; Подождать конца текущего обратного хода’ луча.
МВТ: т а1, 9х | |
Тезт а1,8 * о р
712 УАТЕ2 ‚; А теперь начала следующего.
рор. 9х
ге |
ма1т_гетгасе епдр

рате{{ез: : За концом программы мы храним две копии


й . палитры - всего 1,5 Кб.
епд зТаг{

5.10.5. Таймер
До сих пор о систменом таймере нам было известно лишь то, что он вызывает,
прерывание 1ВО0 приблизительно 18,2 раза в секунду. На самом деле програм-
мируемый интервальный таймер — весьма сложная система, состоящая из трех
частей — трех каналов таймера, каждый из которых можно запрограммировать
для работы в одном из шести режимов. И более того, на многих современных ма-
теринских платах располагаются два таких таймера, следовательно, число кана-
лов оказывается равным шести. Для своих нужд программы могут использовать
_ канал 2 (если им не нужен динамик) и канал 4 (если присутствует второй тай-
_ мер). При необходимости можно перепрограммировать и канал 0, но затем надо
будет вернуть его в исходное состояние, ‘чтобы В105 и РО$ могли продолжать
работу.^
В пространстве портов ввода-вывода для таймера выделена область от 406
до 5ЕБ:
О порт 40} - канал 0 (генерирует 1800);
О порт 41 - канал 1 (поддерживает обновление памяти);
Опорт 42} - канал 2 (управляет динамиком);
О порт 43В— управляющий регистр первого таймера;
О порты 448- 47 - второй таймер компьютеров с шиной Мисгосвавпе!;
О порты 48}— 4ВЬ - второй таймер компьютеров с шиной ЕТЗА.:
Все управление таймером осуществляется путем вывода одного байта в АЗ
(для первого таймера). Рассмотрим: назначение битов в этом байте.
биты 7-6: если не 11 — это номер канала, который будет программироваться
00, 01, 10 = канал
0, 1,2
бит 5—4: 00 — зафиксировать текущее значение счетчика для чтения (в этом
' ` случае биты 3-0 не используются)
01 - чтение/запись только младшего байта
10 — чтение/запись только старшего байта
11 - чтение/запись сначала младшего, а ‘потом старшего байта -
1
Ра -

[332 ГТГ Сложные приемы программирования


` биты 3—1: режим работы канала
000 - прерывание 1В.О0 при достижении нуля
` 001 — ждущий мультивибратор
_ 010 — генератор импульсов
011 - генератор прямоугольных импульсов (осно
вной режим)
‚ 100 — программно запускаемый одновибратор
7101 - аппаратно запускаемый одновибратор
бит 0: формат счетчика:
0 — двоичное 16-битное число (0000 - ОРЕЕЕБ)
— двоично-десятичное число (0000 — 9999) ,
Если биты 7—6 равны 11, считается, что байт,
посылаемый в 4ЗВ, - команда
чтения счетчиков, формат которой отличается
от команды программирования
канала:
биты 7-6: 11 (код команды чтения счетчиков)
биты 5-4: что читать:
00 — сначала состояние канала, потом значение
счетчика
01 — значение счетчика
‚10 — состояние канала
биты 3-1: команда относится к каналам 3-1
Если этой командой запрашивается состояние каналов,
новые команды будут
игнорироваться, пока не прочтется состояние из всех
каналов, которые были за-
казаны битами 3-1.
Состояние и значение счетчика данного канала получ
ают чтением из порта, со-
ответствующего требуемому каналу. Формат байта состоя
ния имеет следующий вид:
бит 7: состояние входа ОПТХ на момент выполнения
команды чтения счетчи-
ков. Так как в режиме 3 счетчик уменьшается на 2
за каждый цикл, со-
стояние этого бита, замороженное командой фиксации
текущего значе-
ния счетчика, укажет, в каком полуцикле находился Тайме
р
бит 6: 1/0: состояние счетчика не загружено/загружен
о (используется в режи-
мах 1 и 5, а также после команды фиксации текущего значен
ия)
биты 5-0: совпадают с битами 5-0 последней команд
ы, посланной в АЗЬ
Для того чтобы запрограммировать таймер в режим
е 3, в котором работают
` каналы 0 и 2 по умолчанию и который чаще всего приме
няют в программах, тре-
буется выполнить следующие действия:
1. Вывести в регистр 43Ь команду (для канала 0) 001101
1Ь, то есть установить
режим 3 для канала 0, и при чтении/записи будет пересы
латься сначала
- младшее слов, а потом старшее.
2. Послать младший байт начального значения счетчи
ка в порт, соответствую-
щий выбранному каналу (42 для канала 2).
3. Послать старший байт начального значения счетчи
ка в этот же порт.
После этого таймер немедленно начнет уменьшать введен
ное число от началь-
ного значения к нулю со скоростью 1 193 180 раз
в секунду (четверть скорости.
Программирование на уровне портов |ИИННИИИНИИЕЕЕ
вернет-
процессора 8088). Каждый раз; когда это число достигнет нуля, оно снова
таймер
ся к начальному значению. Кроме того, при достижении счетчиком нуля
выполняет соответствующую функцию - канал 0 вызывает прерыва ние ТКОО,
а канал 2, если включен динамик, посылает ему начало следующ ей прямоуго ль-
ной волны, заставляя его работать на`установленной частоте. Начальн ое значе-
то есть
ние счетчика для канала 0 по умолчанию составляет ©ЕЕЕЕВ (65 535),
прерыва ния ГВО0 рав-
максимально возможное. Поэтому точная частота вызова
на 1 193`180/65 536 = 18,20648 раза в секунду.
Чтобы прочитать текущее значение счетчика, надо:
1. Послать в порт 43ЗВ команду фиксации значения счетчика для выбранного
канала (биты 5-4 равны 00Ъ).
2. Послать в порт 43 команду перепрограммирования канала без смены ре-
жима работы, если.нужно воспользоваться другим способом чтения/записи
(обычно не требуется). й
3. Прочитать из порта, соответ ствующе го выбранн ому каналу, младший байт
зафиксированного значения счетчика .
4. Прочитать из того же порта старший байт.
здесь
Для таймера найдется много применений, единственное ограничение
следующее: таймер - это глобальный ресурс,и перепро граммир овать его в много-
вооб-
задачных системах можно только с ведома операционной системы, если она
ще это позволяет. 4. -_
Рассмотрим в качестве примера, как при помощи таймера измерить, сколько
когда
врёмени проходит между реальным аппаратным прерыванием и моментом,
обработчик этого прерыва ния получае т управле ние (почему это важно, см. при-
происхо-
меры лрограмм вывода звука из разделов 5.10.8 и.5.10.9). Так как [ВОО
е во
дит при нулевом значении счетчика, нам достаточно прочитать его значени
по-
время старта обработчика и изменить его знак (потому что счетчик таймера
стоянно уменьшается).
; Чатепсу. азт .
и запуском
; Измеряет среднее’‘время, ‘проходящее между аппаратным прерыванием
время ‘в микросек ундах после
; соответствующего’ обработчика; Выводит среднее
; нажатия любой клавиши (на самом деле в 1/1 193 180).
так что может давать
Программа использует 16-битный сумматор для простоты,
‚ неверные результаты, если’ подождать‘ больше нескольких минуТ. -
. и

.тоде] {1пу
. соде у .
.386 „С Для команды $114.:
ого 100н`_ ‚ ; СОМ-программа.
эТаг: И —
ах, 35088 | ; АН = 351, АЁ = номер прерывания.
мо\у
1% 211 | ; Получить адрес. обработчика
мо\ ога рег 019_1п1081,5х ; и ‘записать его в 019111081.
том мого ртг 019_1п081+2,ез
мо ах; 2508 Н ‚ АН = 256, АЁ= номер прерывания.
Сложные приемы программировани;
тому 9х, оТРзет 1пт08и.вапо1ег ; 05:0Х - адрес обработчика.
101 218 . ; Установить обработчик.
; С этого момента в переменной 1атепсу накапливается сумма,
поу . ав,0
1 = 161 . ; Пауза до нажатия любой клавиши.
МОУ ах, мога рфг ]атепсу ; Сумма в АХ.
стр мога рег соиптег, 0 ; Если клавишу нажали немедленно,
2 Чопт_41\14е ; избежать деления на ноль.
хог 9х, ах. ; бХ=0.
. Фу мога ртг соиптег ; Разделить сумму на число накоплений
доп{_91\14е: .
са11 рилтах . ; И вывести на экран.
му ах, 2508 В . ; АН = 251, АЁ = номер прерывания.
19$ вх, биога руг 019 1п108№ : 0$:0Х = адрес обработчика.
17 218 , ; Восстановить старый обработчик.
гет , ; Конец программы.
1атепсу Чи 0 ; Сумма задержек.
соуптег : Чи о. ‚ Число вызовов прерывания.
; Обработчик прерывания 08н (1800).
; Определяет время, прошедшее с момента срабатывания 1800.
1п08Н_папа1ег - ргос Раг .
ризв ах - ; Сохранить используемый регистр.
поу а1,0 . ; Фиксация значения счетчика в канале 0.
оит 431, а} ; Порт 43ЗН: управляющий регистр таймера. ‹
‚; Так как этот канал инициализируется 810 для 16-битного чтения/записи, другие
; команды не требуются. \^ `
1п а], 408 ; Младвий байт счетчика- `

оу ай, а1 ; В АН.
п а1, 401 ; Старший байт счетчика в АГ.
хсН9 ай, а1 ; Поменять их местами.
пед ах ; Изменить его знак, так как счетчик уменьшается.
а99. ° мога рег сз; ]атепсу,ах ; Добавить к сумме.
1пс могЧ` рфг с3: соуптег ; Увеличить счетчик накоплений.
рор ах . °
4 ОЕАН __; Команда тр Таг.
014_1п108В 99 0 ; Адрес старого обработчика,
111081 _Палпа] ег «Ор

; Процедура рг1п_ах. .
; Выводит АХ на. экран в шестнадцатеричном формате.
рг1п{_ах ргос пеаг . `
хСНд Чх, ах ; 0Х = АХ.
. Де сх, 4 ; Число цифр для вывода.
ЗНА _ах: |
.-$119 ах, дх, 4 ; Получить в АЁ очередную цифру.
го] 9х, 4 , ; Удалить: ее из ОХ.
апа а1, Ор ^ ; Оставить в АЁ только эту цифру.
Программирование на уровне портов ШИНИИВИЕЕЕ
||
` ср ’° а, 0. ; Три команды, переводящие
$65 а1, 698 ; шестнадцатеричную цифру в АЁ -
даз - ; в соответствующий АЗСТТ-код.
^ 11%. 291 ; Вывод на экран. . |
1Лоор 111 ах ; Повторить для всех цифр.
гет ``
рг1пЕах епдр .
епб ЗТаго

Таймер можно использовать для управления динамиком, точных измерений


отрезков времени, создания задержек, управления переключением процессов
и даже для выбора случайного числа с целью запуска генератора случайных чи-
сел — текущее значение счетчика канала 0 представляет собой идеальный-вариант
такого начального числа для большинства приложений. .

5.10.6. Динамик
Как сказано в разделе 5.10.5, канал 2 системного таймера управляет динами-
ком компьютера - он генерирует прямоугольные импульсы с частотой, равной
1 193 180/нача льно
значение е.
счетчика. При программировании динамика на-
чальное значение счетчика таймера называется делителем частоты: подразумева-_
ется, что динамик работает с частотой 1 193 180/делитель герц. После програм-
мирования канала 2 таймера надо еще включить сам динамик. Это осуществляется
путем установки битов 0 и 1 порта 61Ь в 1.Бит 0 фактически разрешает реботу
данного канала таймера, а бит 1 включает динамик.
‚. Процедура ъеер. | \.
; Издает звук с частотой 261 Гц (нота “ми” средней октавы)
: длительностью 1/2 секунды на динамике: :
Беер ` ргос леаг . |
' `; МОУ а1, 101101105 ; Канал 2, режим 3.
оц 431, а] . .
а1, 00 - ‚ Младший байт делителя частоты 11008. _
Мом
оц 421, а1 т
тому а], 118 | ‚ Старший байт делителя частоты.
ит 421, а] ° :
п - а], 618 ; Текущее состояние порта б1Н в АЕ.
ог . а1,:0000001165. ; ‘Установить биты би 1. в 1.
оц ‚ 611, а1 ; Теперь динамик включен,
мо сх, 00071 ; Старшее слово числа микросекунд паузы.
моу ах, 041208 ; Младшее слово числа микросекунд паузы.
оу ап, 861 | ; Функция 861: . |
пе ` 15Н | : пауза. °
11 ^ а1, 618 7
апа а], 111111005 ; Обнулить младшие два бита.
оу ба] ; Теперь динамик выключен.
гет
Беер епар
ЕЕЗИИШИШИШИИИИ — Сложные приемы программирования
В связи с повсеместным распространением звуковых плат обычны
й динамик
РС сейчас практически никем не используется или используется
для выдачи со-
общений об ошибках. Вернемся к звуку чуть позже, а пока вспомн
им, что в разде-
ле 4.7.1 рассматривалось еще одно устройство для определения
текущего време-
ни и даты - часы реального времени.

5.10.7. Часы реального времени и СМО5-память


В каждом компьютере есть микросхема, отвечающая за поддер
жку текущей
даты и времени. Для того чтобы значения не сбрасывались при
каждом выключе-
нии питания, на микросхеме расположена небольшая область
памяти (от.64 до
128 байт), выполненная по технологии СМО5, позволяющей
снизить энергопот-
ребление до минимума (фактически энергия в таких схемах затрачи
вается только
на зарядку паразитных емкостей при изменении состояния ячеек
памяти), Мик-
росхема получает питание от аккумулятора, расположенного на
материнской пла-
те, и не отключается при выключении компьютера. Для хранения
собственно вре-
мени достаточно всего 14 байт такой энергонезависимой памяти,
и остальная ее
часть используется ВТО$, чтобы хранить различную информ
ацию, необходимую
для корректного запуска компьютера. Для общения с СМО$
и регистрами ВТС.
выделяются порты ввода-вывода от 70 до 7ЕБ, но только назнач
ение портов 708
и 71 одинаково для всех материнских плат.
Порт 70 для записи: индекс для выбора регистра СМО$З;:
бит 7: прерывание ММТ запрещено на время чтения/записи
бит 6: собственно индекс
Порт 71 для чтения и записи: данные СМО5
После записи в порт 708 нужно осуществить запись или чтение
из порта 71Ъ,.
иначе ВТС окажется в неопределенном состоянии. Содержимое
регистров СМО$
варьируется для разных В105, но первые ЗЗВ регистра обычно
выполняют следу-
ющие функции: о
001: ВТС: текущая секунда (00-596 или 00-ЗВВ) — формат выбирае
тся регист-
ром ОВЬ, по умолчанию - ВСО | |
018: ВТС: секунды будильника (00-591 или 00-ЗВВ или ОЕ ЕВ (любая
секунда).
021: ВТС: текущая минута (00-598 или 00-ЗВВ) р
031: ВТС: минуты будильника (00-59% или 00-ЗВЬ или ЕЕЬ)
04: ВТС: текущий час;
00-235/00-17Ь (24-часовой режим) ,
'01-125/01-1СЬ (12-часовой режим до полудня)
. 811-92,/81-8СВ (12-часовой режим после полудня)
055: ВТС: часы будильника (то же или Е ЕВ, если любой час).
06Ъ: ВТС: текущий день недели (1-7, 1 -— воскресенье)
07В: ВТС: текущий день месяца (01-315/015-1ЕЪ)
08Ъ: ЕТС: текущий месяц (01-126/01-0СЬ)
ОЭЬ: ВТС: текущий год (00-996/00—63Ь)
Программирование на уровне портов
САБ: ВТС: регистр состояния А
бит:7: 1 - часы заняты (происходит обновление)
биты 4-6: делитель фазы (010— 32 768 кГц — по умолчанию)
биты 3-0: выбор частоты периодического прерывания...
0000 — выключено _
0011 - 122 мкс (минимум)
1111 — 500 мс
0110 —976,562 мкс (1024 Гщ)
оВЬ: ВТС: регистр состояния В.
зна-
бит 7: запрещено обновление часов (устанавливают перед записью новых
чений в регистры даты и часов)
бит 6: вызов периодического прерывания (808)
бит 5: вызов прерывания при срабатывании будильника.
бит 4: вызов прерывания по окончании обновления времени |
‚ бит 3: включена генерация прямоугольных. импульсов
бит 2: 1/0: формат даты и времени двоичный/ВСО
_ бит 1: 1/0; 24-часовой/ 12-часовой режим
бит 0: автоматический Переход на летнее время в апреле и октябре
ось только для чтения: ЕТС: регистр. состояния с м
`\
бит 7: произошло прерывание
бит 6: разрешено периодическое прерывание
бит 5: разрешено прерывание от будильника
бит 4: разрешено прерывание по окончании обновления часов
ООВ только для чтения: регистр состояния }®)
бит 7: питание КТС/СМО$ есть
ОЕБ: результат работы РОЗТ при последнем старте компьютера: `
| бит 7: КТС сбросились. из-за отсутствия питания СМО$
` бит 6: неверная контрольная сумма смо5- конфигурации
бит 5: неверная конфигурация
бит 4: размер памяти не совнадает с записанным в конфигурации
бит 3: ошибка инициализации первого жесткого диска
бит 2: ЕТС-время установлено. неверно (например, 30 февраля)
перезагрузкой
ОЕВ: состояние, в котором находился компьютер перед последней
00 — Си-АК-Ое!, 05 — 1МТ 19, ОА, ОВЬ, ОСЬ - ар, ге, гей на адрес, хра-
что перезагрузка про-
нящийся в 00401: 00678. Другие значения указывают,
изошла в ходе РОЗТ или в других необычных условиях
10Ъ: тип дисководов (биты 7-4 и 3—0 — типы первого и` второго дисковода)
0000Ъ — отсутствует.
0001- 360 Кб
0010Ъ - 1,2 Мб
0011Ъ - 720 Кб
0100 - 1,44 Мб
0101Ъ - 2,88 Мб
/ | |
р

ЕЕ ИНОЕ! Сложные приемы программирований


128: тип жестких дисков (биты 7-4 и 3—0 - типы первого и второго жестких дис-
ков, 1111Ъ, если номер типа больше 15)
14: байт состояния оборудования
биты 7-6: число установленных жестких дисков минус один _ |
биты 5-4: тип монитора (00, 01, 10, 11 = ЕСА/УСА, 4025 ССА, 80х25 ССА, МРА)
бит 3: монитор присутствует
бит 2: клавиатура присутствует
бит 1: ЕРУ присутствует
бит 0: дисковод присутствует.
15Ъ: младший байт размера базовой памяти в килобайтах (805).
161: старший байт размера базовой памяти в килобайтах (025)
17В: младший байт размера дополнительной памяти (выше 1 Мб) в килобайтах
18}: старший байт размера дополнительной памяти (выше 1 Мб) в килобайтах
191: тип первого жесткого диска, если больше 15 ``
1АБ: тип второго жесткого диска, если больше 15
2ЕЪ: старший байт контрольной суммы регистров 106 — 2РЬ _-
2ЕЪ: младший байт контрольной суммы регистров 105 — 20
ЗОВ: младший байт найденной при РОЗТ дополнительной памяти в килобайтах
31: старший байт найденной при РОЗТ дополнительной памяти в килобайтах
32Ь: первые две цифры года в ВСР-формате
Данные о конфигурации, хранящиеся в защищенной контрольной суммой об-
ласти, бывают нужны достаточно редко, а для простых операций с часами реаль-
’ ного времени и будильником удобно использовать прерывание В1О$ 1АК. Одна-
ко, программируя ЕТС на уровне портов, можно активизировать периодическое
прерывание - режим, в котором ВТС вызывает прерывание 1808 с заданной ча-
стотой, что позволяет оставить 1В.О0 для работы системы, если вас удовлетворя-
ет ограниченный выбор частот периодического прерывания. В качестве примера
посмотрим, как выполняются чтение и запись в СМО$-память, =
; ГЕСЕНе.
ат
‚ Вывод на экран текущей даты и времени из ВТС.

.то9е1 11пу
‚ соде
. 186 ‚ Для эНг а1,4.
ог9 1001 : ; СОМ-программа.
эТаге:
оу а1, ВВ ; С№05.08№ - управляющий регистр. В.
ош . 701, а] ; Порт 70в - индекс СМ0$.._ и
п а,7 ; Порт 71й - данные СМ0$. |
апа а1, 11111011 ; Обнулить бит 2 (форма чисел - ВСБ)
от 71Н, а1 ‚ и записать обратно. :
е `` а1,32' — $ 0№0$ .32н - две старшие цифры. геда. '
са11 ри1п*_стоз ; Вывод на экран. АН:
пом а1,9 .` С№0$. 091 - две младшие цифры. года.
Программирование. на уровне портов | 3
; сай рее спо8
поу а], '-’. 2} Нину.
11 298 ‹ Вывод на экран,
по а1.8 ; СМ0$ 081 - текущий месяц.
‚са11 — рг1пЕ спо | |
МОУ а}, ' -' ; Еще один минус.
17 298 |
мочу а1,7 ; 6м05 07н - день.
са1] ` рг1п_стоз `
ОУ а1,’°°. ; Пробел.
101 291 --
моу а], 4 __; 640$ 04 - час.
` са11 реп _стоз |
| ° оу а]. |’ °; Буква “М”. ^
1 29 ` -
то\ а1;’'. ; Пробел.
ие 291 . : ,
_ МОУ а1,2: су 6М0$ 021. - минута.
са11 реп _стоз т
му 1 а1,':' `_ ; Двоеточие.
м 29 о о
у‘ а,08 . $ СМ05 О0н - секунда.
са11 рг1л*_стоз ` р '
гет
; Процедура рг1пт_стоз.
‚ Выводит на экран содержимое ячейки СМО$ с номером в АЕ.
; Считает, что число, читаемое из СМ0$, находится в формате ВС0.
рг1п*_сто$ ргос пеаг
. о 701, а} ; Послать АС в индексный порт СМ05.
п а], 71И ; Прочитать данные.
‚ РизВ ах
ЭГ - а!, 4 . Выделить старшие четыре бита.
299 21, '0’ ‚ ; Добавить АЗСТТ-код цифры 0.
1% 298 _ .; Вывести на экран.
рор ах |
апб а}, ОП ; Выделить младшие четыре бита.
а99 21, Зов ; Добавить АЗСТТ-код цифры 0.
пт 2 ; Вывести на экран.
` . . . . 1
ге

рг1пе_сто$ епбр ,
епа зтагт

5.10.8. Звуковые платы _


Звуковые платы; совместимые с теми или иными моделями Зоипа В1азбег,
ВЫГЛЯДЯТ как четыре независимых устройства:

счи-
оо5$Р (Бизна! Зета] Ргосеззог) — устройство, позволяющее выводить и
тывать оцифрованный звук;
О микшер (№!хег) — система регуляторов громкости для всех каналов платы;
ШВ! — Сложные приемы программирования
ОЕМ (Егедиепсу Моданоп) или АЗГЛЬ (по названию первой звуковой пла-
ты) — устройство, позволяющее синтезировать звук из синусоидальных
и треугольных волн. Слова типа ОРТ.2 или ОРЗ в описании платы -— это
и есть номера версии используемого ЕМ-синтезатора;
Я МТ! (Мизес пягатерёа1 Олена! Ницегасе) — стандартный интерфейс пере-
дачи данных в музыкальной аппаратуре. Но в нашем случае рассматривает-
ся СМШГ (обобщенный МТО- более качественная система генерации му-
зыки, в которой используются не искусственные синусоидальные сигналы,
а образцы звучания различных инструментов. К сожалению, качество этих
образцов в большинстве дешевых плат оставляет желать лучшего.
Номера портов ввода-вывода, предоставляющих доступ ко всем этим устрой-
ствам, отчитываются от базового порта, обычно равного 2201, но допускаются.
также конфигурации с 210, 2308,.240}, 2505, 2601 и 2808. Кроме того, интерфейс
‹ СМ!Гиспользует другую серию портов, которая может начинаться как с 3001,
так и с 330. В описаниях портов мы будем считать, что базовыми являются 2208
и 3008. Область портов интерфейса с АЧТЛЬ начинается с 3888.
Существует большое число модификаций плат Зоип@ Вазег, отличающихся,
помимо всего прочего, набором поддерживаемых команд и портов ввода-вывода.
После названия каждой команды или порта мы будем указывать сокращенное
название платы, начиная с которой эта команда или порт поддерживается:
ОЗВ- боиоа ВЙазвет 1.0;
а58В2- боцла ВЁьжег 2.0;
о $ВРго — боипа Вазбег Рго;
о $ВРго2 - $оипа В]а%ег Рто2;
/ 95816 - боипа Еазбет 16;
ОАЗР - Зоип4 Вв&ег 16 А$Р;.
С АМУЕ — Зоцпа ВЙаег АХЕЗ2.
Программирование О$Р
‚ Цифровой процессор — наиболее важная часть звуковой платы. Именно с его
помощью осуществляется вывод обычного оцифрованного звука, так же как и за-
пись звука из внешнего источника в файл. Для своей работы, помимо описывае-
мых в этом разделе портов, О5Р использует прерывания и контроллер прямого
доступа к памяти ОМА. Программирование ОМА с примером программы, ис-
пользующей его для воспроизведения звука, мы рассмотрим в разделе 5.10.9.
ОЗР обслуживается при помощи следующих портов:
226 для записи: сброс О$Р ($5В)`
Запись в этот порт осуществляет полную переинициализацию ОЗР, прерывая
все происходящие процессы. Операцию сброса О5Р необходимо выполнить, по
крайней мере, один раз после перезагрузки системы, чтобы его можно было ис-
пользовать.
Процедура сброса осуществляется следующим образом:
1. В порт 226Ъ записывается число 1 (начало инициализации).
2. Выдерживаётся пауза как минимум 3,3 мкс.
Программирование на уровне портов — |]
3. В порт 2268, записывается число 0 (конец инициализации).
4. Выдерживается пауза максимум 100 мкс. В течение паузы можно выполнять
_ чтение порта 22Е. Когда в считываемом числе будет установлен бит 7 (дан-
ные готовы), можно сразу переходить к нункту 5. В противном случае имеет
смысл повторить ‘процедуру, используя ‘другой базовый порт.
‚ 5, Выполняется чтение из порта 22АЬ. Если считанное число равно (ААВ — ОЗР
был успешно инициализирован. В противном случае допускается/вернуться
к пункту 4, но по истечении 100 мкс после записи в 226} можно будет с уверен-
ностью сказать, что О$Рс базовым адресом 220} не существует!или не работает.
АВ для чтения: чтение данных из РР (5В)
Чтение из этого порта используется для передачи всех возможных данных от
О5Р программам. Процедура чтения состоит из двух шагов:
1. Выполнять цикл чтения порта 22ЕВ, пока бит 7 считываемого байта. Не ока-
жется равным единице.
`2, Выполнить чтение из порта 22АВ.
22СЁ для записи: запись данных и команд ОР (начиная с5В)
Этот единственный порт используется для передачи всего множества команд
ОЗР и для пересылки в него данных (аргументов команд). Процедура.заниси:
1. Выполнять цикл чтения порта 22СЬ, пока бит 7 считываемого байта не ока-
жется равным нулю.
2. Выполнить запись в порт 226.
22СЁ для чтения: готовность ОЗР для приема команды (5В)
Если при чтении из этого порта бит 7 сброшен в ноль— ОР готов к приему оче-
`редного: байта. в порт 22СЬ на запись. Значение остальных битов не определено.
22ЕЙ для чтения: готовность О$Р для посылки данных (начиная с 5В)
Если при чтении из этого порта.бит 7 установлен в единицу—‚ ОЗР готовх пере-
даче через порт 22АВ очередного байта.
22ЕЙ для чтения (тот'же порт): подтверждение обработки 8битного прерыва-
ния ($58) ,
Обработчик прерывания, ‘сгенерированного звуковой платой по. окончании
8-битной операции, обязательно должен выполнить одно чтение из этого порта
перед завершением (помимо обычной процедуры 1посылки сигнала ЕО] в соответ-
ствующий контроллер прерываний).
22ЕВ для чтения: подтверждение обработки 16- ‘битного прерывания (5816)
Обработчик |прерывания, сгенерированного звуковбй платой по окончании
16-битной операции, обязательно должен выполнить одно чтение из этого пор-
та перед завершением (помимо обычной процедуры ‘посылки сигнала ЕО] в со-
ответствующий контроллер прерываний).
Теперь рассмотрим команды ОЗР. Все они пересылаются В звуковую плату че-
рез порт 22СВ, как описано выше. После команды могут следовать аргументы,
+

[32 СТИ Сложные приёмы программировани


я
которые передаются таким же
образом (включая ожидание гото
команды). вности к приему
`
041: состояние О5Р (устаревшая)
($В2 - ЗВРго2)
Возвращает информацию о тек
ущей операции ОЗР:
бит 0: динамик включен
бит 1: стерео АЦП включен ,
бит 2: всегда 0
бит 3: происходит прямое воспроизведение 8-би
бит тного РСМ
4: происходитвоспроизведение 2-битного АОР
бит 5: происходит СМ через ОМА
воспроизведение 2,6-битного АБР
бит 6: происходит СМ через РМА
воспроизведение 4-битного АОРСМ
бит 7: происходит через ОМА _
воспроизведение 8-битного РСМ
через ОМА
106, ММ: прямое воспроизведение
8-бйтного звука (5В)
Выводит очередной байт (ММ) |
из несжатого 8-битного оцифро
воспроизведение. При. использов ванного звука на
ании этого способа воспроизведе
грамма должна заботиться о том, ния сама про-
чтобы новые данные всегда.бы
есть не считывать их с диска в ходе ли наготове (то
работы) и чтобы байты пересылал
с необходимой частотой. (В этом ись в ОЗР
режиме поддерживаются частоты
до 23 кр.)
1. Вывести в О5Р команду 10[
и очередной байт из оцифровки.
2. Подождать необходимое врем
я и вернуться к пункту 1.
Чтобы выполнять пересылку байт
ов с заданной частотой, обычно
раммируют системный таймер, как перепрог-
будет показано в конце этого раздела.
за ограничений по качеству звук Но из-
а и ВЫСОКОЙ ресурсоемкости
произведения практически такой способ вос-
не используется.
14Ъ, ГО, НГ: прямое воспроизведе
ние 8-битного РСМ через ОМА
Начинает процесс воспроизведения СВ)
данных, на которые настроен соотве
щий канал ОМА (см. раздел тствую-
5.10.9):
ан :
1. Установить обработчик прерывани
я от звуковой платы (и разрешить
в контроллере прерываний). его
‚ Выполнить команду 408 или друг о
им образом установить частоту оциф
. Выполнить команду ОО1Ь (включ ровки.
ить динамик). ` |
. Настроить ОМА (режим 48В +
номер канала).
ль - Выполнить команду 146. Аргументы :
ГО и НТ — Это младший и старший бай-
ты длины проигрываемого Участка
минус один, ^^ В
[>]‚ Из обработчика пре
рывания подтвердить его чтением
кой байта. 20} в соответст порта 22 ЕВ и посылЛ-.
вующий контроллер прерываний.
7. Выполнить команду 0ОЗЬ (вы
ключить динамик).
На платах, начиная с 5816, для
этого режима рекомендуется поль
мандами 0С?Ь, зоваться ко-
|
Программирование на уровне портов

166; ТО, НЕ прямое воспроизведение 2-битного АОРСМ через ОМА ($5В)


Начинает процесс воспроизведения данных‘аналогично команде 148, но они долж-
ны храниться в сжатом формате Сгеануе АОРСМ 2.Ы&. Длина, указываемая в каче-
‘стве аргументов этой команды, равна (число_ байтов + 2)/4. В качестве нулевого.
байта в процедуре распаковки АРРСМ используется значение, которое применя-
лось последней командой 17В. В остальном процедура воспроизведения аналогич-
на команде 14В..
17Ь, ГО, НТ: прямое воспроизведение 2-битного АБРСМ через ОМА сновым ну-
левым байтом (58) ^
То же самое, что и 16}, но ‚первый байт из данных ‹ будет рассматриваться как ну-
левой байт для процедуры распаковки АБРСМ.
1СВ: воспроизведение 8-битного РСМ через ОМА с автоинициализацией ($82)
Начинает режим воспроизведения с автоинициализацией — лучший из режимов,
предлагаемых звуковыми платами. В этом режиме ОЗР. воспроизводит в цикле
содержимое указанного участка памяти, мгновенно возвращаясь на начало, пока
он не будет остановлен командой ООАВ или новой командой воспроизведения
через ОМА. Весь секрет заключается в том, что плата генерирует прерывание не
только при достижении конца блока; но и при достижении его середины. Таким
образом, пока ОЗР проигрывает вторую половину буфера, мы можем прочитать
следующие несколько килобайтов в первую половину, не останавливая воспроиз-
ведение ни на миг. `
Г. Установить обработчик прерывания звуковой платы и разрешить его в кон-
троллере прерываний.
2. Выполнить команду 40} или другим образом установить частоту оцифровки.
3. Выполнить команду 48 |
(установить размер ОМА-буфера = (число_байтов + 1/2 _ 1).
4. Выполнить команду ОО1В (включить динамик).
5. Настроить ОМА (режим 58В + номер ханала).
6. Выполнить команду 1СКВ. |
7. В обработчике прерывания: заполнить. следующую половину буфера. .
8. В обработчике прерывания: подтвердить прерывание чтением из 22ЕЬ и за-
писью 208 в контроллер прерываний.
9. Подождать, пока не будут воспроизведены все данные.
10. Выполнить команду ОРЗЬ (выключить динамик). ‚
11. Выполнить команду ОР0В (остановить 8-битную ОМА-передачу).
12. Выполнить команду ОБАК (завершить режим автоинициализации).
13. Выполнить команду оров (остановить 8-битную ОМА-передачу).
На платах, начиная с 5816; для этогоо режима рекомендуется пользоваться ко-
мандами 0С?Н. ,
1ЕЪ: воспроизведение 2-битного. АОРСМ через РМА с автоинициализацией
(582).
344 Г ТТР Сложные приемы программирования
Аналог команды 1СВ, но данные хранятся в 2-битном формате АОРСМ с нуле-
вым байтом. Длина блока рассчитывается так: |
длина = (число_байтов + 3)/4.+ 1
длина блока = (длина + 1)/2 - 1
208: прямое чтение 8-битных данных из АЦП ($В)
Команда предназначена для чтения оцифрованного звука из внешнего источни-
ка. Используется следующая процедура:
1. Выполнить команду 208.
2. Прочитать очередной байт. .
`3. Нодождать необходимое. время и вернуться к пункту 1.
Проблемы с этой командой точно такие. же, как ис10Ъ.
245, 10, НИ. чтение 8-битного РСМ через ОМА (5В)
Аналог команды 146, но выполняет не воспроизведение, а запись звука. Последо-
вательность действий идентична случаю с 141, но используемый режим ОМА
-—
44В + номер канала. 7 |
2СЬ: запись 8-битного РСМ через ЦМАс автоинициализацией ($В2)
Аналог команды 1СВ, но выполняет не воспроизведенис, а запись звука. Последо-
вательность действий идентична случаю с 1СВ, но используемый режим ОМА -
541 + номер канала. |
З0В: прямое чтение М (5$В)
Выполняет чтение очередного МТПО1-события:
й

1. Выполнить команду 30Ъ.


2. Прочитать МТО]-событие
(до 64 байт).
З1Ь: чтение МПГ с прерыванием (5В)
Включает генерацию прерывания от звуковой платы при поступлении нового
МТОГ-события. Для этого необходимо:
1. Установить обработчик прерывания.
2. Выполнить команду 316.
3. В обработчике прерывания: прочитать МТО/-событие.
4. В обработчике прерывания: подтвердить прерывание чтением из 22ЕВ и за-
писью 20р в контроллер прерываний.
5. Выполнить команду 31В еще раз, чтобы отменить генерацию прерывания.
328: прямое чтение МТО]-события с дельта-временем. (5В)
Выполняет чтение очередного МТО]-события и 24-битного дельта-времени; то
есть времени в микросекундах, наступившего после предшествующего МТО]-со-
бытия. (Считываются данные в следующем порядке: младщий байт времени,
средний байт времени, старший байт времени, МТОГ-команда.) Именно в виде `
последовательности М Т-событий, перед каждым из которых указано дельта-^
время, и записывается музыка в МПУ1-файлах. |
Программирование на уровне портов ик

325: чтение МТОТ-события с дельта-временем с прерыванием (В)


‚ Включает/выключает генерацию прерываний от звуковой платы аналогично ко-
мандеЗ1В, но при чтении МТО-события передаются вместе с дельта-временами,
как в команде 32В.
ЗВ: режим прямого доступа к ОАВТ ($82) `
Отключает О$Р; после чего все. команды записи/чтения. в его порты (используя
тот же мехайизм проверки готовности) рассматриваются как МТО[-события. Вы-
вести О$Р из этого режима можно только с помощью полной переинициализации.
37Ь: режим прямого доступа к ЧАКТ с прерыванием (582). р
Переключает порты ОЗР на ОАВТ аналогично команде 341, но каждый раз, ког-
да новое МПУ-событие готово для чтения, вызывается прерывание звуковой
платы.
38В,МШ: прямая:‚зались ми в
Посылает одно МШ/Г-событие.
405, ТС: установить временную константу (5В)
Устанавливает частоту оцифровки, используя однобайтную константу, рассчиты-
ваемую следующим образом:
ТС- 256- (1000000 / (число_каналов Х частота)),
где число. каналов — 1 для моно и 2 для стерео.
41В, ГО, НЕ установить частоту оцифровки (5816)
Аналогично 401, но указывается истинное значение частоты (сначала младший,
потом старший байты). Число ‘каналов определяется автоматически. Реальная
частота тем не менее округляется до ближайшего возможного значения ТС.
45Б: продолжить. остановленнбе 8- битное воспроизведение через ОМА ($816)
Продолжает остановленное командой ОРАВ воспроизведение 8-битного звука
через ОМА с автоинициализацией.

АТЬ: продолжить остановленное 16-битное воспроизведение через ОМА (5816)


Продолжает остановленное командой ор9ь воспроизведение 16-битного звука
через ОМА с автоинициализацией. :

48Ъ, ТО, НГ: установить размер буфера ОМА. ($82).


Устанавливает число байтов минус один для следующей команды передачи через
ОМА (сначала младший байт, затем старший).
74, 10, НГ: прямое воспроизведение: 4-битного АОРСМ через ОМА (5В)
Аналог 16}, но используется 4-битный вариант формата СтеаНуе АОРСМ.

158, ГО, НИ: прямое воспроизведение 4-битного АОРСМ через ОМА с новым ну-
левым байтом (5В)
Аналог 17Ъ, но используется 4-битный вариант формата. Стеайуе АБРСМ.
ЕРТИНИИШИИИИИ Сложные приемы программирования
76, ГО, НИ: прямое воспроизведение 2,6-б
итного АОРСМ через ОМА (58)
Аналог 16}, но используется 2,6-битный вариа
нт формата СтеаНуе АБРСМ.
77, ТО, НГ: прямое воспроизведение 2,6-б
итного АОРСМ через ОМА с новым.
нулевым байтом (5В)
Аналог 17, но используется 2,6-битный
вариант формата СтеаНуе АОРСМ.
ПТ: воспроизведение 4-битного А,РСМ
через ОМА с автоинициализацией ($82)
Аналог 1ЕВ, но используется 4-битный вариант формата СгеаНуе АОР
СМ.
7ЕЪ: воспроизведение 2,6-битного АОРСМ через
ОМА с автоинициализацией (582).
Аналог 1Е1, но используется 2,6-битный вариа
нт формата Стеануе АОРСМ. |
808, 10, НТ: заглушить ОЗР (5В)
Вывести указанное число байтов тишины
с текущей частотой оцифровки. \
0В?5/0С?Ь МОРЕ, 10, НТ: обобщенный инте
рфейс к О5Р ($816)
Команды 0В?. используются для 16-битны
х операций, команды ОСЗ — для
8-битных. Младшие четыре бита определя
ют режим:
’ бито: всегда 0
бит 1: используется ЕГЕО о
бит 2: используется автоинициализация ОМА
бит 3: направление передачи (0 -— воспроизве |
дение, 1 — оцифровка)
Аргументы этой команды -— режим, младший
байт длины, стар ший байт дли-
ны (перед указанной командой не требуется
устанавливать размер ОМА-буфера
специально). | | — |
В байте режима определены всего два бита (оста
льные должны быть равны нулю):
бит 4: данные рассматриваются как числа со
знаком
бит 5: режим стерео `
Длина во всех случаях равна числу байтов
минус один для 8-битных операций
и числу слов минус один для 16-битных.
х
0008: остановить 8-битную ОМА-операцию
(5В)
Останавливает простую (без автоинициали
зации) 8-битную ОМА-операцию.
001: включить динамик ($В)
Разрешает работу выхода на динамик (коло
нки и т. д.).
После сброса ОР этот канал выключен.
0131: выключить динамик ({5В)
Отключает выход на динамик (колонки ит.
д.).
ОП4В: продолжить 8-битную ОМА-операцию
(В) — ,
Продолжает ОМА-операцию, остановленную
командой 0О0В. В
0051: остановить 16-битную ОМА-операцию
(5В)` о.
Останавливает простую (без автоинициализаци
и).16-битную РМА-операцию. —.
9061: продолжить 16-битную ОМА-операцию
(58)
Продолжает РМА-операцию, остановленную
командой 005...
Программирование на уровне портов
008}: определить состояние динамика (5В)=
Возвращает О0Ъ, если динамик выключен; ЕВ, если включен.
ООН: завершить 16-битную ОМА-операцию с автоинициализацией ($816)
Эта команда завершает операцию только после окончания воспроизведения теку-
щего блока. Для немедленного прекращения воспроизведения необходимо выпол-
нить последовательно команды ООЗВЬ, 005Ъ, ОТВ и 0058.
ОПАН: завершить 8-битную ОМА-операцию ‹ автоинициализацией (582)
Аналог 009, но для 8-битных операций.
ОЕбЬ, ВУТЕ: проверка наличия ОЗР на этом порту ($В2)^
Любой байт, посланный как аргумент к этой команде, возвращается при чтении из
ОБР в виде своего побитового дополнения (О5Р выполняет над ним операцию МОТ).
ОЕ1В: определение номера версии О5Р (5В)
Возвращает последовательно старший ит младший номера версии Р5Р:
1.? - В
2.0- $82 | | ` | .-
3.0 - ЗВРго : В
3.2? - $ВРго2
4.0? - $816
4.11 - 53В16 $651-2
4.12 - А\ЕЗ2
ОЕЗЬ: чтение СоруцевЕ О5Р (5$ВРго2)
Возвращает АЗСТ7-строку с информацией Сорупё данной платы.
ОБЬ, ВУТЕ: запись в тестовый регистр (5В2)
Помещает байт в специальный неиспользуемый регистр, который сохраняется
даже после переинициализации ОР
ОЕ8В: чтение из тестового регистра ($82)
‚ Возвращает байт, помещенный ранее в тестовый регистр командой ОЕАЬ.
ОЕОН: генерация синусоидального ситила ($В)
Запускает О$Р на воспроизведение синусоидального сигнала с частотой около
2 кГц, который можно прервать только сбросом ОЗР.
0Е21: запрос на прерывание в 8-битном режиме ($8)
Генерирует прерывание от звуковой карты. В качестве подтверждения от обработ-
чика ожидается чтение из порта 22ЕБ.
ОЕЗЬ: запрос на прерывание в 16-битном режиме (СВ) ,
Генерирует прерывание от звуковой карты. В качестве подтверждения от обработ-
чика ожидается чтение из порта 22ЕВ. |
ОЕВЬ: состояние О$Р. (5816).
Возвращает ‘байт состояния текущей О$Р-операции:
бит 0: 8-битное воспроизведение через ОМА
бит 1: 8-битное чтение через ОМА
|
1
ии Сложные приемы. программирования {

бит 2: 16-битное воспроизведение через ОМА `


бит 3: 16-битное чтение через ОМА
|
‚ бит 4: динамик включен
биты 5—6: не определены ..
бит 7: ТС модифицирована (может быть ноль, если предыдущая команда 40
пыталась установить неноддерживаемую частоту)
ОЕ Сь:.дополнительная информация ($5816) |
Возвращает. дополнительный байт состояния текущей ОМА- “операции:
- бит 1: синхронный режим (одновременная запись и воспроизведение)
бит 2: 8-битный режим с автоинициализацией
бит4: 16-битный режим с автоинициализацией
0ЕОБ: последняя выполненная команда (5816)
Возвращает последнюю успешную команду ОЗР

Программирование микшера ,
Это устройство предназначено для регулирования громкости на всех каналах,
используемый звуковой платой.
Для управления микшером служат всего два порта ввода-вывода.
224й для записи: выбор регистра микшера (5ВРго)
Запись в этот порт выбирает номер регистра, к которому будет осуществляться
доступ при последующих обращениях к порту 2256.
2258 для чтения и записи: чтениё/запись регистра микшера (5ВРго) |
Чтение и запись в этот порт приводят к чтению и записи в соответствующий ре-
гистр микшера. Рассмотрим их назначение.
Регистр 00 для записи: сброс и инициализация (5ВРго)
Выбор этого регистра в порту 2241 начинает инициализацию. Следует подождать
как минимум 100 мкс, а затем записать в порт 225} число 01} (команда «завер-.
шить инициализацию»). , ‘

Регистр 01 для чтения: состояние. микшера (ЗВРго)


Возвращает последний номер регистра.
Регистр 04 для чтения и‘записи: уровень ЦАП (5ВРго)
биты-4-0: уровень правого ЦАП
биты 7-4: уровень левого ЦАП
Регистр ФАВ для чтения и записи: уровень микрофона (5ВРго)
биты 2-0: уровень микрофона
Регистр 22В для чтения и записи: общий уровень (5ВРго)
биты 4-0: правый общий уровень
биты 7-4: левый общий уровень
Программирование на уровне портов МНЕ
Регистр 26Ъ для чтения и записи: уровень ЕМ {5ВЕго)
биты 4-0: правый уровень ЕМ
биты 7-4: левый уровень ЕМ
Регистр 288 для чтения и заниси: уровень СО аидю (ЗВРго)
биты 4-0: правый уровень СО аи4ю
биты 7—4: левый уровень СО аидю
Регистр 2ЕВ для чтения и записи: уровень линейного входа (ЗВРго)
биты 4-0: уровень правого линейного входа
биты 7—4: уровень левого линейного входа
Регистр З0В для чтения и ‘записи: левый общий уровень (5816)
биты 7-1: левый общий уровень Ра

Регистр З4В для чтения и записи: правый общий уровень ($816)


биты 7-1: правый общий уровень
Регистр 328 для чтения и записи: левый уровень ЦАП ($5816)
биты 7-1: левый уровень ЦАП
Регистр ЗЗЬ для чтения и записи: правый уровень ЦАП ($816)
биты 7-1: правый уровень. ЦАП
Регистр ЗАВ для чтения и записи: левый уровень ЕМ ($816)
биты 7-1: левый уровень ЕМ
Регистр 358 для чтения и записи: правый уровень ‚ЕМ (5816)
биты 7-1: правый уровень ЕМ
Регистр З6Ь для чтения и записи; левый уровень ср аи4д1ю ($816)
‘биты 7-1: левый уровень СО аиао. _
Регистр З7Ь для чтения и записи: правый уровень СО амф ($816)
биты 7-1: правый уровень СО ао
Регистр 388 для чтения и записи: левый уровень линейного входа ($816)
биты 7-1: левый уровень линейного входа
Регистр З9В для чтения и записи: правый уровень линейного входа (5816)
биты 7-1: правый уровень линейного входа :
Регистр ЗАВ для чтения и записи: уровень микрофона ($816) |
биты 7-3: уровень микрофона :
Регистр ЗВЬ для чтения и записи: уровень динамика РС (5816)
биты 7-5: уровень динамика РС
Регистр ЗСЬ для чтения и записи: управление выводом (5В16)
бит 0: микрофон включён
бит 1: правый канал СО аи10 включен
бит 2: левый канал СО аидю включен
Ш! Сложные приемы программирования
бит 3: правый канал линейного входа включен
бит4:левый канал линейного входа включен
биты 7-5: нули
Регистр ЗРВ для чтения и записи: управление левым каналом ввода (5816)
бит 0: микрофон включен у
бит 1: правый канал СО аи4ю включен
бит 2: левый канал СО аи10 включен
бит 3: правый канал линейного входа включен
бит 4: левый канал линейного входа включен
бит 5: правый канал ЕМ включен
бит 6; левый канал ЕМ включен
бит 7: нуль -
Регистр ЗЕВ для чтения и записи: управление правым каналом ввода (5816)
° бит 0: микрофон включен:
бит 1: правый канал СО аиаю включен
бит 2: левый канал СО аи4ю включен | ОИ
бит 3: правый канал линейного входа включен ` ‚ *
бит 4: левый канал линейного входа включен |
бит 5: правый канал ЕМ.включен
бит 6: левый канал ЕМ включен
бит 7: нуль
Регистр ЗЕВ для чтения и записи: уровень усиления в левом канале ввода ($816).
биты 7-5: усиление в левом канале ввода
| Регистр 408 для чтения и записи: уровень усиления в правом канале ввода (5816)
биты 7—5: усиление в правом канале ввода
Регистр А1В для чтенияи записи: уровень усиления в левом канале вывода (5816)
биты 7-5: усиление в левом канале вывода -. .
Регистр 428 для чтения и записи: уровень усиления в правом канале вывода ($816)
биты 7-5; усилениев правом канале вывода :.
Регистр АЗВ для чтения и записи; автоматическая подстройка усиления (5816).
бит 0: автоматическая подстройка усиления включена
Регистр 44В для чтения и записи: уровень усиления высоких частот слева (5816)
биты 7-4: усиление высоких частот слева в
Регистр 45В для чтения и записи: уровень усиления высоких частот справа ($816)
биты 7-4: усиление высоких частот справа -` |
Регистр 46 для чтения и записи: уровень усиления басов слева ($816)
биты 7-4: усиление басов слева | В
Регистр 47Ь для чтения и записи: уровень усиления басов справа (381 6)
биты 7-4: усиление басов справа >’ ео
Программирование на уровне портов ПМ
Регистр 808 для чтения и записи; выбор прерывания (516)
бит 0: 1802 -
бит 1: 05
бит 2: ВО7
бит 3: [КО10
биты 7—4: всегда 1
Эта установка сохраняется при сбросе микшера или даже при «горячей» пере-
загрузке компьютера.
Регистр 818 для чтения и записи: выбор БМААви
бит0: 8-битный МАО
^ бит1:8-битный ОМА!
бит2:0 |
бит3: 8-битный МАЗ
бит 4: 0
_ бит 5: 16-битный ОМА5
бит 6: 16-битный ОМАб
‘бит 7: 16-битный ОМА7
Данная установка сохраняется при сбросе микшера ‘или даже при' ‘«горячей»
перезагрузке компьютера. .
Регистр 828 для чтения: состояние прерывания ($В16)
бит 0: происходит обраротка прерывания от 8-битной опёрации
бит 2: происходит обработка прерывания от 16-битной операции
бит 3: происходит обработка прерывания операции МРО- 401
биты Л-—4: зарезервированы о
Частотный синтез (программирование АЧНЬ)
Синтезатор, расположенный на звуковой плате и отвечающий за ЕМ- -музы-
ку, управляется тремя портами— портом состояния, выбора регистра и портом
данных. Для совместимости с различными платами они дублируются несколь-
ко раз.
‚ 2288, З88Ё для чтения: порт состояния ЕМ (58)
2208 для чтения: порт состояния левого канала ЕМ ($ВРго)
2224, ЗВАЙ для чтения: порт состояния правого канала ЕМ (ЗВРю) _
Определяет, закончился ли отсчет ЕМ-таймеров и какого именно.
биты 4-0: всегда 0
бит 5: таймер 2 (период— 230 мкс).срабетал
бит 6; таймер 1(период- 80 мкс) сработал
бит: один из таймеров сработал
228}, 388Ё для записи: выбор регистра ЕМ (В). ,
2208 для записи: выбор рёгистра левого канала ЕМ (ЗВРюо)
2224, ЗВАЙ для записи: выбор регистра правого канала ЕМ ($ВРго)
° Запись числа в этот порт выбирает, с каким регистром синтезатора будут ра-
ботать последующие команды записи в порт данных.
ЕЕРИИМИШИШИИ | — Сложные приемы программирования
Процедура записи числа в регистр ЕМ выглядит следующим образом:
1. Выполнить запись в порт.выбора регистра.
2. Подождать как минимум 3,3 мкс.
3. Выполнить запись в порт данных.
4. Подождать как минимум 23 мкс перед любой другой операцией со звуковой
платой.
На современных платах эти паузы можно сделать меньше. Так, если использу-
ется синтезатор ОРТЗ, требуемое значение пауз - 0,1 и 0,28 мкс.
_ 2294, 389 для записи: запись в регистр ЕМ (5В)
221# для записи: запись в регистр левого канала ЕМ ($ВРго)
223й, З8ВА для записи: запись в регистр правого канала ЕМ (5ВРго)
Всего в этих синтезаторах доступно 244 регистра - от 01Ь до ОЕЗВ. Рассмот-
рим наиболее полезные.
Регистр 011: тестовый регистр
биты 4-0:0.
бит 5: ЕМ микросхема контролирует форму волны у
биты 7-6: 0.
Регистр 021: счетчик первого таймера
Значение этого счетчика увеличивается на единицу каждые 80 мкс. Когда ре-
гистр переполняется, вырабатывается прерывание таймера 18.00 и устанавли-
ваются биты 7 и 6 в порту состояния.
Регистр 03Ь: счетчик второго таймера
Значение этого счетчика увеличивается на единицу каждые 320 мкс. Когда
регистр переполняется; вырабатывается прерывание таймера 1В.О0 и устанав-
ливаются биты 7 и 5 в порту состояния.
Регистр 048: регистр управления таймером
бит 0: установка бита запускает первый таймер (с начальным значением счет-
чика, помещенным в регистр 024)
бит 1: установка бита запускает второй таймер (с начальным значением счет-
чика, помещенным в регистр ОЗЁ)
биты 4-2: зарезервированы
бит 5: маска второго таймера- установка этого бита запрещает включение вто-
рого таймера при установке бита 1
бит 6: маска первого таймера - установка этого бита запрещает включение
первого таймера при установке бита 0
бит 7: сброс флагов для обоих таймеров
Регистр 08В: включение режимов С$М и КеузриЕ
биты 5-0: зарезервированы
бит 6: включение режима КеузрИ
бит7: 1 - режим С5М; 0 — режим ЕМ
Программирование науровне портов ПНИШИИВИИВИЕРЕ
Режим С$М (синусоидально-волновой синтез речи) применялся на платах АЧТЛЬ _
без ОЗР для воспроизведения оцифрованного звука (с очень плохим качеством).
Следующие регистры описываются группами — по одному на голос.
Регистры 206 - 35%: различные настройки режимов |
биты 3—0: какая гармоника будет создавать звук (или модуляцию) относитель:
но точно установленной частоты голоса:
0 - одной октавой ниже. |
1 - с точно установленной частотой голоса
2 - одной октавой выше
3 - октавой и квинтой выше .
А — двумя октавами выше.
5- двумя октавами и большой терцией выше
‚ 6 — двумя октавами и квинтой выше
.7-— двумя октавами и малой септимой выше ,
8 — тремя октавами выше
9 - тремя октавами и большой секундой выше: .
А, В -— тремя октавами и большой терцией выше
С, О - тремя октавами и квинтой выше .. й
Е, Е — тремя октавами и большой септимой выше
бит 4: режим КеуБоаг4 зсаНпв — если он выбран, длина звука сокращается и он
повынгается
бит 5: продление стадии поддержки звука (тоесть он не затухает сразу после
нарастания)
бит 6: включает режим вибрато (его глубина контролируется флагом в регис-
тре ОВО)
бит 7: применение амплитудной модуляции (ее глубина контролируется фла-
гом в регистре ОВОВ)
Регистры: 408-—558: управление уровнями выхода
биты 5-0: общий выходной уровень канала (00000— максимум, 11 — минй-
мум)
биты 7—6: понижение выходного уровня с повышением частоты: `
00 - не понижать
10 - 1,5 дБ на октаву.
01 - ЗдБ на октаву
` 11-1 дБ на октаву
Регистры 608- 751: темп нарастания/спада
биты 3-0: темп спада (0 — минимум, Е — максимум)
биты 7-4: темп нарастания (0 — минимум, Е — максимум) _
Регистры 86 - 958: уровень поддержки/темп отпускания
биты 3-0: темп отпускания (0 — минимум, Е — максимум)
‚биты 7—4: уровень поддержки (0 — минимум, Е — максимум)

|2 Зак. 459
ЕРШ ИИИИИИИ! — Сложные приемы программирования
Регистры 9АОВ - ОАЗВ: нота (младший байт)
биты 7-0: биты 7-0 номера ноты
Регистры ОВОВ- ОВ: октава и нота (старшие биты),
биты 1-0: биты 9-8 номера ноты
биты 4-2: номер октавы
бит 5: включить звук в этом канале
Значение 10-битного номера ноты соответствует следующим реальным нотам
(для четвертой октавы):
016ВВ - С# (277,2 Гц)
01816 —Р (293,7 Гц).
01985— О# (311,1 Гц)
01В0Ь -Е (329,6 Гц)
. 01САВ - Е (349,2 Гц),
О1Е5Ь - Е# (370,0 Гц):
‘02028 - С (392,0 Гн)
02208 - С# (415,3 Гц)
'0241Ъ - А (440,0 Гц)
0263 — А# (466,2 Гц).
0287 - В. (493,9. Гц)
О2АЕЬ - С (523,3 Гц) у:

Регистры ©СОВ- 0СВ8В: обратная связь/алгоритм


‚бит 0: 0 — первый оператор модулирует второй, 1 - оба оператора непосредст-'
венно производят звук
биты 3-1: сила обратной связи. Если это поле ненулевое, первый оператор
будет посылать долю выходного сигнала обратно: в ‚себя
Регистр ОВОБ: глубины модуляций/ритм
бит 0: включен НННа
‚ бит 1: включен Сушфа! |
бит 2: включен Тат ат
бит 3: включен Зпаге Агат
. бит 4; включен Вазз Чгит
бит 5: 1 - включен ритм (6 голосов на мелодию), 0 — ритм выключен © голо-
, сов на мелодию)
_ бит 6: глубина вибрато. .
бит 7: глубина амплитудной модуляции (1-4,8 дБ; 0-1 дБ).
Регистры ®ЕОЬ- 0Е5В: выбор формы волны
биты 1-0: форма волны, использующаяся, если бит 5регистра 01 установлен в' 1.
00: синусоида'
01: синусоида без отрицательной половины
02: абсолютное значение синусоиды (нижние полуволны отражены
вверх)
11: пилообразные импульсы
Программирование на: уровне портов
Чтобы извлечь из ЕМ простой звук, выполним такую’ последовательность
действий:
1. Обнулим все регистры. (грубый способ инициализации каб.
Канал 0 будет использоваться для голоса: `
2. Запишем в регистр 208 число 01Ь- кратность модуляции 1.
3. Запишем в регистр 408 число 101- уровень модуляции 40 дБ.
4. Запишем в регистр 60 число ОРОВ-— нарастание быстрое, спад— долгий.
5. Запишем в регистр 801 число 77Ъ- поддержка и отпускание бредние.
6. Запишем в регистр ОАОН число 988- нота О#. `
Канал 3 будет использоваться для несущей:
7. Запишем в регистр 023Ь число 01В- кратность несущей 1.
8. Запишем в регистр 043Ь число 00 — максимальная громкость для несущей
(47.дБ).
9. Запишем в регистр 'О6ЗВ число ОЕОВ— нарастание среднее, спад— долгий.
10. Запишем в регистр 083В число 77В — поддержка и’отпускание - средние.
11. Запишем в регистр ОВОВ число 0З1Ь-— установить октаву, старшие биты
НОТЫ И ВКЛЮЧИТЬ ГОЛОС.
С этого момента синтезатор звучит.
12. Запишем в регистр ОВОВ число 11Н (или пюбое с нулевым битом 5) для вы-
ключения звука.
Пример программы
- Программирование современных звуковых плат — весьма сложное занятие,
поэтому в качестве примера рассмотрим одну часто применяемую операцию -
воспроизведение оцифрованного звука. С этой целью потребуется программиро-
вать только О$Р: Для вывода звука через звуковую плату может использоваться
один из трех режимов: прямой вывод (команда 101), когда программа должна
сама с нужной частотой посылать отдельные байты из оцифрованного звука
в ОЗР; простой ОМА-режим, когда выводится блок данных, после чего вызыва-
ется прерывание; и ОМА савтоинициализацией, когда данные выводятся непре-`
рывно и после вывода каждого блока вызывается прерывание. Именно в этом
порядке увеличивается качество воспроизводимого звука. Так как мы пока. не
умеем работать с ОМА, рассмотрим первый способ.
Чтобы вывести оцифрованные данные с нужной частотой в О$Р придется
перепрограммировать канал 0 системного таймера на требуемую частоту и уста-
новить собственный обработчик прерывания 08}. При этом будет нарушена ра-
бота системных часов, хотя можно не выключать совсем старый обработчик,
а передавать ему управление примерно 18,2 раза в секунду, то есть, в частности,
при каждом 604-м вызове нашего обработчика на частоте 11 025 Гц. Покажем,
как это сделать на примере. простой программы, которая именно таким спосо-
- бом воспроизведет файл с\ула4о\з\
те а\{адамау (или с\\млпдо\из\(ада.мау,
если вы измените соответствующую директиву ЕОП вначале программы).
; мауафг. ам | | №
; Воспроизводит файл с:\м1пдоиз\тед1а\тТаЧа.мау, не используя ОМА.
: Нормально работает только под 005 в реальном: режиме с,
ЕЕЗИШИШИШИИИИ!—— Сложные приемы программирован
; (то есть не в окне 00$ (И1паомз) и не под ЕММЗ86, ОЕММ или другими
‚ подобными п№граммами).

ЕГ.ЕЗРЕС еду “с: \м1паомз\тед1а\тада.мау” ; Имя файла тада. мау с


; полным путем (замените на с: \и1паоиз\тада, мау
; для старых версий №1пдомз). —
ВРОНТ еди 2201 ‚ Базовый порт звуковой платы (замените,
; если у вас он отличается).
.тоде1 11пу
. соде
. 186 ; Для ризпа/рора.
ог9 1001 ; .СОМ-программа.
этагт: .
са11 95р_гезет ; Сброс и инициализация’ О5Р.
с по_Б]1азтег =
моу 51, 001в_ ` ; Команда ОЗР ОЛН.
са11 Озр.мг Це ; Включить звук.
са1] ореп_111е . ; Открыть и прочитать тада. мам.
са11 Ноок_ 1118 ;'Перехватить прерывание таймера. .
тоу 6х, 5 ; Делитель таймера для частоты 22 050 Н2
; (на самом деле соответствует 23 867 Н2).
са11 ° гергодгам_р1т ; Перепрограммировать таймер.

та1п_100р: ; Основной цикл.


стр Буте рег Е1пт5Нед_Ё1ад,0
]е ма1и_1оор . .; Выполняется, пока- Р1п1зВед_Р1ад равен нулю.
пом Бх, ОРРЕРИ ‚ Делитель таймера для частоты 18,2 Нх.
са11 гергодгат_р1т ; Перепрограммировать таймер. °
° са] гезтоге_ 1118 ‚ Восстановить ТНОО.
по_Б1азтег:
гет

БиРег_аддг ом оЁРзет риРег ^; Адрес текущего играемого байта.


0149111081 99 2 ; Старый обработчик ТМТ .08Н (1800).
Е1п1$пед_Е1ад 96. 0 ; Флаг завершения.” |
111епате ‚ № ЕТЬЕЗРЕС, 0 ‚ Имя файла Тада.мау с полным путем.

; Обработчик ТМТ 080 (1800).


; Посылает байты из буфера в звуковую плату.
11408 п_Напа]ег ргос Таг
ризва ‚: Сохранить регистры.
стр Буте рег сз: Е1п1зНед_11ад,1’; Если флаг уже 1,
]е ех1{_ Пай ег { ничего не делать.
тоу 91, могд рг сз:БиРРег_а@4г ; Иначе: ОТ = адрес текущего байта.
Ь1, 101 | ‚ Команда ОЗР 10.
9$р_мгаТе ; Непосредственный 8-битный вывод.
5], Буте рег ©3:[91] ; ВЕ = байт данных для. вывода.
Чзр_мглте .
91 ‚; ОТ = адрес следующего ‚байта.
91, оРРзет БиЁЁег+27459 ‚ 27 459 - длина звука в Тада. мам.
А
и”
Программирование на уровне портов. |ММИВИИИНИЕЙ —.
р) ПОТ 1111 $1е4 . Если весь буфер пройден,
тоу Буте рег с$: 1п131е8_1]ад,1 ‚ установить флаг в 1.
по{_11п131е9: ` ; Иначе: |
| том могд рег с$:БиЕРег_аддг,91 ; сохранить текущий адрес.
ех1*_Папд1ег:
поу а1, 201 ; Завершить обработчик аппаратного прерывания,
оу{ 208,а1 ; послав’ неспецифичный ЕСТ. (см. раздел 5.10.10).
рора ; Восстановить регистры. ;
1гет
11108 Н_Пап ег епар

‚ Процедура 9зр_гезет.
; Сброс и инициализация О5Р.
95$р_гезет ргос пеаг
му 9х, ЗВРОВТ+6 ; Порт 2261 - регистр сброса О$Р.
МОУ а1,1 ; Запись единицы в него начинает инициализацию.
от 9х,а1
моу сх,40 ; Небольвая пауза.
95$р1оор: 7
1п а],дх
1оор 95р1оор
том а],0 . Запись нуля завершает инициализацию.
о дх,а1 ; Теперь 05$Р’ готов к работе.
‚ Проверить, есть ли 0$Р вообще.
а99 9х,8 Порт 22ЕН - состояние буфера. чтения 0$Р.
мо сх, 100
спеск_рогт:
1п а1,9х :; Прочитать состояние буфера.
ап а1, 801 ; Проверить бит 7.
12 рогт ‘пот_геаду ‚ Если ноль - ‘порт еще не готов.
$и0 9х,4 ‚ Иначе: порт 22АН - чтение данных из 0$Р.
11 а1,9х
а99 9х,4. ‚ И снова перт 22Е\.
сир а], ОААМ .; Если прочиталось число ААП - 0$Р присутствует
‚ и действительно готов к работе.
. 4 9009 _гезет
рогЕ_по*_геаду: |
]оор спеск_рогт Если нет “повторить проверку 100. раз
Бад_гезет:
тс и сдаться.
гет Выход с СЕ = 1.
‚ 9009_гезет:
с1с ; Если инициализация прошла успешно,
гет выход с СР = 0.
азр_гезет епар

; Процедура 95р_мг Ще.


; Посылает байт из ВЕ в 05Р.
Чзр_мг3те ргос пеаг
„ПоУ 9х, ЗВРОАТ+ОСИ ; Порт 2201 - ввод данных/команд О$Р.

и
вании Сложные приемы программирования
мг1Те_10о0р: ; Подождать готовности буфера записи ОЗР.
11 а1, 4х ; Прочитать порт 22Сп
айда а1, 80П ; и проверить бит 7,
917 иг Те_1оор ‚ ; Если он не ноль - подождать еще.
оу а1, 51 ; Иначе: !
ощ ах, а1 ; послать данные.
ге
9зр_мг1{е епдр

‚ Процедура’ гергодгат_р1т.
; Перепрограммирует канал 0`системного таймера на новую частоту.
; Вход: ВХ = делитель частоты.
гергодгат_р1т ргос пеаг.
с11 ; Запретить прерывания.
МОУ а1, 001101106 ; Канал 0, запись младшего и старшего байтов
‚ режим работы 3, формат счетчика - двоичный.
оц 431, а1 ; Послать это в регистр команд первого таймера.
оу а1,61 ; Младший байт делителя -
от 401 ‚а? ‚ в регистр данных канала 0.
мо а}, БИ ; И старший байт -
сит 401, а1 ‚ Туда же.
$11 : ‚ Теперь ТА@О вызывается с частотой 1 193 180/ВХ Н2.
гет
гергодгат_р1т епар

‚ Процедура поок_1п18. |
; Перехватывает прерывание ТМТ 08н (1800).
поок_1718 ргос ° пеаг
° оу ах, 35081 , ; АН = 358, АС = номер прерывания.
1и 21А ; Получить адрес старого обработчика.
по мога ртг 0149111081,6х ; Сохранить.его. в о14_1п08Н.
[7 мога руг о14_1п1081+2‚ез
МОУ ах; 2508 < АН = 251, АЁ = номер прерывания.
- оу 9х, оЕЕзет 1п108П_папд1ег ; 05:0Х - адрес обработчика.
17. 2. ‚ ; Установить обработчик,
гет
ВооК_1п18 епар о.
‚ Процедура гезтоге_ 1118.
‚ Восстанавливает прерывание ТМТ 088 (1800).
гезфоге_1п18 ргос педг. | .
оу ах, 2508В ' ; АН = 251, АЁ = номер прерывания.
195 Чх, мог ртг о14_111081 ; 05:0Х - адрес обработчика,
1 21н о ; Установить старый ‘обработчик.
тет |
гезтоге_1п18 епдр

‚ Процедура ореп_#11е.
; Открывает файл Ё1]епате и копирует звуковые данные из него, считая его’ файлом
‚ Тада.мау, в буфер БиРРег.
ореп_#11е ргос пеаг
моу ах, 30001 : ‚ АН = ЗО, АЁ = 00.
Программирование на уровне портов |ИНИВИИИИИЕЕЕ
_ му . 4х, о1Мвет ЕАТепате ” ;. 0$:0Х - А$СТ2-имя файла с путем.
9 ам , ; Открыть файл. для. чтения. .
с. еггог_ех1т ; Если не удалось открыть файл -- выйти.
по Хх,ах с ` : идентификатор фанта в ВХ.
пом ах, 42008 : :- ; =- 421, АЁ=
моУ сх, 0 ; ох:
ОХ - новое значение указателя.
мочу ах, 381 | . по этому адресу начинаются данные в`-Тада. мау.
17 211 . у ереместить файловый указатель.
ту ° ай, ЗЕ® ` ; = ЗЕИ.
моу сх, 27459 ‚ Это - р звуковых данных 'в файле тада. мам.
_ МОУ 6х, оРзет БиГРег ; 0$:0Х - адрес буфера.
1% 214 ; Чтение файла.
гет - |
еггог_ех1т: “ ° р ; Если не удалось. открыть файл.
оу ап, 9: - _^; АН = 091.
мо ах,
ОТ зех .поторепяз9 ; 05:0Х = сообщение об ошибке.
о 2 | ; Открыть файл для чтения.
Не 208 . -; Конец программы.
поторептз 9 95 “Ошибка при открытии файла”, ООН, ОА, ' $’
ореп_111е епдр |

риРГег: .^ “. Здесь начинается буфер длиной 27`459 байт.


еп зтагт |
Если вы скомпилировали программу ]аепсуазт из раздела 5.10.5 и попробова-
ли запустить ее в разных условиях, то могли заметить, что под УЛи4о\з 95, а также
под ЕММЗ86 и в некоторых других ситуациях пауза между реальным срабатыва-
нием прерывания таймера и запуском обработчика может оказаться весьма зна-
чительной и варьироваться с течением времени, так что качество звука, выводимого
нашей программой угауЧи.азт; окажется под ЕММЗ86 очень плохим, а в ОО5-задаче
под УМа4о\ 95 вообще получится протяжный хрин. Чтобы этого избежать, а так-
же чтобы указывать точную скорость оцифровки звука и’выводить 16-битный
звук, нужно обратиться‘к программированию контроллёра ОМА (пример про-
граммы, выводящей звук при помощи ОМА, см. в конце следующего раздела).

5.10.9. Контроллер ОМА


Контроллер ОМА используется для. обмена данными между внешними уст-
ройствами и памятью. Он нужен в работе с жесткими ‘дисками и дисководами,
звуковыми платами и другими устройствами, работающими со значительными
объемами данных. Начиная с РС АТ, в компьютерах присутствуют два ОМА-кот-
роллера- 8-битный (с каналами 0, 1, 2и3) и 16-битный (с каналами 4, 5, би 7).
Канал 2 используется для обмена данными с дибководами, канал 3 — для жестких
дисков, канал 4 теряется при каскадировании контроллеров, а назначение осталь-
ных каналов может варьироваться.
ОМА позволяет выполнить чтение или запись блока данных, начинающегося
с линейного адреса, который описывается как 20-битное число для первого РМА-
контроллера и как 24-битное для второго, то есть данные для 8-битного ОМА
должны располагаться в пределах первого мегабайта памяти, а для второго —
ШИ! — Сложные приемы программирования
в пределах первых 16 Мб. Старигие четыре бита для 20-битных адресов и старшие
8 бит для 24-битных адресов хранятся в регистрах страниц ОМА, адресуемых
через порты 801 -— 8ЕЪ:
порт 81#: страничный адрес для канала 2 (биты 3-0 = биты 19-16 адреса)
порт 82#: страничный адрес для канала 3 (биты 3-0 = биты 19-16 адреса)
порт 831: страничный адрес для канала 1 (биты 3-0 = биты 19-16 адреса)
порт 87й: страничный адрес для канала 0 (биты 3-0 = биты 19-16 адреса)
порт 89#: страничный адрес для канала 6 (биты 7-0 = биты 23-17 адреса)
порт ВАЙ: страничный адрес для канала 7 (биты 7-0 = биты 23-17 адреса)
порт 8В#: страничный адрес для канала 5 (биты 7-0 = биты 23-17 адреса)
Страничный адрес определяет начало 64/128-килобайтного участка памяти,
с которым будет работать данный канал, поэтому при передаче данных через
ОМА обязательно надо следить за тем, чтобы не было выхода за границы этого
участка, то есть чтобы не было попытки пересечения адреса 10006:0, 20001:0,
3000}:0 для первого ОМА или 20001:0, 40003:0, 6000}:0 для второго. `.
Младшие 16 бит адреса записывают в следующие порты:
00Ъ: биты 15-0 адреса блока данных для канала 0
01Ъ: счетчик перёданных ‘байт канала 0
02 - 038: аналогично для канала 1-
04} — 955: аналогично для канала 2
Об - 07: аналогично для канала 3 |
(для этих портов используются две операции чтения/записи — сначала пере-
даются биты 7-0, затем биты 15-8)
ОСОБЬ: биты 8-1 адреса блока данных для канала 4 (бит 0 адреса всегда равен нулю)
` 0С1Ъ: биты 16-9 адреса блока данных для канала,4
0С2Ь: младший байт счетчика переданных слов канала 4
ОСЗЬ: старший байт счетчика переданных слов канала 4
0С4Ь - 0С71: аналогично для канала 5
ОС8Ь - ОСВЬ: аналогично для канала 5
ОССЬ - ОСЕБ: аналогично для канала 5
(эти порты рассчитаны на чтение/запись целыми словами)
Каждый из указанных двух ОМА- -контроллеров также имеет собственный на-
бор управляющих регистров — регистры первого контроллера адресуются через
порты 08В- ОЕЪ, а второго - через 000— ОР:
порт О8#/ОРОЕ для чтения: регистр состояния ОМА
бит 7, 6, 5, 4: установлен запрос на ОМА на канале 3/7, 2/6, 1/5, 0/4
„бит 3, 2, 1, 0: закончился ОМА на канале 3/7, 2/6, 1/5, 0/4
порт ОЗЕ/ШОЙ для записи: регистр команд ОМА (устанавливается В10$)
‚ бит 7: сигнал РАСК использует высокий уровень
бит6: сигнал ОВЕО использует высокий уровень
Программирование
на уровне портов И
МИИИИИНЕГЯ
бит 5: 1/0: расширенный/задержанный цикл записи
бит 4: 1/0: приоритеты сменяются циклически фиксированно
. бит.3: сжатие во времени
бит 2: ОМА-контроллер отключен
бит 1: разрешен захват канала 0 (для режима память-память)
бит 0: включен режим память-память (канал 0 - канал 1)
порт 09/0028 для записи: регистр запроса ОМА
бит 2: 1/0: установка/сброс запроса на ОМА
биты 1-0: номер канала (00, 01, 10, 11 = 0/4, 1/5, 2/6, 3/7)
порт ОАЙ/ОБ4Е для записи: регистр маски канала ОМА
бит 2: 1/0: установка/сброс маскирующего бита
биты 1-0: номер канала. (00, 01, 10, 11 = 0/4, 1/5, 2/6, З/Т)
порт ОВЕ/ОО6БА для записи: регистр режима ОМА.
биты 7-6: 00 — передача по’ запросу
01 — одиночная передача (используется для звука)
10 — блочная передача (используется для дисков)
11 — канал занят для каскадирования
бит 5: 1/0: адреса уменьшаются/увеличиваются
бит 4: режим автоинициализации.
биты 3-2:
00 — проверка
01 - запись
10 — чтение
биты 1-0: номер канала (00, 01, 10, 11 = 0/4, 1/5, 2/6, 3/7)
порт ОСВ/ООВЕ для записи: сброс переключателя младший/старший байт
Для чтения/записи 16-битных значений из/в 8-битные порты 008-—‘08.
‚ Очередной байт, переданный в эти порты, будет считаться младшим, а сле-
дующий за ним -— старшим.
порт ОБЕ/ОРАЙ для записи: сброс контроллера ОМА
Любая запись сюда приводит к полному сбросу ОМА-контроллера, так что
его надо инициализировать заново. |
порт ОРЕ/ОРАЕ для чтения: последний переданный байт/слово.
порт ОЕВ/ОРСЕ для записи: любая запись снимает маскирующие биты со всех
каналов | |
порт ОЕЛ/ОПЕЙ для записи: регистр маски всех каналов:
‘биты 3-0: маскирующие биты каналов 3/7, 2/6, 1/5;0/4
Чаще всего внешнее устройство само инициализирует передачу данных, и все,
что необходимо сделать программе, -— это записать адрес начала буфера в порты,
соответствующие используемому каналу, длину передаваемого блока данных ми-
нус один в регистр счетчика нужного канала, установить режим работы канала
и снять маскирующий бит. |
В качестве примера вернемся к программированию звуковых плат и изменим
программу \ау@г.азт так, чтобы она использовала ОМА.
ШИШШШИН!! — Сложные приемы программирования -
; маудта.
аэт .
; Пример программы, проигрывающей файл С:\ИТМООМ$\МЕОТА\ТАВА.
ИАУ
; на звуковой карте ‘при’ помощи ОМА.
ЕТЬЕЗРЕС еди “с:\и1пдомз\тед1а\тада.
мам” ‚ Заменить на с: \м1паомз\тада.
мам.
для старых версий \1паомз.
ЗВРОАТ еди 220,
; ЗВОМА еди 1 Процедура ргодгат_ата рассчитана
лишь на канал 1.
ЭВТА@ — еди 5 Только 1800 - ТНО?.
‚.100е]1 пу
.соде
‚ 186
ог 1008 С0М-программа.
$Фагт: .
са11 9зр_гезет Инициализация 0$Р.
3с по_О1азтег
моу Ь1, оон Команда ОЛ.
са11 дзр_игМе Включить звук.
са11 ° ореп_Е11е Прочитать файл в буфер.
са11 поок_$61га ПерехваТить прерывание.
моу 5}, 408 Команда 401.
са11 Ч9зр_мг1 те Установка скорости передачи.
оу 51, 0В2В Константа для 11025Н2/ЗТегео.
са1} 9$р_мг1те
са]11 ргодгат_дта Начать ОМА-передачу данных.

па1п_10о0р: Основной цикл. '


стр Буфе рег Р1п151ед_Ё1ад,0
де та1п_1оор Выход, когда байт #1п1зВед_Р1ад = 1.
са11 гезтоге_$51г4 Восстановить прерывание.
по_Б]азтег:
гет

014 ®51га 99 7? Адрес старого обработчика. |


#1п15ед_Е1а9 [е] 0 Флаг окончания работы.
Е епаме 96° [ТЪЕ$РЕС,0 Имя файла.

; Обработчик прерывания звуковой карты.


; Устанавливает флаг 11п15Пед_Еад в 1.
$61га_Папа ег ргос Таг
ризН ах
оу - Бе р\уг с5: Раитзвед_1]ад,1 ‚ Установить .флаг.
. ОУ а1, 201 ‚ Послать команду ЕОТ
оц 201, а1 ; В контроллер прерываний:
^ рор ах
1гет -
з61га_папатег . епдр

; Процедура дзр- гезет.


; Сброс, и инициализация 05Р:
Программирование на уровне. портов
А.
Вы о.
и
95р_гезет ргос пеаг |
му дх, ЗВРОЯТ+6 : Порт 2268 - региетр. сброса ОР. а
то\ а1,1 - : Запись в него единицы запускает ‘инициализацию.
сит 9х, а1 й
поу сх, 40 | ; Небольшая пауза.
95р100р: |
11 а],ах
100р ` 93р10ор
том а1,0 ; Запись нуля завершает инициализацию.
сит 9х, а] ` Теперь О3Р готов к работе.

ада дх, 8 ; Порт 22Еп - бит 7 при чтении указывает на занятость


мо сх, 100 ; буфера записи 0$Р.
спеск_рогт:
п а1, 9х .. ; Прочитать состояние буфера записи.
апа а], 801 ; Если бит 7 ноль,
ру рогф_пот_геаду ; порт еще не готов. |
$40 9х, 4 : ; Иначе: порт 22Ап - чтение ‘данных из О$Р.
11 а],9х
а94 9х, 4 ; Порт снова 22Еп.
стр ат, сААП ВЫ Проверить, что 0$Р возвращает `ОААВ при чтении, -
это сигнал о ‘готовности к работе.
]е 0009_гезет -
рогт_пот_геаду:
1оор спеск_рогт ; Повторить проверку на ОААМ 100 раз.
раб_гезет:
31 ; Если боипд ВЗазфег не откликается,
. гет ; вернуться с СЕ =
9004_гезет: .
сс ; Если инициализация прошла успешно,
гет ; вернуться с СЕ =
Ч9зр_гезет епар

: Процедура @зр_мг1те
; Посылает байт из ВЕ в 05Р
Чзр-ми1те‘ ргос пеаг
поу — 9х, ЗВРОАТ+0С °; Порт 22Сп - ввод данных/команд О$Р.
игЦе_1оор: ; Подождать до готовности буфера записи ОЗР,
1п а}, 9х ; прочитать порт. 2208
апа а1, 808 - ; и проверить бит 7.
312 мг1Те_1оор ; Если он не ноль - подождать еще.
тоу а], 61 ; Иначе: `
- о вх, а1 ; послать данные.
геф
9зр_мга Те’ епар

; Процедура Поок_зЬ1га.
; Перехватывает прерывание звуковой карты и разрешает его.
ВоОК_$51г4 ргос пеаг
| ах, 3508+58 140 —; АН = З5в, АЁ = номер прерывания.ика =
1 211 ; Полу чить адрес старого. обработч
ЕТУИИШИВИШИИИ ! — Сложные приемы программирования
МОУ. могд рфг о19_з61га,Бх ; и сохранить его.
тоу мог4 рфг 019_$51г4+2,ез
`по\ ах, 2508 1+$ВТНО АН = 251, АЁ = номер прерывания.
моу ах, оРРзет 361га_Папа]ег Установить новый обработчик
101 211
оу с1,1
$0] с1, ЗВТВО
лот с1 Построить битовую маску.
1й ай, 21н Прочитать ОСИЗ.
апа а1, с1 Разрешить прерывание.
ит 218,а1 Записать ОСМ1.
гет
поок_$61га епар

`; Процедура гезтоге_$61г4.
и
‚ Восстанавливает обработчик и запрещает прерывание.
гезтоге_$51г4 гос пеаг
ЮУ ах,3508й+5ВТАО АН = 251, АЁ = номер прерывания.
193 Чх, Чиог@ рег о19_$51га
11 211 “Восстановить обработчик.
оу с1,1
$11 с1, ЗВТАЙ Построить битовую маску.
11 а], 21н Прочитать СЧ.
ог а1, с] Запретить прерывание
о 211,а1 Записать ЦСМ1.
гет
гезТоге_$51га ‚ епар

‚ Процедура. ореп_111е.
; Открывает файл Р11епате и копирует звуковые данные из него, считая, что
; это Тада. мам, в буфер: Би! Рег.
ореп_111е ргос пеаг
оу ах, 30008 АН.= ЗОВ, АЁ = 00.
поу 9х, оРРзет Г1]епате ; 05:0Х - А$СТ2-строка с именем файла.
1% 218. Открыть файл для чтения,
37° еггог_ех1т Если не удалось открыть файл - выйти.
том Ьх, ах Идентификатор файла в ВХ.
оу ах, 42001 АН = 421, АГ = 0. '
тоу сх,0 СХ:0Х - новое значение указателя.
оу дх, 388 По этому адресу начинаются данные
в Тада. мам.
171 21ы Переместить файловый указатель.
моу ап, ЗЕИ АН = ЗЕА.
оу СХ, 27459 Это - длина данных в файле тада. мау.
|
рузН 9$ : `

оу ах,43
апа 9х, ОЕ000Н ; Выравнять буфер на границу 4-килобайтной страницы
ада 9х, 10004 ; для’ ОМА.
оу 0$,4х
тоу дх,0 ‚ 05:0Х - адрес буфера.
17 21н ; Чтение файла.
Программирование на уровне портов |НИИВИИИВИИИИИИ,
рор 9$
гет р (_ .
еггог_ехзт: : с; Если не удалось открыть файл.
оу › ан,9 | ; АН = 091. |
оу Чх, оРЕзег поторепт$9 ; 0$:0Х = адрес сообщения об ошибке..
1 21и ‘; Вывод ‘строки на экран..
те 200 : ; Конец программы.
‚ сообщение об ошибке
поторептз9 ЗЬ “Ошибка при’ открытии файла" , Об, ОАВ, '$’.

ореп. #11е епар

; Процедура ргодгат_дта.
; Настраивает канал 1 ОМА:
ргодгам_дта ргос` пеаг
`. оу ^ 21,5 ` ° ; Замаскировать канал 1.
от ^ ОА, а] :
хог а], а] ; Обнулить счетчик.
ои* ОСН, а1 :
ПУ а1, 49Н ; Установить режим передачи. ‘-
, .. : (используйте 591 для автоинициализации).
ит. ОВП, а1 . -

ризй |
рор ° ах
апа. 90, ОРОН
299 ап, 101 ; Вычислить адрес буфера.
хог ах, ах . :
ом 021,21 ; Записать младшие 8 ‘бит.
ом 028, а1 ; Записать следующие 8 бит.
оу а], Ч |
Пг а1,4
сит 831, а] о Записать старшие 4 бита.

оу ах, 27459 - ; Длина данных в Тада.мау. _


дес ах `; ОМА требует длину минус один.
о ОЗВ, а1 ; Записать младшие 8 бит длины.
тоу а1, ап ` : '
ош ОЗ, а1 . ; Записать старшие 8 бит длины.
моу а],1
ош ОАП, а1 `..; Снять маску: с канала 1.

тмоу 51,141. ‚ Команда 148.


са11 4зр_мг1 {Хе : 8-битное простое ОМА-воспроизведение.
оу Ьх, 27459 ; Размер. данных в тада. мам’
дес Ьх ‚ минус 1. :
са11 9зр_мг1Те ; Записать в О5Р младшие 8 ‘бит длины
моу 1, БИ | `.
са11 дзрмге . ; и старшие. |
ге! 7
ргодгат_дта епар
епа зфтагт
ЕСТ ИНН |! Сложные приемы программирования
В этом примере задействован обычный ОМА-режим работы, в котором зву-
ковая плата проигрывает участок данных, вызывает прерывание и, пока обра-
ботчик прерывания подготавливает новый буфер данных, программирует ОМА
и звуковую плату для продолжения воспроизведения, проходит некоторое вре-
мя, что может звучать как щелчок. Этого можно избежать, если воспользоваться .
‘режимом автоинициализации, позволяющим обойтись без остановок во. время
воспроизведения.
При использовании режима ОМАс автоинициализацией нужно сделать следу-
ющее: загрузить начало воспроизводимого звука в буфер длиной, например, 8 Кб.
и запрограммировать ОМА на его передачу с автоинициализацией. Затем сооб-
щить ОР, что проигрывается звук с автоинициализацией и размер буфера равен
4 Кб. Далее, когда придет прерывание от звуковой платы, она не остановится и про-
должит воспроизведение из вторых 4 Кб буфера, поскольку находится в режиме
автоинициализации. Теперь запишем в первые 4 Кб следующий блок данных.
Когда кончится 8-килобайтный буфер, ОМА начнет посылать его сначала, пото-
му что мы его тоже запрограммировали для автоинициализации (бит 4 порта
ОВЬ/ОР6В), О5Р вызовет прерывание и тоже не остановится, продолжая воспро-
изводить данные, которые посылает ему ОМА-контроллер, а мы тем временем за-
пишем во вторые 4 Кб буфера следующий участок проигрываемого файла и т. д.

5.10.10. Контроллер прерываний |


Контроллер прерываний- устройство, которое получает запросы на аппарат-
ные прерывания от всех внешних устройств. Он ‘определяет, какие запросы следу-
` ет обслужить, какие должны ждать своей очереди, а какие не будут обслуживаться
вообще. Существует два контроллера прерываний, так же как и ОМА. Первый
контроллер, обслуживающий запросы на прерывания от 1800 до ВОТ, управля-
ется через порты 20} и 21В, а второй (1ВО8- 1КО15)- через порты ОАОВ и ОА1В.
Команды контроллеру делят на команды управления (ОС\’) и инициализа-
ции (1С\”):
‚ порт 201 /ОАОК для записи: ОСУ/2, ОСУГЗ, 1СУ/1
порт 208 /ОАОЕ для чтения: см. команду ОС\З
порт 218/0А1Р для чтения и записи: ОСУИ1 - маскирование прерываний
порт 211/ОАТЁ для записи: ТСУ/2, 1СУ/З, 1С\/4 сразу после 1СУ/1
Команды управления
осу:
биты 7—0: прерывание 7-0/15-8 запрещено
‚При помощи этой команды можно временно запретить илиг разрешить то или
иное аппаратное прерывание. Например, команды
к |
п ^ а1, 241
ог а1, 00000010
04 218,а1

приводят к отключению 1ВО1, то есть клавиатуры.


Программирование на уровне-портов
‚- Мы пользовались. ОС\1 в программе фегт2.азт, чтобы разрешить 1КОЗ -
прерывание от последовательного порта СОМ2. 1:
ОС\/?2: команды конца прерыванияи сдвига приоритетов
‘биты 7-5: команда
`000Ъ: запрещение сдвига- приоритетов в режиме без ЕО]
001Ъ: неспецифичный ЕО] (конец прерывания в режиме с приоритетами)
010Ъ: нет операции
011Ъ: специфичный ЕО] (конец прерывания в режиме без приоритетов)
100Ъ: разрешение сдвига приоритетов в режиме без ЕО!
101Ъ: сдвиг приоритетов с неспецифичным ЕО1
- 1105: сдвиг приоритетов
111Ь: сдвиг приоритетов со специфичным ЕОТ
биты 4-3: 00Ъ (указывают; что это ОС\/2) ва .
биты 2-0: номер 1КО для команд 014, 1105 и 111Ъ | в
Как упоминалось в разделе 5.8.2, если несколько прерываний происходят од-
новременно, обслуживается в первую очередь то, у которого высший приоритет.
При инициализации контроллера высший приоритет имеет {К О0 (прерываниеот
системного таймера), а низший - 1807. Все прерывания второго контроллера
(1В08- 1ВО15) оказываются в этой последовательности между 1ВО1 и 1ОЗ, так
как именно 1ВО2 используется для каскадирования этих двух контроллеров. Ко-
манды сдвига приоритетов позволяют изменить ситуацию, присвоив завершаю-
щемуся (команды 101 или 111) или обрабатывающемуся (110)! прерыванию низ-
ший приоритет, причем следующее прерывание получит наивысший, и далее по
круту.
Более того, в тот момент, когда выполняется обработчик аппаратного прерыва-
ния, других прерываний с низшими приоритетами нет, даже если обработчик
выполнил`команду $4. Чтобы разрешить другие прерывания, каждый обработчик |
обязательно должен послать команду ЕОГ- конец прерывания- в соответствую- `
щий контроллер. Именно поэтому обработчики аппаратных прерываний в про-
граммах {егт2.азт и \аудта.азт заканчивались командами
моу а1,20' : команда “неспецифичный конец прерывания”.
от 201, а1 ; посылается в первый контроллер. прерываний

Если бы контроллер был инициализирован в режиме без приоритетов, вместо


неспецифичного ЕО! пришлось бы посылать специфичный, содержащий в млад-
ших трех битах номер прерывания, но ВТО$ инициализирует контроллер именно
в режиме с приоритетами. Кроме того, контроллер мог быть инициализирован
в. режиме без ЕО], но тогда в ходе работы обработчика прерывания могли бы про-
исходить все остальные прерывания, включая`обрабатываемое. О способах ини-
циализации контроллера говорится далее, а здесь рассмотрим последнюю коман-
ду управления. |
ОСУ\У/З: чтение состояния контроллера и режим специального маскирования
бит 7: 0 а
ЕТЗЕЗИВВОИНИШИ ИИ — Сложные приемы программирования
биты 6-5: режим специального маскирования
00 — не изменять
10 — выключить
11 - включить
биты 4-3: 01 - указывает, что это ОС\УЗ
бит 2: режим опроса
биты 1-0: чтение состояния контроллера
00 -— не читать
10 — читать регистр запросов на прерывания
11 - читать регистр обслуживаемых прерываний -^
В режиме специального маскирования при выполнении обработчика преры-
вания разрешены все прерывания, кроме осуществляющегося в настоящий мо-
мент и маскируемых командой ОС\\1, что имеет смысл сделать, если обработчи-
ку прерывания с достаточно высоким приоритетом потребуется много времени.
Чаще всего ОС\\!З используют для чтения состояния контроллера- младшие
два бита выбирают, какой из регистров контроллера будет возвращаться при пос-
ледующем чтении из порта 21 /0А1Ъ. Оба возвращаемых регистра имеют струк-
туру, аналогичную ОС\\1, - каждый бит отвечает соответствующему 1ВО.
Из регистра: запросов на прерывания можно узнать, какие прерывания. про-
изошли, но пока не были обработаны, а из регистра обслуживаемых прерываний —
какие прерывания обрабатываются в данный момент. Итак, еще одна мера бе-
зопасности, которую применяют резидентные программы, - нельзя рабютать
с дисководом (1ВОб), если в данный момент обслуживается прерывание от пос-
ледовательного порта (1ВОЗ), и нельзя работать с диском (1014/15), если об-
служивается прерывание от системного таймера (ВОО).
Команды инициализации
Чтобы инициализировать контроллер, В1О$ посылает последовательность ко-
манд: 1С\У1 в порт 20Ъ/0А0Ь (она отличается от ОСУ\ своим битом 4) и 1С\?2,
ГС\З, 1С\/4 в порт 216 /0А1Ь сразу после этого.
ТС\1:
биты 7—4: 0001Ъ
бит 3: 1/0: срабатывание по уровню/фронту сигнала 1ВО (принято 0)
бит 2: 1/0: размер вектора прерывания 4 байта/8 байт (1 для 80х86)
бит 1: каскадирования нет, [С\У/З3 не будет послано
бит 0: [С\/4 будет послано
1С\/?2: номер обработчика прерывания для 1ВО0/1ВО8 (кратный восьми)
` (086 - для первого контроллера, 70} -— для второго. Некоторые операцион-
ные системы изменяют первый обработчик на 50)
ГСУ\УЗ для ведущего контроллера:
биты 7-0: к выходу 7-0 присоединен подчиненный контроллер (0100Ъ в РС)
ГСУ’З для подчиненного контроллера:
биты 3-0: номер выхода ведущего контроллера, к которому подсоединен ведомый
на уровне портов ] ||
Программирование
ТСУ\УА:
биты 7—5: 0 ,
бит 4: контроллер в режиме фиксированных приоритетов
биты 3-2: режим: о. р
00, 01 - небуферированный
10 — буферированный/подчиненный
11 - буферированный/ведущий |
бит 1: режим с автоматическим ЕОТ
(то есть обработчикам не надо посылать ЕОГ в контроллер)
бит 0: 0 — режим совместимости с 8085; 1 — обычный ._
ер, изменить
Повторив процедуру инициализации, программа может, наприм
тными пре-
соответствие между обработчиками прерываний и реальными аппара
на неиспользуемую
рываниями. Переместив базовый адрес первого контроллера
на каждое из пре-
область (например, 501) и установив собственныеобработчики
ающие ПУТ 08Ь — ОЕ, вы будете абсолютно увере- ,
рываний ПМТ 508 - 58В, вызыв
тного прерыва-
ны в том, что никакая программа не определит обработчик аппара
ния, который получил бы управление раньше, вашего.. |
сту

; ри.ат .
прерываний _
‚ Выполняет полную инициализацию обоих. контроллеров
нием‘ прерыва ний 1800 - 1807 на векторы ТМТ 501 - 571.
; с отображе
коротки й звук после каждого ТВО1.
; Программа остается резидентной и издает.
; Восстановление старых обработчиков прерываний и переинициализация
‚ контроллера в прежнее состояние опущены. |

.тюде1 . 11пу
. сое ` : ь
ог9 1001 _ . ; СОМ-программа.

50 - ; На этот адрес процедура р1с_1п1{т перенесет


РТС1_ВАЗЕ _ еди
; 1800-.- ТНОТ. ° .
701.’ ^; На этот адрес процедура ‘р1с_114 ‘перенесет
Р1С2_ ВАЗЕ еду
; 1808 - 18015, ‚

этагт: (о |
; Переход на начало инсталляционной части,
Этр еп4_о{_гез14етт

1г90_папа1ег: : ; Обработчик ТН@0


| ‚ (прерывания от системного таймера). |
: `` :
ризй ах
а], 611 . |
1п
. апд а1, 111111006 ‚ Выключение динамика.
ош 611, а1 | |
ах . | ,
рор
11 081 ; Старый обработчик 1800.
_1гет ° ; Он послал ЕСТ, так’что завершить простым 1ге*
-
1г91_папд1ег: › ; обработчик 1801 (прерывание от клавиатуры).
рузп ах
п - @1, 68 ы
| — Сложные приемы программирования
ог. а1, 000000116 —; Включение динамика,
оч 611, а].
. рор ах
111 оэн | ‚ Старый обработчик ТВО1.
1гет |
й
1га2_ папа 1ег: ‚ И так далее.
19 ОАН
1гет
1га93_папа1ег:
111 ОВЕН
1гет ,
1г494_пал1ег:
у 11 оси
1гет
1г45_папа]ег:
11 о08
1гет
1146_пап@]ег:
171 ОЕВ
1гет
` 1747_Валпа1ег: | -
1 ЗОРИ ‹
1гех

еп4_оЁ_гез1депт: ; Конец резидентной части.


са] 1 ВооК_р1с1_1п1з —; Установка наших обработчиков
| $ АТ 501 - 571. й
са11 ‘1 _р1с ; Переинициализация контролНера прерываний.
_ ЮУ Чх, оРзеф еп4_о{._гез1
деп
пи 2 ; Оставить наши новые обработчики резидентными;

; Процедура 1п1{_р1с*
; Выполняет инициализацию обоих контроллеров прерываний,
‚ отображая 1800 -.ТВО7 на РТС1_ВАЗЕ - РТС1_ВАЗЕ+7,
‚; а 1808 - 18015 на РТС2 ВАЗЕ - РТС2_ВАЗЕ+Т.
; Для возврата в стандартное состояние вызвать
; РТС1_ ВАЗЕ =. 088,
; РТС2_ВАЗЕ = 708.
ПИ _р1с ргос пеаг

поу, | а1, 000101045 ; ТО. |


ош 201, а1 |
о ОАО, а]
поу а1, РТС1_ВАЗЕ ‚: `ТС\2 для первого’ контроллёра.
сит 218, а1 я у
моу а1, РТС2_ВАЗЕ ‚ ТСИ2 для второго контроляера. .:,
. от ОА1И, а1 |
МОУ ‚ ат, 040 ; ТСЗ для первого контроллера: и
сит 211, а1 |
МОУ - а1, 021. : Т6иЗ’ для второго контроллера: ``
! «
Программирование на уровне портов
оц ОАЧВ, а]
ОУ а], 000011016 ‚ 104 для первого контроллера.
от 211, а1 | -
том а1, 000010015 _'; 104 для второго контроллера.
от САЛА, а] ` . .
$11
. ге
115.1 епар -

; Перехват прерываний от РТС1_ВАЗЕ до РТСЛ_ВАЗЕ+Т.


поок_р1с1_1п1$ `ргос -пваг |
ту = ах, 25001+РТС1_ВАЗЕ
ту — @х,о1@зет 1г40_папб1ег
111 РА |
мо\ ах, 25011+РТС1_ВАЗЕ
оу ах,
ОТ зе 1га1_ПапдТег
17 2. ..
оу ах, 25021+РТС1_ВАЗЕ у
тоу Чх, отРвеЕ 1г42_ папа 1ег :
11 211
ом ах, 25031+РТС1_ВАЗЕ
МОУ 9х, отРзет 1га3.пап@ег
11 211
„МЮУ ах, 25041+РТС1_ВАЗЕ
оу 9х, от зе 1г44_папа1ег
пе _ 2 | |
оу ах, 25051+РТС1_ВАЗЕ.
МОУ 9х, оРзе{. 1г45, папа] ег
171 218 .
оу ах, 2506 1+РТС1_ВАЗЕ
МОУ ах, отГзет 1г4б_Папа1ег
1% 211
том ах, 2507Н+РТС1_ ВАЗЕ
тому вх, оРРзет 1г47_папа1ег
1% 21п.
гет
поок_р#с1_411$ — епар
епа зТагт

5.10.11. Джойстик -
И напоследок - о программировании ‘джойстика. Он подключается кеще одно-
му, помимо последовательного и параллельного, внешнему порту компьютера —
к игровому. Для игрового порта зарезервировано пространство портов ввода-вы-
вода от 200 до 20ЕЬ, но при общении с джойстиком используется всего один
порт - 201Ъ, чтение из которого возвращает состояние джойстика:
порт 201 для чтения:
биты 7, 6: состояние кнопок 2, 1 джойстика В
биты 5, 4: состояние кнопок 2, 1 джойстика А
ЕЕ: “ и!! Сложные
й
приемы программирования:

биты 3, 2: у- и х-координаты джойстика В


биты 1, 0: у- и х-координаты джойстика А
С состоянием кнопок все просто -- достаточно прочитать байт из 201 и опре-
делить значение нужных битов. Но для определения координаты джойстика при-
дется выполнить весьма неудобную и медленную операцию: надо записать в порт :|
р
201Ъ любое число и засечь время, постоянно считывая состояние джойстика. Сра-
зу после записи в порт биты координат будут равны нулю, и время, за которое
они обращаются в 1, пропорционально соответствующей координате (Х- коорди-
наты растут слева направо, а У-координаты - сверху вниз).
Если джойстик отсутствует, биты координат или будут единицами с самого на- `
чала, или останутся нулями ‘неопределенно долгое время. Кроме того, после запи-
:си в порт 201 нельзя производить это же действие еще раз, пока хотя бы один из
четырех координатных битов не обратится в 1.
В ВТО$ для работы с джойстиком есть функция ЗАВ прерывания 15Ъ, но обще-
ние напрямую с портами оказывается гораздо быстрее и ненамного сложнее. На-
пример, чтобы определить координаты джойстика, В1О$ выполняет целых четы-
ре цикла измерения координат, по одному на каждую.
Чтобы получить значение координаты в разумных единицах, мы определим, .
на сколько изменилось показание счетчика канала 0 системного таймера, и разде-
лим это число на 16 — результатом окажется то самое число, которое возвращает
ВТО$. Для стандартного джойстика (150 кОм) оно должно быть в пределах 0416,
хотя обычно максимальное значение оказывается около 150. Так как аналоговые
джойстики -— не точные устройства, координаты для одной и той же позиции мо-
гут изменяться на 1-2, и это надо учитывать особенно при определении состоя-
ния покоя. |
Покажем, как все это можно реализовать на примере чтения координат джой-
стика А:

; Процедура геад_}оуз1ск.
; Определяет текущие координаты джойстика А.
; Выход: ВР - \-координата, ВХ - Х-координата (-1, если джойстик
; не отвечает), регистры не сохраняются.

геаЧ_]оу$т1ск ргос пеаг


ризНЁ ; Сохранить флаги
611 р ; И отключить прерывания, так. как и
; вычисляется время выполнения кода и не |
‚ нужно измерять еще и время выполнения
‚ обработчиков прерываний.
му ‚ 6х, -1 ; Значение Х, если джойстик не ответит.
тому Бр,Бх ; Значение У, если джойстик не` ответит.
мо\ ах, 2011 _ ; Порт. |

меу а1,0
ие 431, а1 ` ‚; Зафиксировать счетчик канала 0. таймера.
1п а1, 408
Программирование на уровне портов
том ап, а? ах
11 - 21,408 _ : ВА
хсв9 ай, а] ; АХ = значение счетчика.
моу 91,ах _ ; Записать его в ОТ.

оц дх, а1 > Запустить измерение ‘координат’ джойстика.


1 а1, 9х _, ; Прочитать начальное состояние координат. Ш
апд 1,01% = |
_ по 61,21 — - ^^; Записать его в Си.
геаа_уоузт1ск_1обр: ве т
поу а1,0 — В ти .
би 431, а] °/ ; Зафиксировать ‘счетчик канала 0 таймера.
т а], 401 у . : =
ЮУ ^ ап,аЁ
11 21, 408 :
хСп9 ай, а] -;. АХ - значение счетчика.
том $1,91 _ ; 31 - начальное значение. ‚счетчика.
‘Зи $1, ах .- ‚ 5ЁГ - разница во времени, '
стр 731, ЛЕЕВ __; Если наступил тайм-аут
‚(значение взято из процедуры 810$),
Ча ех1{_геад] ^°’; выйти из ‘процедуры. |

Ш о 41,90х у Иначе: .` прочитате востояние джойстика


апд а1, 00115 .
стр а], с] ; сравнить его с предыдущим.
зе геа4_)оузЕ1ск_1оор . : | .
хепо а1,с1 ; Поместить новое значение в С4
хог а1,с1 ‚и определить ‘изменившийся бит..
тезт а1, 015 ; Если это Х-координата, “ `. -
уе. х_зате ` | -_ |
поу Бх, $1 ; записать Х-координату в ВХ.
х_зате: | .
тезт а1, 105 ; ЕСЛИ это \У-координата,
ру. геад доузНск. тоор ; | |
МОУ Бр, 51. ; записать У-координату в ВР.

`ех1{_геаа):
тезт бх, 6х.’ ; Проверить, равен ли ВХ -1.
3$ Бх_Баа | .
ЗВг -6х,4 .; Если. нет - разделить на 16.
Ьх_Бад: Тез* фр, Бр ; Проверить,. равен ли ВР -1.
33 „бр.вад . , .
Аг Бр, 4 ; Если. нет - ‘разделить на 16.
Ьр_Баа: :
рорЁ ^
геф
геад_)оузт1ск епар_

‚ Если вы когда- нибудь играли с помощью джойстика, то наверняка вам извест-


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

5.11. Драйверы устройств в 20$


Итак, в предыдущих разделах говорилось о том, как происходит работа с неко-
торыми устройствами на самом низком уровне- уровне портов ввода-вывода. Од-
нако прикладные программы обычно никогда не используют это уровень, а обра-
щаются ‘ко всем устройствам через средства операционной системы. ОО$5, в свою
очередь, обращается к средствам ВТО$, которые осуществляют взаимодействие на
уровне портов са всеми стандартными устройствами. Фактически процедуры
ВОЗ и выполняют функции драйверов устройств - программ, осуществляющих
интерфейс между операционной системой и аппаратной частью компьютера.
ВТО$ обычно лучше веего известно, как управлять устройствами, которые постав-
ляются вместе с компьютером, но, если требуется подключить новое устройство,
о котором В10$ ничего не знает, появляется необходимость в специально напи-
санном загружаемом драйвере.
Драйверы устройств в ОО$ - исполняемые файлы со специальной структу-
рой, которые, загружаются на этапе запуска (при выполнении команд РЕУ1СЕ
или РЕМ !СЕН!СН файла сопй8.5уз) и становятся фактически частью системы.
Драйвер всегда начинается с 18-байтного заголовка:
+00: 4 байта — дальний адрес следующего загружаемого драйвера РОЗ- так как
в момент загрузки драйвер будет последним в цепочке, адрес дол-
жен быть равен ОБЕЕЕВ:0ЕЕЕЕВ
+04: 2 байта — атрибуты драйвера
+06: 2 байта — адрес процедуры стратегии ОИ
+08: 2 байта — адрес процедуры прерывания
+0АБ: 8 байт — имя драйвера для символьных устройств (дополненное пробелами).
_ для блочных устройств— байт по смещению ОАЪ включает число
устройств, поддерживаемых этим драйвером, а остальные байты
могут содержать имя драйвера
Здесь следует заметить, что 20$ поддерживает два типа драйверов - символь-
ного и блочного устройств. Первый тип используется для любых устройств —
клавиатуры, принтера, сети, а второй - только для устройств, на которых могут
существовать файловые системы, то есть для дисководов, КАМ-дисков, нестан-
дартных жестких дисков; для достула к разделам диска, занятым другими ойера-
ционными системами, и т. д. Для работы с символьным устройством программа
должна открыть его при помощи.функции 2О$ «открыть'файлили устройство»,
а для работы с блочным устройством— обратиться |к соответствующему 1логичес-
кому. диску.
"Итак, код драйвера устройства представляет собой обычный код программы,
как и в случае с СОМ-файлом, но в начале не надо размещать директиву огё:100}
для пропуска РР. Можнотакже объединить драйвер и.исполняемую программу,
Драйверы устройств в.00$.
разместив. в ЕХЕ-файле код драйвера с нулевым смещением от начала сегмента,
а точку входа самой программы ‘ниже.
При обращении к драйверу ОО$ сначала вызываетт процедуру: стратегии (ад-
рес по.смещению 06 в заголовке), передавая ей адрес буфера запроса, содержа-
щий все параметры, передаваемые: драйверу, а затем процедуру прерывания (ад-
рес по смещению 08) без каких-либо параметров. Процедура стратегии должна
сохранить адрес буфера запроса, а процедура прерывания — собственно выпол-
нить все необходимые действия. Структура буфера запроса меняется в зависимо-
сти от типа команды, передаваемой драйверу, но структура его заголовка остается
постоянной:
+00Ъ: байт— длина буфера запроса (включая заголовок)
+01: байт- номер устройства (для блочных устройств) '
+023: байт— код команды (00 — 195)
+03Ь: 2 байта— слово состояния драйвера — должно ‘быть:заполненоо драйвером
бит 15: произошла ошибка
‚’ биты 10-14: 00000Ъ-
бит 9: устройство занято
бит 8: команда обслужена
‚ биты 7-0: код ошибки
`` 005: устройство защищено`от записи -
01В: неизвестное устройство ‹
021: устройство не готово ,
03Ъ: неизвестная команда
04В: ошибка СКС
05Ъ: ошибка в буфере запроса
06Ъ: ошибка поиска
07: неизвестный носитель" , а
08Ъ: сектор не найден о о
‚ 09Ъ: нет бумаги | |
‚ ОАЗ: общая ошибка записи
ОВЬ: общая ошибка чтения .
_ ОСЬ: общая ошибка
_ ОЕЪ: неожиданная смена диска`
+055: 8 байт— зарезервировано
+00: отсюда начинается область данных, отличающаяся для разных команд, |

`Дажеесли драйвер не поддерживает. запрошенную от:него функцию, он обяза-


тельно должен установить бит 8 слова состояния в 1.
Рассмотрим символьные и блочные драйверы на конкретных примерах.

5.11.1. Символьные устройства ``


Драйвер символьного устройства должен содержать в поле атрибутов драйве-
ра (смещение 94 в заголовке) единицу в.самом старшем бите. Тогда остальные
биты трактуются ‘следующим образом:
они Сложные приемы программирования
бит 15:1
бит 14: драйвер поддерживает функции чтения/записи ЮСТЕ
бит 13: драйвер поддерживает функцию вывода до занятости
бит 12:0 ,
бит 11: драйвер поддерживает ‘функции открыть/закрыть устройство
„биты: 10-8: 000
бит 7: драйвер поддерживает функцию запроса поддержки 1ОСТЕ.
бит 6: драйвер поддерживает обобщенный ГОСТИ.
бит 5: 0
бит 4: драйвер поддерживает быстрый вывод (через ГМТ 298)
бит 3: драйвер устройства «часы» _
бит 2: драйвер устройства МОГ,
_ бит 1: драйвер устройства ЗТРОПТ
‚ бит 0: драйвер устройства ЗТОТМ
ТОСТИ, - это болыной набор функций (свыше пятидесяти), доступных как
различные подфункции ПМТ 21Ъ АН = 44} и предназначенных для прямого взаи-
модействия с драйверами. Ноо 1ОСТЕ- чуть позже, а сейчас познакомимся с тем,
как устроён, возможно, самый простой из реально полезных драйверов.
В качестве первого примера рассмотрим драйвер, который вообще не обслужи-
вает никакое устройство, реальное или виртуальное, а просто увеличивает размер
буфера клавиатуры ВТО$ до 256 (или больше) символов. Этого можно было бы до-
биться обычной резидентной программой, но ВТО$ хранит в своей области данных
только ближние адреса для этого буфера, то есть смещения относительно сегмент-
ного адреса 0040}. Так как драйверы загружаются в память первыми, еще до коман-
дного интерпретатора, они обычно попадают в область линейных адресов 004001 -
10400, в то время как с резидентными программами этого может не получиться.
Наш драйвер будет обрабатывать только одну команду, команду инициализа-
ции драйвера 001. Для нее буфер запроса выглядит следующим образом:
+00Ъ: байт - 19Ъ (длина буфера запроса)
+016: байт —- не используется
+025: байт - 00 (код команды)
+03Ь: байт — слово состояния драйвера (заполняется. драйвером)
+05: 8 байт - не используется
+00: байт —— число обслуживаемых устройств (заполняется блочным драйвером)
+0ЕБ: 4 байта — на входе — конец доступной для драйвера памяти; на выходе —
адрес первого байта из той части драйвера, которая не будет ре-
зидентной (чтобы выйти без инсталляции - здесь надо записать
адрес первого байта) |
+12}: 4 байта - на входе— адрес строки в СОМЕ!С.5У5, загрузившей драйвер; на
выходе - адрес массива ВРВ (для блочных драйверов)
+16Ъ: байт — - номер первого диска
+17Ъ: 2 байта — сообщение об ошибке (00001, если ошибки не было). - запол-
няется драйвером
Драйверы устройств в20$ = _ ИНО ООНИОНИЕЗЕ.
Процедура инициализации может использовать функции 0ОО$ 01В- ОСЬ, 256,
ЗОВ и 358. :
‚ КБЧехт. азм .
‚ Драйвер символьного устройства, увеличивающий буфер клавиатуры `до ВУЕ_$17Е
‚. (256 по умолчанию) символов.

ВИЕ_517Е еди 256 , ‚. ; Новый размер буфера.


.100е] 11пу -
.186 - ; Для сдвигов и ризй 00401.
‚ собе ‘ а
ого 0 | ; Драйвер начинается с С$:0000.
этаг: и
; Заголовок драйвера. .
99 -1 ; Адрес следующего ‘драйвера - ОРЕЕЕВ: ОЕЕЕРВ
=. 5 для последнего. `
[е - 80001 . г, о. : Атрибуты: символьное устройство,
... $ Ничего не поддерживает. .
м _ ОТРзет зтгатеду .; Адрес процедуры стратегии.
9м оРзет 1тбеггирт ; Адрес процедуры ‘прерывания.
[Е] “$$КВОЕХТ" ``; Имя устройства (не должно ‘совпадать
‘ ``; с каким-нибудь именем файла).

гедиезт 93 ? р ; Здесь процедура стратегии сохраняет


о .‹ адрес буфера запроса.
Битег ‚ ВИР _$17Е*2 дир (?); А это - наш новый буфер
: клавиатуры размером ВИЕ_$12Е символов
2 : (два байта на’ символ).
`; Процедура стратегии.
; На. входе ЕЗ:ВХ= адрес буфера запроса.
этгатеду ргос Таг
оу с3:мога руг гедиезт,Бх ; Сохранить
этот, адрес для
ЮУ с$:могд рег гедиезт+2,ез ; процедуры прерывания.
гет . <=.
зтгатеду епар

‚ Процедура прерывания,
1птеггирт ргос фаг
ризй 9$ . — ; Сохранить регистры:
°‘ризй 5х - : 1 т.
ризй ах я . ; . 2.
198 5х, дога рег св:гедиез®: . ;..0$:ВХ
.-. адрес. запроса.
тои °' ап,Буе рег [6х+2]. в Прочитать номер команды.
ог. ал, ай ; Если команда ОбН (инициализация)
37. ви ИИ |
са11 ии о’. ‚ обслужить ее.
; Иначе:
ех1т: поу ах, 1001 ; установить бит 8 (команда обслужена)
оу < мог рег [5х+3],
ах `; В слове состояния драйвера
рор ах ‚; и восстановить: регистры.
`

Сложные приемы программирования.


рор 6х
рор 9$
гех
1отеггире епар
}

; Процедура инициализации.
; Вызывается только раз при загрузке драйвера.
ТП ‚ргос пеаг
ризй сх
ризН 9х

том ах, оРРзет БиГРег


оу сх, 6$ СХ:АХ - ‘адрес нашего буфера клавиатуры.
стр ` сх, 10001 Если СХ слишком велик,
пс 100_019 не надо загружаться.
381 сх,4 Иначе: умножить сегментный адрес на 16,
ада сх, ах добавить смещение - получился
линейный адрес.
Зиь о сх, 4008 Вычесть линейный адрес начала данных ВТ05.

ризИ 00408
‚ рор 3.
МОУ 5х, ЛАВ - 0$:8Х = 00401:001АВ .- адрес головы..
тоу мога рег [6х],сх Записать новый адрес головы буфера.
поу могб рег [6х+2],сх Он же новый адрес хвоста.
тому 3, 808 05:8Х = 00401:0080Н -
адрес начала буфера.
оу мога ртг [5х],
сх Записать новый адрес начала.
а94 сх, ВИЕ_$17Е*2 Добавить размер
оу мога рег [6х+2),сх и записать новый адрес конца.

оу ан, 9 . Функция 005 09.


моу 9х, оРГзет зисс_тз9 0$:0Х - адрес строки
ризй 65 с сообщением 0б успешной установке.
рор 95
111 218 Вывод строки на экран,

135 Ьх, дога ртг сз: гедиезт ; 0$:8Х - адрес ‘запроса,


мо ах, оРзет 1711
мо мог рег [Ьх+0ЕН],ах у ; С5:АХ - следующий байт. после
ем мога рег [5х+108],сз конца резидентной масти.
Лир ЗПогЕ допе, ; Конец процедуры инициализации.

‚ Сюда передается управление, если мы’ загружены слишком низко ‘в` памяти,
100.-510:
поу ан,9 Функция 00$ 091. ВЫ '
тому 9х, оЕЁз6т Та11_п$9 ; 05:0Х - адрес строки’
ризв с$ с сообщением о неуспешной
рор 38 установке.
111 211 Вывод строки на экран.
,
193. Ьх, лога рфг с$: гедиезт у 05:8Х - адрес запроса.
Драйверы устройств в 00$
моу ° могд р&г [6х+0ЕВ],0 ; Записать адрес начала драйвера.
оу мог рег [Ъ5х+108],с5 ; в поле "адрес первого {
; освобождаемого байта”.
Чопе: ° рор _ ах
рор сх °
ге! .
ПИ - епар : . .
Сообщение об успешной установке (на английском, потому что в этот момент
; русские шрифты еще не загружены).
3и6С_ $0 Ге “Кеубоагф ехтепдег. Зюадед" ‚ б0в, бАл, '$'
; Сообщение о неуспешной ‘установке.
2а1]_п$9 [29] "Лоо тапу Чг1мегз 1п тетогу - “_
96 “риЁ КЫдех*.зуз РАгзт “
(+) “]п с0п{19.зуз“,ООВ, ОАВ, '$'
епа’ эта
Теперь более подробно рассмотрим функции, которые должен поддерживать
ВОТ13— драйвер символьного устройства. КОТ13- это метод простой модифи- ‘

кации английского текста, применяющийся в электронной почте, чтобы текст


нельзя было прочитать сразу. Методика заключается в сдвиге каждой буквы ла-
тинского алфавита на 13 позиций (в любую сторону, так как всего 26 букв). Рас-
кодирование, очевидно, выполняется Такой жее операцией. Когда наш ‚драйвер за-
гружен, команда ОЗ - — ,
сору епсгурт.тх{ гот13

приведет к тому, что текст из епсгуре.хЕ будет выведен на экран, зашифрованный или
расшифрованный КОТ1З, в зависимости от того, был ли он зашифрован до этого.
Рассмотрим все команды, которые может поддерживать символьное устрой-
ство, и буфера запросов, которые им передаются.
`00Ъ: инициализация (уже рассмотрена)
0ЗЬ: ТОСТТ--чтение (если установлен бит 14 атрибута)
+0ЕЪ: 4 байта — адрес буфера —
+12Ъ: 2 байта — на входе — запрашиваемое число байтов
на выходе — реально записанное в буфер число байтов
04Ь: чтение из устройства
структура буфера для символьных устройств совпадает с ОЗЬ
05Ь: чтение без удаления символа из буфера |
+00Ъ: на выходе — прочитанный символ, 5.
если символа нет- установить бит 9 слова состояния
06Ъ: определить состояние буфера чтения,
если в буфере нет символов для чтения— установить бит 9 слова состояния
07Ь: сбросить буфер ввода. = а
08Ъ: запись в устройство. _ !
+0ЕЬ: 4 байта - адрес буфера
+125: 2 байта — на входе — число байтов для записи
на выходе — число байтов, которые были. записаны
ШЕ!! — Сложные приемы программирования
09Ъ: запись в устройство с проверкой
аналогично 08Б
ОАБ: определить состояние буфера записи,
‘если в устройство нельзя писать — установить бит 9 слова состояния
ОВЬ: сбросить буфер записи
— 0СЬ: ТОСТГ-запись (если установлен бит 14 атрибута),
аналогично 08В |
ООЬ: открыть устройство (если установлен бит 11 атрибута)
ОЕБ: закрыть устройство (если установлен бит 11 атрибута)
118: вывод, нока не занято (если установлен бит 13 атрибута),
аналогично 08 |
в отличие от функций записи здесь не считается ошибкой записать не все
байты
13В: обобщенный 1ОСТГ. (если установлен бит 6 атрибута)
+0ТБ: байт - категория устройства (01, 03, 05 = СОМ, СОМ, ТРТ)
| 00№ — неизвестная категория
+0ЕБ: байт — код подфункции: |
451: установить число повторных попыток
65}: определить число повторных попыток
4АЪ: выбрать кодовую страницу
6АБ`определить активную кодовую страницу
4СЬ: начало подготовки кодовой страницы
АОВ: конец подготовки кодовой страницы
6ВВ: получить список готовых кодовых страниц
5ЕВ: установить информацию о дисплее
7ЕВ: получить информацию о дисплее -
+0ЕЪ: 4 байта — не используются `-
+135: 4 байта— адрес структуры данных ТОСТ. - соответствует структуре, пе-
редающейся в О$:ОХ для ИМТ 21%, АХ- 440СВ
195: поддержка функций ГОСТИ, (если установлены биты 6 и 7 атрибута)
+005: байт - категория устройства |
+0ЕЪ: байт - код подфункции . |
Если эта комбинация подфункции и категории устройства не поддерживается
драйвером - надо вернуть ошибку 0ЗЬ в слове’состояния.
Итак, теперь мы можем создать полноценный драйвер символьного устрой-
ства. Упрощая задачу, реализуем только функции чтения из устройства и будем
возвращать соответствующие ошибки для других функций.
Еще одно отличие этого примера - в нем показано, как совместить в одной
программе исполняемый файл типа ЕХЕ и драйвер устройства. Если такую про-
грамму запустить обычным образом, она будет выполняться, начиная со своей
точки входа (метка 5баг в нашем примере), а если ее загрузить из СОМЕТС.$У5,
РО$5 будет считать драйвером участок программы, начинающийся со смещения 0.
Драйверы устройств. в 205.
; го13. авт
; Драйвер символьного устройства, выводящий посылаемые ему символы на экран
‚ после выполнения над ними преобразования В0Т13
: (каждая буква английского алфавита смещается .на 13 позиций).
‚ Реализованы только функции зачиси в устройство.

; Пример использования:
‚ сору епсгуртед.тхЕ $гот13
; Загрузка - из СОМЕТб. 95
; ОЕМТСЕ=С:\го{13.ехе, .
‚; если гот13.ехе находится в директории С:\.- в

..00де1 зта}1 ; Модель для ЕХЕ-файла.


‚воде и | | |
. 186 . . ; Для ризпа/рора..
0г9 0 . ; Код драйвера ‘начинается с. 05:0000.
94 -1 ` ‚Адрес следующего драйвера.
[6 048001 . $ Атрибуты. нашего устройства.
дм оТРзе{ф зтгафеду ; Адрес процедуры . стратегии.
@м оГРзет уптеггирт ; Адрес процедуры прерывания.
[0 "$Н0Т13",201,20н ; Имя устройства, ‘дополненное .
; пробелами до’ восьми символов.

гедиезт 69 ? ; Сюда процедура стратегии будет писать


и
‚; адрес буфера запроса. -

; Таблица адресов обработчиков для всех команд.


соттапа_фае = ом ° ОРЕзер и - ; 00
ди 3 Чир(оРЕзет ипзиррогтед); 01, 02, 03
ом 2 Чир(оЁРзе{ геад) ; 04, 05
ди 2 дир(оГЕзет. ипзиррог{еа); 06, 07
м 2 дир(оТРзет игЦе) ‚. о8н, 09н
би 6 дир(о[Езее ипзиррогтеа) ; бАВ,` ОВВ, СВ, 008, ОЕП, ОРВ
9 оРЕБет игле — ; 10 ^^ .
9 2 дир(оРЕ5ет 1п\ма119) ; АВ, 128
дм оЕЕзет ипзиррогеед .. 13
м 3 дур(оРРзет 1пуа119) ; 140, 158, 160
„и. . 3 ир(оРЕзеф ипзиррогед); 17, 181,. 191

; Процедура стратегии - одна’И-та же для всех драйверов. -:- -


зтгатеду ргос Таг
моу мог рег сз: гедиез+, 5х
"То мога рег сз: гедиезт+2,5 о я

зтгафеду епар

; Процедура прерывания.
1птеггир\ ргос Раг
изв
ризНа ` ; Сохранить регистры
шо Сложные приемы программирования _ 3
ризй 9$ ‚ и, На всякий случай, флаги.
ризй ез

ризй 6$
рор 95 — ; 0$ = наш сегментный ‘адрес.
1е5. $1, 0м0гд ‘рфг гедиезт ; 5:51 = адрес буфера запроса.
хог Ьх, 5х .
том Ь1, Буфе рег ез:[$1+2] ; ВХ = номер функции.
стр 61, 191 . ; Проверить, что команда
; в пределах 00 - 191.
, ]ъе сотмапа ок .
` са11 1пуа119 ‚ Если нет - выйти. с ошибкой.
тр ЗВогф 1птеггире_
ета
сомтапа_- ок: | , ; Если команда находится в пределах 00 - 198,
$81 _бх,1 ; Умножить ее на 2, чтобы получить
; смещение в таблице слов соттапа_ Табе,
са11 могд ртг сомталд_ТаБ1е[Ьх]; и вызвать обработчик.
1птеггурт_епд: .
стр а1,0 ; АЁ = 0, если не было ошибок.
3е по_еггог |
ог ав, 808 ; Если была ошибка - установить бит 15 в.АХ,
по_еггог:
ог “ав, о1п' > ; В любом случае установить бит 8
пом мог руг ез:[$1+3],ах ; и записать слово состояния.
рор ез
рор ` 9$
`рора р
рорт . у ый
гет -
1птеггирт епдр °

‚ Обработчик команд, предназначенных для блочных устройств.


упзиррогТед ргос пеаг . , .
хог ах, ах ; Не возвращать никаких ошибок.
. гет
упзиррогтед епар

; Обработчик команд чтения.


геад ргос пеаг . `
том а1, ОВК ; Общая ошибка чтения.
гет -
геад епар
; Обработчик несуществующих команд.
1пуа119 ргос пеаг .
мо ах, оЗя В ; Ошибка “неизвестная. команда“.
гет а | у
1пума119 | епар
; Обработчик функций записи.
мг Те ‚ . ргос пеаг
ризн $1
Драйверы устройств в20$
моу ‚ сх, мога рёг ез:[31+128] ; Длина буфера в СХ.
7ех2 мг1Те_11п13Нед ; Если это 0 - снам делать. нечего...
\ 195. $1, мог4 руг ез:[31+0Е!] ; Адрес буфера в 03:51.
; Выполнить ВОТ13-преобразование над буфером.
19
го{13 _1оор: ; Цикл по всем символам буфера.
109365 ; АЁ = следующий символ из буфера в ЕЗ:5Т..

стр а], 'А’' ’ Если он меньше “А”,


д гот 13_допе ; это не буква.
стр а], °2' ‚Если он больше “7”,
19 го 13_10\ может быть, это маленькая буква.
. стр а1, (^А”+13) ‹ Иначе: если он: больше “А” + 13,
39е гот13_дес вычесть из него 13,
"р Вог из. 1пс а в противном случае - добавить.
гот13_ 10м:
стр а], 'а' ` Если символ меньше’ “а”,
Л гох13_допе ‚это не буква.
_ стр а1,'2’ Если символ больше “2” -
39 гот13_вопе то же самое.
стр а1, ("а"+13) Иначе: если он больше “а” + 13,
39е гот13._дес ‚ вычесть из него 13, иначе:
го{13 _1пс:
ада а], 13 добавить 13 к. коду символа,
тр ЗПог{ гот13_допе
гот13. дес-
‚ 366 а1,13 ’ вычесть 13 из кода символа,
гот13. допе:
1 298 вывести символ на экран
1оор го{13_10ор ‚ и повторить для всех, символов.

мг е_Р1п131ед:
хог ах, ах ` ‚ Сообщить, что ошибок не было.
рор $1
гет
иг Те епар

‚ Процедура инициализации драйвера.


пи ргос ^ пваг
ам,9 ; Функция 00$ 09п. -
9х, оРзет 10а4_т59 ; 05:0Х - сообщение об установке.
эВ. ; Вывод строки на, экран.
мога рег ез:[$1+0Е1], оРРзет 1п1{ ; Записать, адрес
могд- рег е$:[31+101],с8 ; конца резидентной части...
ах, ах ‚ Ошибок не произошло.

п 9пар

; Сообщение об установке драйвера.


1оа4_тз9 95‘ ” “ВОТ13 Чеу1се 4г1уег 1оадед” ‚оон, АН, ‚$’
А

Сложные приемы программирования. :


; Точка входа ЕХЕ-програмны.
ризН с
рор 9$ | ;
ту . (Хх, ОРРэеф ехе_т$9 ‚ 03:0Х - адрес строки.
тому ап, 9 ; Функция 00$.
1% 211 ; Вывод строки на экран. °.
тоу ав, 4Сп ‚ Функция 00$ 4СП.
11 218 . ; Завершение ЕХЕ-программы.

; Строка, которая выводится при’ запуске не из СОМЕТС. 5\5:


ехе_пт59 ` 46 “Эту программу надо загружать, как драйвер устройства из”
6 “СОМЕТа. 5У5", ОБЛ, АВ, '$'

. ЗТаск ‘

епа ЭТагт

5.11.2. Блочные устройства


Блочными устройствами называются такие устройства, на которых ОО$ мо-
жет организовать файловую систему. РО$ не работает напрямую с дисками через
ВТОЗ, а только с драйверами блочных устройств, каждое из которых представля-
ется системе как линейный массив секторов’ определенной длины (обычно 512
байт) с произвольным доступом (для ВОЗ, к примеру, диск — это четырехмер-
‘ный массив секторов, дорожек, цилиндров и головок). Каждому загруженному
устройству ОО$ присваивает один или несколько номеров логических дисков,
которые соответствуют буквам, используемым для обращения к ним. Так, стан-
дартный драйвер дисков получает буквы А, В, С и так далее, по числу видимых
рааделов на диске.
Рассмотрим атрибуты и команды, передающиеся блочным устройствам.
Атрибуты:
бит 15: 0 (признак блочного устройства)
бит 14: поддерживаются 1ОСТТГ-чтение и запись
бит 13: не требует копию первого сектора ЕАТ, чтобы построить ВРВ
бит 12: сетевой диск
бит 11: поддерживает команды открыть/закрыть устройство и проверить, яв-
ляется ли устройство сменным
биты 10-8: 000 ,
бит 7: поддерживается проверка поддержки ТОСТТ.
бит 6: поддерживается обобщенный 1ОСТТ. и команды установить и опреде-
лить номер логического диска
биты 5-—2:.0000 ,
бит 1: поддерживаются 32-битные номера секторов
бит 0: 0
Команды и структура переменной части буфера запроса для них (только то,
что отличается от аналогичных структур для символьных устройств):
Драйверы ‘устройств в РО$ |335]
006: инициализация |
+01: — байт количество устройств, которые поддерживает драйвер`
+128: 4 — байта дальний адрес массива ВРВ--структур` {по одной для каждого. ус-
тройства)
ВРВ - это 25-байтная структура. (53 для РАТЗ2), которая
к описывает блочное
устройство. `Ее можно найти по смещению ов от начала нулевого сектора на
любом диске:
+0: 2 байта — число байтов в секторе (обычно 512)
+2: байт - число секторов.в кластере (20$ выделяет пространство на’дис-
ке для файлов не секторами, аобычно более крупными единица-
ми- кластерами. Даже самый маленький файл занимает один
кластер)
+3: 2 байта — число секторов до начала ЕАТ (обычно один — загрузочный)
+5: байт — - число копий:РАТ (обычно 2) (ЕАТ- это список кластеров, в ко-
торых расположен каждый файл. РОЗ делает вторую копию,
чтобы можно было восстановить диск, если произошел сбой
с во
. время модификации ЕАТ)
+6: 2 байта — максимальное число файлов в корневой директории
+8: 2 байта — число секторов на устройстве (если их больше 65 536 — здесь за-
| писан 0)
+ФАБ:байт —— описатель носителя (ОЕВН- для жестких дисков, ОЕОВ— для дис-.
кет на 1,2 и 1,44 Мб, атакже других устройств).
_ +6 ВВ: 2 байта — число секторов водной копии РАТ`(0; если больше 65 535)
+9098:2 байта — число секторов на дорожке (для доступа средствами ВЮ05) -
+0ЕЬ: 2 байта — число головок (для доступа средствами 8105)
+1: 4 байта — число скрытых секторов
+155:.4 байта — 32-битное число секторов на диске
{следующие поля действительны только для дисков, использующих РАТЗ2)
+16}: 4 байта - 32-битное число секторов в ВАТ
+1ОБ:байт - флаги но
бит 7: не обновлять резервные копиии БАТ
биты 3-0: номер активной ЕАТ, если бит7 = 1
+1ЕБ: 2 байта — версия файловой системы (00008 для УЛпдом$ 95 0582)
+216: 4 байта- номер кластера корневой директории
+251: 2 байта — номер секторах инфармацией.о файловой ‹системе (ОЕЕЕЕЬ, если .
он отсутствует)
+27Ъ: 2 байта - номер сектора запасной копии загрузочного сектора (ОРЕРРЬ,
если отсутствует)
+29Ъ: 12 байт— зарезервировано
Для всех остальных команд в поле буфера запроса со смещением +1 размеща-
ется номер логического устройства из числа обслуживаемых драйвером, к кото-
рому относится команда:

{3 Зак. 459
#1! Сложные приемы программирования
01: проверка носителя ,
+00: байт — на входе — описатель носителя
на выходе — ОРЕВ, если диск был сменен
01Ь, если диск не был сменен
00Б, если это нельзя определить
+0ТЕЪ: 4 байта — адрес АЗС 7-строки с меткой диска (если установлен бит 11
в атрибуте)
028: построить ВРВ
+0ПБ: описатель носителя
+0ЕЪ: 4 байта — на входе — дальний адрес копии первого сектора РАТ
на выходе - дальний адрес ВРВ
03В: ОСТГ--чтение (если установлен бит 14 атрибута)
04В: чтение из устройства |
+005: байт — описатель носителя
+128: 2 байта — на входе - число секторов, которые надо прочитать
на выходе — число прочитанных секторов .
+161: 2 байта — первый сектор (если больше 65 535'— здесь ОЕЕЕЕВ)
+185: 4 байта — на выходе — адрес метки диска, если произошла ошибка ОРЬ
+1СЪ: 4 байта- первый сектор |
`08Ъ: запись в.устройство.
структура буфера аналогична 04} с точностью до замены чтения на запись
09Ь: запись в устройство с проверкой |
аналогично 08
©СЬ: ТОСТЕ-запись (если установлен бит 14 атрибута)
ОБ: открыть устройство (если установлен бит 11 атрибута)
ОЕВ:. закрыть устройство (если установлен бит 11 атрибута)
ОЕВ: проверка наличия сменного диска (если установлен бит 11 атрибута):-
драйвер должен установить бит 9 слова состояния, если диск сменный,
и сбросить, если нет
135: обобщенный ТОСТТ, (если установлен бит 6 атрибута)
+0ПЬ: байт - категория устройства:
08Ъ: дисковое устройство
48В: дисковое устройство с ЕАТЗ2
+0ЕЪ: код — подфункции:
401: установить параметры
60}: прочитать параметры
41Ъ: записать дорожку
425: отформатировать и проверить дорожку
621: проверить дорожку
46Ъ: установить номер. тома
66Ъ: считать номер тома
47: установить флаг доступа
671: прочитать флаг доступа
68Ъ: определить тип носителя (2О$ 5.0+)
Драйверы устройств в 005$ — _ Минин
4АВ: заблокировать логический диск (АИпдо\з 95),
бАВ: разблокировать логический диск (УЛп4о\з 95)
4ВВ: заблокировать физический диск (УЯпао\$ 95)
‚ 6ВЬ: разблокировать физический диск (МЛп4о\з 95)
_ 6СЬ: определить флаг блокировки (УЙЯп4о\$ 95)
6): перечислить открытые файлы (УЙпдо\з 95).
`бЕН: найти файл подкачки (УЙп4о\з 95)
6ЕЬ: получить соотношение логических и физических дисков (\/т4о\з 95).
70Ъ: получить текущее состояние блокировки (УЙпдо\з 95)
71: получить адрес первого кластера (УЛп4о\з 95)
+131: адрес структуры (аналогично ПМТ 21 АХ= 4400)
17: определить логический диск (если установлен бит. 6 атрибута)
+018: байт — на входе — номер устройства
на выходе — его номер диска (1-А, 2-В) ,
18: установить логический диск (если установлен бит: 6 атрибута)
_ +018: байт - номер устройства
(команды 17В и 18 позволяют РО$ обращаться к одному и тому же
` дисководу как к устройству А: и как к устройству В)
196: поддержка функций ТОСТЕ, (если установлены биты 6 и 7. атрибута)
Для написания своего драйвера блочного устройства можно пользоваться схе-
мой, аналогичной символьному драйверу из предыдущей главы. ‚Единственное |
важное отличие - процедура инициализации должна будет подготовить и запол-
нить ВРВ, а также сообщить 2О$ число устройств, для г которых действует этот.
драйвер.
Глава 6. Программирование
в защищенном режиме
Все, о чем рассказано до этой главы, рассчитано
на работу под управлением РО$
в реальном режиме процессора (или в режиме \86), унаследованном еще с семи-
десятых годов. В этом режиме процессор неспособен адресоваться к памяти выше
границы первого мегабайта. Более того, так как для адресации используются
16-битные смещения (РМ), невозможно работать с массивами больше 65 536
байт. Защищенный режим лишен этих недостатков, в нем можно адресоваться
к участку памяти размером 4 Гб как к одному непрерывному массиву и вообще
забыть о сегментах и смещениях. Этот режим намного сложнее реального, поэто-
‚му, чтобы переключить в него процессор и поддерживать работу, надо написать
небольшую операционную систему. Кроме того, если процессор уже находится
под управлением какой-то операционной системы, которая перевела его в защи-
щенный режим, например УЛп4о\ 95, она, скорее всего, не разрешит программе
устранить себя от управления компьютером. С этой целью были разработаны спе-
циальные интерфейсы, позволяющие программам, запущенным в режиме У86
В 005$, переключаться в защищенный режим простым вызовом соответствующе-
го прерывания- УСРТ и ОРМЕ

6.1. Адресация в защищенном режиме_


Прежде чем познакомиться с программированием в защищенном режиме, рас-
смотрим механизм адресации, применяющийся в нем. Так же как и в реальном
режиме, адрес складывается из адреса начала сегмента и относительного смеще-
ния, но если в реальном режиме адрес начала сегмента просто лежал в соответ-
ствующем сегментном регистре, деленный на 16, то в защищенном режиме не все
так просто. В сегментных регистрах находятся специальные 16- битные структу-
ры, называемые селекторами и имеющие следующий вид: р
к

биты 15-3: номер дескриптора в таблице


бит 2: индикатор таблицы 0/1 — использовать сотлот.
биты 1-0: уровень привилегий запроса. (КРТ.)
Уровень привилегий запроса — это число от ( до 3, указывающее степень защи-
ты сегмента, для доступа к которому применяется данный селектор. Если програм-
‚ ма имеет более высокий уровень привилегий, при использовании этого сегмента
привилегии понизятся до ВРГ.. Уровни привилегий и весь механизм защиты в за-
щищенном режиме нам пока не потребуются. и ..*

о
Адресация в защищенном режиме НАИИВЕЕЯ
СОТ и ГОТ - таблицы глобальных и локальных дескрипторов соответствен-
но. Это таблицы. 8-байтных структур, называемых дескрипторами сегментов, где
и находится начальный адрес сегмента вместе с. другой важной информацией:
слово 3 (старшее):
биты 15-8: биты 31—24 базы
бит 7: бит гранулярности (0- лимит в байтах, 1 - лимит в 4-килобайтных еди-
ницах)
бит 6: бит разрядности (0/1
1 - 16-битный/3?2- битный сегмент)
бит 5: 0 :
бит 4: зарезервировано для операционной системы
биты 3-0: биты 19-16 лимита
слово 2:
бит 15: бит присутствия сегмента
биты 14-13: уровень привилегий дескриптора (ОРГ.)
бит 12: тип дескриптора (0 — системный, 1 - обычный)
‚ ‘биты 11-8: тип сегмента
биты 7-0: биты 23-16 базы
слово 1: биты 15-0 базы'
слово 0 (младшее): биты 15-0 лимита
Два основных поля структуры, которые нам интересны, — это база и лимит сег-
мента: База представляет линейный 32-битный адрес начала сегмента, а лимит —
20-битное число, которое ‘равно размеру сегмента в байтах (от 1 байта до 1 мега-
байта), если бит гранулярности сброшен в ноль, или в единицах по 4096 байт (от
4 Кб до 4 Гб), если он установлен в 1. Числа отсчитываются от нуля, так что ли-
мит 0 соответствует сегменту длиной 1 байт, точно так же, как база 0 соответству-
ет первому байту памяти,
Остальные элементы ‚дескриптора выполняют следующие функции:
1. Бит разрядности: для сегмента кода этот бит указывает. на разрядность опе-
рандов и адресов по умолчанию. То есть в сегменте с этим битом, установ-
ленным в 1, все команды будут интерпретироваться как 32-битные, а. пре-
фиксы изменения разрядности адреса или операнда будут превращать их
в 16-битные, и набборот. Для сегментов данных бит разрядности управляет
тем, какой регистр (5Р или Е$Р) используют команды, работающие с этим
сегментом данных как со стеком.
2. Поле ОР!. определяет уровень привилегий сегмента.
3. Бит присутствия указывает, что сегмент реально есть в памяти. Опера-
ционная система может выгрузить содержимое сегмента из памяти на диск
и сбросить бит присутствия, а когда программа попытается к нему обратить-
° ся, произойдет исключение, обработчик которого снова загрузит содержи-
мое данного сегмента в память. |
4. Бит типа дескриптора — если он равен 1, сегмент является обычным сегмен-
° том кода или данных. Если этот бит - 0, дескриптор является одним из 16
возможных видов, определяемых полем типа сегмента.
Программирование вРМ .
5. Тип сегмента: для системных регистров в этом поле находится число от 0 до
15, определяющее тип сегментов (Т.ОТ, Т$$, различные шлюзы), которые
рассмотрены в главе 9. Для обычных сегментов кода и данных эти четыре
бита выполняют следующие функции:
бит 11:0 — сегмент данных, 1 — сегмент кода
бит 10: для данных -— бит направления роста сегмента
для кода — бит подчинения
бит 9: для данных — бит разрешения записи
для кода - бит разрешения чтения
бит 8: бит обращения |
6. Бит обращения устанавливается в 1 при загрузке селектора этого сегмента.
в регистр.
7. Бит разрешения чтения/записи выбирает разрешаемые операции с сегмен-
том — для сегмента кода это могут быть выполнение или выполнение/чте-
ние, а для сегмента данных — чтение или чтение/запись.
‚ 8. Бит подчинения указывает, что данный сегмент кода является подчинен-
ным. Это значит, что программа с низким уровнем привилегий может пе-
редать управление в сегмент г кода и текущий уровень привилегий не из-
менится.
9. Бит направления роста сегмента бращает смысл лимита сегмента. В сег-
ментах с этим битом, сброшенным В НОЛЬ, разрешены абсолютно все смеще-
ния от 0 до лимита, а если этот бит 1, то допустимы все смещения, кроме от
0 до лимита. Про такой сегмент говорят, что он растет сверху вниз, так как
если лимит, например, равен—100, допустимы смещения от —100 до 0, аесли
лимит увеличить, станут допустимыми еще меньшие смещения.
Для обычных задач программирования нам не потребуется все многообразие
возможностей адресации. Единственное, что нам нужно, — это удобный неогра-
ниченный доступ кпамяти. Поэтому мы будем рассматривать простую модель па-
мяти — так называемую модель Йа, где базы всех регистров установлены в ноль,
а. лимиты - в 4 Гб. Именно в такой ситуации окажется, что можно забыть о сег-
‘ментации и пользоваться только 32-битными смещениями.
Чтобы. создать Йа(-память, нам потребуются два дескриптора.с нулевой базой аак
бе
а
аа
д,
и максимальным лимитом — один для кода и один для данных.
Дескриптор кода: лак
а
лимит ОЕЕЕЕЕВ |
база 00000000 а | ' а

тип сегмента ОЕАБ |


бит присутствия = 1
уровень привилегий= 3 (минимальный)
бит типа дескриптора = 1
тип сегмента: 1010Ъ (сегмент кода, для выполнения/чтения).
Интерфейс МСРЕ _
бит гранулярности = 1
бит разрядности = 1
[е]* ‘ОРРА, ОРЕВ, ОВ, Он, ОН, ОРАВ,: `ОСЕИ, ОВ

Дескриптор данных:
лимит ОЕЕРЕЕЬ
база 000000008
бит присутствия = 1
уровень привилегий= 3 (минимальный)
бит типа дескриптора = 1
тип сегмента: 0010Ъ (сегмент данных, растет вверх, для | чтения/записи)
бит гранулярности = 1
бит разрядности = 1
96 ОРЕл, ОРРА, ОН, ОВ, ОН, ОЕ2А, ОСЕНИ, Он

Для того чтобы процессор знал, где искать дескрипторы, операционная систе-
ма собирает их в таблицы, которые называются СОТ (таблица глобальных деск-
рипторов - может быть только одна) и Г.ОТ (таблица локальных дескрипторов —
по одной на каждую задачу), и загружает их при помощи привилегированных
команд процессора. Так как мы пока не собираемся создавать операционные сис-
темы, нам нужно только подготовить дескриптор и вызвать соответствующую
функцию УСР! или ОРМ!.
Заметим также, что адрес, который получается при суммировании базы сег-_
мента и смещения, называется линейным адресом и может не совпадать с физи-
ческим, если дело происходит в операционной системе, реализующей виртуаль-
ную память с помощью специально предусмотренного в процессорах Пе!
страничного механизма виртуализации памяти.

6.2. Интерфейс УСР! ` т.


Спецификация интерфейса УСРГ была создана в 1989 году (вскоре после по-
явления процессора 80386) компаниями РБаг [Гар Зо_\аге и О/пацег4еск ОЁйсе
Зузетз. Программа, применяющая УСР! для переключения в защищенный ре-
жим, должна поддерживать полный`набор системных таблиц- СОТ, ГОТ, ШТ,
таблицы страниц и т. д. То есть фактически УСР/[-сервер обеспечивает следующее:
процессор находится в защищенном режиме,и различные программы, пользую-
щиеся им, не конфликтуют между собой.
УСР! является своего рода расширением интерфейса ЕМ$, и все обращения
к нему выполняются при помощи прерывания ЕМ$, ПМТ 67 с АН = ОРЕВ и ко-
дом подфункции УСРГ в АГ.
МТ 67. АХ = ОБЕДОВ: Проверка наличия УСР1
„Вход: АХ = ООЕООЬ
Выход: АН = 00, если УСРТ есть
ВН, ВИ. - версия (старшая, младшая цифры)
[9 СТИ Программирование в РМ
Т№Т 678. АХ = ОРЕОЛЕ: Получить точку входа УСР]
Вход: АХ = ОРЕО1Ь
ЕЗ:ОТ = адрес 4-килобайтного буфера для таблицы страниц.
05:51 = адрес таблицы дескрипторов
Выход: АН= 0, если нет ошибок
25:51: первые три дескриптора заполняются дескрипторами СР. сервера.
ЕЗОГ адрес первой не используемой сервером записи в таблице страниц
ЕВХ: адрес точки входа УСРТ относительно сегмента, дескриптор кото-
рого лежит первым в таблице 05:51. Можно делать #аг са из 32-битно-
го защищенного режима на этот адрес с АХ = ООЕООВ — ОРЕОБЬ, чтобы
пользоваться функциями УСР] из защищенного режима
№Т 67} АХ= ОБЕОСЕ: УСРЕ переключиться в защищенный режим (для вызова
из \86)
Вход: АХ = ОРЕОСЬ
Е$Г = линейный адрес таблицы со значениями для системных регист-
ров (в первом мегабайте)
+00Ъ: 4 байта — новое значение СВЗ
+041: 4 байта — адрес 6-байтного значения для СотВ
+081: 4 байта — адрес 6-байтного значения‘ для ТЕ
+0СЬ: 2 байта - ГОТЕ,
+0Е$: 2 байта — ТК.
+101: 6-байт— СЗ:ЕТР — адрес.точки входа
прерывания должны быть запрещены
Выход: Загружаются регистры СОТК, ОТВ, ГОТВ, ТК. Теряются регистры
`ЕАХ, ЕЗ1, 0$, ЕЗ, Е$, С. $$5:Е$Р указывает на стек размером 16 байт,
и его надо изменить, прежде чем снова разрешать прерывания
Точка входа УСРЬ АХ= ОБЕОСЕ: Переключиться в режим \86 (для вызова из РМ)
Вход: Перед передачей управления командой са! в стек надо поместить реги-
стры в следующем порядке (все значения— двойные слова): С5$, Е$, 0$,
ЕЗ, 55, ЕЗР, 0, С$, ЕТР. Прерывания должны быть запрещены
'Выход: Сегментные регистры загружаются, значение ЕАХ не определено, пре-
рывания запрещены
Остальные функции УСРГ.:
ГМТ 67 АХ = ООЕО2#: Определить максимальный физический адрес
Вход: АХ= 00ЕО02Ь
Выход: АН = 5, если нет ошибок
ЕОХ= физический адрес самой старшей 4- килобайтной ‹
страницы, коб-
торую можно выделить
Т№Т 678 АХ= ОРЕОЗЕ: Определить число свободных страниц
Вход: АХ= ОРЕОЗЬ
Выход: АН= 0, если нет ощибок .
.- ЕШХ = число свободных 4-килобайтных страниц для всех задач
Интерфейс УСР | 1333
МТ 678 АХ = ОБЕО4Й: Выделить 4-килобайтную страницу (обязательно надо выз-
вать РЕО5Ъ)
Вход: АХ= ОРЕОАЬ
Выход: АН= 0, если негошибок |
ЕОХ= физический адрес выделенной страницы
ТМТ 67 АХ - ОБЕОБЕ: Освободить 4-`килобайтную страницу
Вход: АХ= ОРЕО5Ь
ЕБХ= физический адреб страницы
Выход: АН= 0, если нет ошибок

Г№Т 672 АХ- ОБЕОбР: Определить физический адрес 4-килобайтной страницы


в первом мегабайте
Вход: АХ= ООЕОбЬ
СХ = линейный адрес страницы, сдвинутый вправо на 12 бит
Выход: АН= 0, если нет ошибок ^
ЕМОХ= физический адрес страницы
ТМТ 67} АХ = ОРЕЙ?7й: Прочитать регистр СКО
Вход: АХ = 00Е07Ь
Выход: АН = 0, если нет ошибок
ЕВХ = содержимое регистра СКО
Т№Т 67 АХ= ОРЕОВ#: Прочитать регистры око - ОКВ?
Вход: АХ = ОРЕОЗЬ
ЕЗ:ОТ1 = буфер на 8 двойных слов
Выход: АН= 0, если нет ошибок, в буфер не записываются ОЕ4 и ОВ5
ТМ№Т 674 АХ= ОРЕОФН: Записать регистры 250- 2В7
Вход: АХ= 0ОЕОЭЬ
ЕЗОГ -= буфер на 8 двойных слов с новыми значениями для регистров
`Выход: АН= 0, если нет ошибок (ОКА и ОВ5 не записываются)
ГУТ.67Р АХ= ОРЕОАЕ: Определить отображение аппаратных прерываний
Вход: АХ= ООЕОАВ
Выход: АН= 0, если нет ошибок .
ВХ = номер обработчика для 100
СХ = номер обработчика для КОВ:
ТМТ 678 АХ = ОРЕОВИ; Сообщить УСР1-серверу новое отображение аппаратных
прерываний (вызывается после перепрограммирования контроллера прерываний)
Вход: АХ = ОРЕОВЬ
ВХ= номер обработчика для 1ВО0
СХ- номер обработчика для [КОЗ
Выход: АН= 0, если нет ошибок
Итак, чтобы использовать защищенный режим с УСРТ, фактически надо уметь
программировать его самостоятельно. Например, чтобы вызвать прерывание ВО5
394 Программирование в РМ _
или ВТО$, нам пришлось бы переключаться в режим У86, вызывать прерывание
и затем возвращаться обратно. Естественно, этот интерфейс не получил широко-
го развития и был практически повсеместно вытеснен более удобным ОРМЕ:

6.3. Интерфейс ОРМ!


Спецификация ОРМГ создана в 1990-1991 годах и представляет собой разви- :
тую систему сервисов, позволяющих программам переключаться в защищенный"
режим, вызывать обработчики прерываний В1О$ и 2О$5, передавать управление
другим процедурам, работающим в реальном режиме, устанавливать обработчики
аппаратных и программных прерываний и исключений, работать с памятью с раз-
деляемым доступом, устанавливать точки останова и т. д. Операционные системы,
такие как \Лп4о\з 95 или [4пих, предоставляют ОРМТ-интерфейс для программ,
запускаемых в РО5-задачах. Многочисленные расширители 2О$, о которых го-
ворится в следующем разделе, поддерживают ОРМГ для РО$-программ, запус-
каемых в любых условиях, так что сейчас можно считать ОРМГ основным интер-
фейсом, на который следует ориентироваться при программировании 32-битных
приложений для ОО$. о

6.3.1. Переключение в защищенный режим


Все основные сервисы ОРМГ доступны только в защищенном режиме через
прерывание ГМТ 31%, следовательно, переключение режимов — первое, что. долж-
на сделать программа.
ГУТ 2Е} АХ = 16871: Функция РМ. получить точку входа в защищенный режим
Вход: АХ = 16876
Выход: АХ= 0, если ОРМ! присутствует ‘л
ВХ: бит 0 = 1, если поддерживаются 32-битные программы; 0, если нет
СГ: тип процессора (02- 80286, 03- 80386 ит. д.)
ОН:ОУ. - версия ОРМГ в двоичном виде (обычно 00:90 (00: ЗАВ) и.
или
01:00)
$Е = размер временной области данных, требуемой для переключения
в 16-байтных параграфах
ЕЗ:1 = адрес процедуры переключения в защищенный режим _
Вызвав эту функцию, программа должна выделить область памяти размером
5Гх16 байт и выполнить дальний САГЛТ. на указанный адрес. Единственные вход-
ные параметры-— регистр Е, который содержит сегментный адрес области дан-
ных для ОРМГи бит 0 регистра АХ. Если этот бит 1 - программа собирается стать
32-битным приложением, а если 0 - 16-битным. Если по возвращении из проце-
дуры установлен флаг СЕ переключения не произошло и программа все еще вре-
альном режиме. Если СЕ = 0, программа переключилась в защищенный режим
и в сегментные регистры загружены следующие селекторы:
С$: 16-битный селектор с базой, совпадающей со старым С$, и лимитом 64 Кб
05: селектор с базой, совпадающей со старым 05, и лимитом 64 Кб:
Интерфейс ОРМ!: — МОЕТ
$$: селектор с базой, совпадающей со старым $$, и.лимитом 64 Кб
ЕЗ: селектор с базой, совпадающей с началом блока РУР, и лимитом 1008 --
Еби 65=0° _ |
Разрядность сегментов данных определяется заявленной разрядностью про-
граммы. Остальные регистры сохраняются, а для'32-битных программ старшее
слово Е$ЗР обнуляется. По адресу Е5:[002СВ] записывается селектор сегмента,
содержащего переменные окружения 2О$. =
После того как произошло переключение, можно загрузить собственные деск-
рипторы для сегментов кода и данных и перейти в режим с моделью памяти Йа&.
- Перечислим теперь основные функции, предоставляемые ОРМГ для рабогы
с дескрипторами и селекторами. |

6.3.2. Функции ОРМ! управления дескрипторами


Т№Т 314, АХ= 0: Выделить локальные дескрипторы
Вход: АХ =0
СХ= количество необходимых дескрипторов
Выход: если СЕ = 0, АХ = селектор для первого из заказанных дескрипторов
‚Эта функция только выделяет место в таблице Г.ОТ, создавая в ней дескриптор
сегмента данных с нулевыми базой и лимитом, так что пользоваться им пока нельзя.
Т№Т 311, АХ = 1: Удалить локальный дескриптор
Вход: АХ = 1
ВХ = селектор
Выход: СЕ= 0, если не было ошибки
Эта функция влияет на дескрипторы, созданные функцией 0, и при перскл! ю-
чений в защищенный режим, но не на дескрипторы, созданные функцией 2.
Т№Т ЗЛЁЬ, АХ= 2: Преобразовать сегмент в дескриптор |
Вход: АХ =2
ВХ = сегментный адрес (0А000\— для видеопамяти, оодоь — для дан-
ных В05$)
Выход: если СЕ== 0, АХ = готовый селектор на сегмент, начинающийся с ука-
занного адреса, и с лимитом 64 Кб
Так программы в защищенном режиме могут обращаться к различным облас-
тям памяти ниже границы 1 Мб, например для прямого вывода на экран.
Т№Т З1ЁЬ, АХ= 6: Определить базу сегмента
Вход: АХ =б6
ВХ - селектор
Выход: если СЕ= 0, СХ:ОХ = 32-битный линейный адрес начала сегмента
1МТ 311; АХ - 7: Сменить базу сегмента
Вход: АХ =7
ВХ = селектор
СХ:.ОХ = 32-битная база
Выход: СЕ = 0, если не было ошибок
ЕСО ООН ИИ Программирование в РМ
1№Т З1А, АХ = 8; Сменить лимит сегмента
Вход: АХ =8
ВХ = селектор
СХ.ОХ -32-битный лимит (длина сегмента минус 1)
Выход: СЕ= 0, если не было ошибок
(чтобы определить лимит сегмента, можно пользоваться командой $1.)
6/№Т 31й, АХ= 9: Сменить права доступа сегмента
Вход: АХ =9
ВХ = селектор
и: СТ.= права Доступа/ тип (биты. 15-8 слова 2 дескриптора)
СН= дополнительные права (биты 7-4 соответствуют битам 7-4 сло-
ва 3 дескриптора, биты 3-0. игнорируются) _
Выход: СЕ = 0,‚если не было ошибок
(чтобы определить права доступа сегмента, можно пользоваться командой Г.АВ)
ГМТ З1В, АХ= ДАЙ: Создать копию дескриптора
Вход: АХ= 000АБ
° ВХ = селектор (сегмента кода или данных)
Выход: если СЕ= 0, АХ-= селектор на сегмент данных с теми же базой и лимитом
Г№Т 311, АХ =ВА: Прочитать дескриптор
Вход: АХ = 000ВЬ
ВХ = селектор
ЕЗЕТЛ = селектор:смещение 8-байтного буфера
Выход: если СЕ = 0, в буфер помещен дескриптор.
Т№Т 311, АХ= 0СВ: Загрузить дескриптор
Вход: АХ= 000СВ
ВХ = селектор
ЕЗ;ЕРЛ = адрес 8-байтного дескриптора
Выход: СЁ= 0, если не было ошибок
ТМТ ЗЛА, АХ = ООЁ: Выделить определенный дескриптор
Вход: АХ= 0000
‚ ВХ = селектор на один из первых 16 дескрипторов
(значения селектора 048— 7СВ)
Выход: СЕ= 0, если нет ошибок (СЕ = 1иАХ= 80116, если этот дескриптор
занят) о
Данного набора функций, а точнее пары функций 00 и ОСЬ, достаточно для
того, чтобы полностью настроить режим Йа (или любой другой) после переклю-
чения в защищенный режим. Но прежде чем это осуществить, нам надо познако-
миться с тем, как в ОМР] сделан вызов обработчиков прерываний реального ре-
жима, иначе наша программа просто не сможет себя проявить.
6.3.3. Передача управления между режимами в ОРМ! .
Вызов любого программного прерывания, кроме 1МТ 316 и МТ 21В/АН = 4СЬ
(функция ОРМГ: завершение программы), приводит к тому, что ОРМ]-сервер
Интерфейс ОРМ! = — 857
переключается в`режим \86 и передает управление обработчику этого же преры-
вания, скопировав все регистры, кроме сегментных регистров и стека (состояние
сегментных регистров не определено, а стек предоставляет сам ОРМ[-сервер).
После того как обработчик. прерывания возобновит управление, ОРМТ-сервер
возвратиться в защищенный режим и вернет управление программе. Таким спо-
собом можно вызывать все прерывания, передающие параметры только в.регист-
рах, например проверку нажатия клавиши или вывод символа на экран. Чтобы
вызвать прерывание, использующее сегментные регистры, например вывод стро-
ки на экран, а также в других ситуациях, когда требуется обращение к процедуре,
работающей в другом режиме, применяются следующие функции.
Т№Т З1В, АХ= 03001: Вызов прерывания. в реальном режиме
Вход: АХ= 03006
ВН= 0, В1.=номер прерывания
СХ= число слов из стека защищенного режима, которое будет скопи-
рована в стек реального режима-и обратно
ЕЗ: ЕЁ] - селектор:смещение структуры регистров86_гебз (см. ниже) |
Выход: если СЕ= 0, структура в. Е5:ЕГТ модифицируется
Значения регистров.С$ и [Р’в.структуре у86_герз игнорируются. Вызываемый
обработчик прерывания должен восстанавливать стек В исходное состояние (на-

пример, МТ 258 и [МТ 26$ этого не делают).


МТ З1р, АХ= 03011: Вызов дальней процедуры в реальном режиме
Вход: АХ= 03018
ВН=0 |
СХ= число слов из стека защищенного режима, которое будет скопи-
ровано в стек реального режима и обратно _
ЕЗ:ЕП] = селектор:смещение структуры регистров У86_геБз (см. ниже)
Выход: если СЕ= 0, структура в Е: ЕО] модифицируется
Вызываемая процедура должна заканчиваться командой КЕТЕ
МТ З1В, АХ= 03021: Вызов обработчика прерывания В реальном режиме
Вход: АХ= 0302.
ВН=0 .
СХ- число слов из стека защищенного режима, которое будет скопи-
ровано в стек реального режима и. обратно |
Е$:ЕП! = селектор:смещение структуры регистров 86 _гевз (см. ниже)
Выход: если СЕ- 0, структура в ЕЗ:ЕР! модифицируется
` Вызываемая. процедура должна заканчиваться командой ВЕТ.
..Эти три функции используют следующую структуру данных для передачи
значений регистров-в реальный режим и обратно:
+001: 4 байта — ЕБТ
+045: 4 байта — ЕЗ1Т ...
+08Ъ: 4 байта: ВВРЫ | Бе Зои
и +0СВ: 4 байта — игнорируются р А
- +10Ъ: 4 байта —ЕВХ..
нии Программирование в РМ лат
ма
Ази
а

+146; 4 байта ЕБХ


+185: 4 байта - ЕСХ
+1СВ: 4 байта - ЕАХ
+20Ъ: 2 байта - ЕГАС$
+225: 2 байта - Ез
+245: 2 байта — 0$
+26Б: 2 байта — Е$
+285: 2 байта —- С$
+2 АБ: 2 байта - 1Р
+2СВ: 2 байта — С$
+2ЕБ: 2 байта — ЗР
+305: 2 байта - $$
Значения 5$ и $Р могут быть нулевыми, тогда ОРМ1-сервер сам предоставит
_ стек для работы прерывания.
Кроме указанных функций, которые передают управление процедурам в реаль-
ном режиме из защищенного, существует механизм, позволяющий делать в точно-
сти обратное действие - передавать управление процедурам В защищенном режи-
ме из реального.

МТ З1Ь, АХ=03031: Выделить точку входа для вызова из реального режима


Вход: АХ= 0303
05$:Е$1= селектор:смещение процедуры в защищенном режиме (закан- `
чивающейся 1КЕТ), которую будут вызывать из реального
ЕЗ:;ЕБТ = селектор:смещение структуры у86_гевз, которая будет ис-
пользоваться для передачи регистров
Выход: если СЕ= 0, СХ:ОХ = сегмент:смещение точки входа
При передаче управления в такую процедуру 0О$:Е $1 указывает на стек реаль-
ного режима, ЕЗ:ЕОТ - на структуру у86_гезз, 55:Е$Р — на стек, предоставлен-
‚ный ОРМГ-сервером, и остальные регистры не определены.
Количество точек входа, которыми располагает ОРМТ-сервер, ограничено, и не-
используемые точки входа должны быть удалены при помощи следующей функ- :
ции ОРМ1.

ТУТ ЗЛА, АХ = 03048: Освободить точку входа для вызова из реального режима
Вход: АХ = 03046
СХ:ОХ = сегментсмещение точки входа
Выход; СЕ = 0, если точка входа удалена

. 6.3.4. Обработчики прерываний


Прежде чем мы рассмотрим первый пример программы, использующей БРМУ,
остановимся еще на одной группе его функций— операции с обработчиками пре-
рываний. Когда происходит прерывание или исключение, управление передается
сначала по цепочке обработчиков прерываний в защищенном режиме, последний
Интерфейс ОРМ! < | 399

управление
обработчик - стандартный ОРМГ - переходит в режим \86, а затем
прерыва ния в реально м режиме (обрабо тчи-
проходит по цепочке обработчиков
ки прерываний и исключений в реально м режиме совпада ют).

1М№Т 314, АХ - 02008: Определить адрес реального обработчика прерывания


_ Вход: АХ = 0200. `. | |
ВГ.= номер прерывания . ,
. <
Выход: СЕ = 0 всегда, СХ:ОХ - сегмент:смещен ие обработ чика прерывания
в реальном режиме
МТ З1А, АХ - 02011: Установить реальный обработчик прерывания
Вход: АХ = 02018 -
ВГ. = номер прерывания
СХЬОХ - сегмент:смещение обработчика прерывания в реальном режиме
Выход: СЕ = 0 всегда - в
ния |
МТ З1Ь, АХ - 02048: Определить адрес защищенного обработчика прерыва
Вход: АХ = 0204Ъ - | . |
ВТ. = номер прерывания ,
Выход: СЕ = 0 всегда, СХ:ЕОХ = селектор:смещение обработчика
[МТ 311, АХ - 02058: Установить защищенный обработчик прерывания
Вход: АХ = 02058 |
В1. - номер прерыва ния
СХ:ЕБХ - селектор:смещение обработчика
Выход: СЕ = 0
[МТ З1В, АХ = 02028: Определить адрес обработчика исключения |
Вход: АХ = 0202.
_ ВЕ. = номер исключения (00 - 1ЕВ)
ния
Выход: если СЕ = 0, СХ:ЕОХ = селектор:смещение обработчика исключе
1М№Т З1А, АХ - 02031: Установить обработчик исключения
Вход: АХ = 02035 о ,
ВТ. = номер исключения (008 - 12) = _
СХ:ЕЩХ - селектор:смещение обработчика исключения
Выход: СЕ = 0; если не было ошибок
стан-
Если обработчик исключения передает управление дальше по цепочке на
исключе ния 0,
дартный обработчик ОРМ1-сервера, следует помнить, что только
а остальны е ис-
1,2, 3, 4, 5 и 7 передаются обработчикам из ‘реального режима,
ключения приводят к прекращению работы программы. о

6.3.5. Пример программы `` и


нный
Теперь воспользуемся интерфейсом ОРМГ для переключения в защище
будет работат ь только в систе-
‘режим и вывода строки на экран. Этот пример
например
‘мах, предоставляющих ОРМЕ для запускаемыхв них ОО$-программ,
в УЛпдо\з 95. 5. | вв
ТЕ Программирование в РМ
; Чритех. азт” .
‚; Выполняет переключение в защищенный режим средствами ОРМТ.
; При компиляции с помощью МАЗМ необходима опция /0О_МАЗМ..
.386 : 32-битный защищенный режим появился в 80386.

; 16=-битный сегмент - в нем выполняется подготовка и переход в защищенный режим.


АМ_зе9 . зедтепт буте руБ11с. и$е16
аззите с3:ВМ_$е9, .4$:РМ_зе9, $3:ВМ_зтаск

; Точка входа программы.


АМ_ептгу:
‚; Проверить наличие ОРМТ.`
ту = ах, 16871 ‚ Номер 16781.`
11% 2ЕВ ; Прерывание мультиплексора.
тезт ах, ах ‚ Если АХ не ноль,
р 474 ОРМТ_еггог. . ; произошла ошибка (ОРМТ отсутствует).
тезт Ь1, 1 ; Если не поддерживается 32-битный режим,
ру ОРМТ_еггог ; Нам тоже нечего делать.

: Подготовить базовые адреса для будущих дескрипторов.


оу вах, РМ_зе9 .
пом 4$, ах ; 05 - сегментный адрес’РМ_зе9.
$1] « еах,4 ; ЕАХ - линейный адрес начала сегмента РМ_зе9.
по\ Чиогф руг РМ_зед_аЧдг,
еах |
ог Чиогд ртг бОТ_11а16$+2,
еах ‚ Дескриптор для 0$.
ог Чмога ртг бОТ_#1а10$+2,
еах : Дескриптор для’ 0$.

; Сохранить адрес процедуры переключения ОРМТ.


том _ мог@ рфг ОРМГ Модезм1сн, 91
пом мога ртг ОРМТ_Модебм11сй+2,ез
; Е$ должен указывать на область данных для переключения режимов.
. У нас она будет совпадать с’ началом будущего 32-битного стека.
ада вах, оЕРзет’ ОРМГ дата ; Добавить к ЕАХ смещение
ПГ еах, 4 ‚ И превратить в сегментный адрес.
1пс ах .
моу ез, ах

: Перейти в защищенный режим. =


поу ах, 1 °; АХ = т - мы будем 32-м. приложением.
+ Таег _МАЗМ_ , _
95 671 ; Поправка для мазм.
епд1 Е ,
са11 9мог@ рег ОРМГ_Моде$и
(си
15 ОРМТ_еггог ‚; Если переключения не произошло - выйти.

‚ Теперь мы находимся в защищенном режиме, но лимиты всех сегментов.


‚ установлены на 64 Кб, а разрядности. ‘сегментов - на 16 бит.
; Нам надо подготовить два .32-битных селектора с лимитом 4 Гб -
; один для кода и один для данных. | | |

ризН 9$ ни и
рор ез ; Еб’вообще был сегментом РЗР.с. лимитом. 1001.
моу е31; оЕР5ет бОТ ; ЕбГ - адрес таблицы: 60Т.
; Цикл по всем дескрипторам в навей СОТ,
0: У едх, 1 5: ‚ которых всего два (0, 1).
зе] 1оор: , |
хог ‚ах. ах. | ; Функция ОРМТ 00:
_ ОУ сх, 1 о
17 З1В | : Создать локальный дескриптор.
оу мог4 ртг зе]естог[евх»2],ах °”, Сохранить селектор
му Ьх, ах. ; в таблице зе1естогз.
поу ах, 000СИ ; Функция ОРМТ ОСН.
116. З1В | ° `` Установить селектор.`
209 91,8 ; ЕБТ -.следующий дескриптор.
дес 9х | .
913 5е1 1оор
| -* и

; Загрузить селектор сегмента кода В 0$ при помощи команды ВЕТЕ..


ризп @мога рАг 3е1_ #18163 ; Селектор для 6$.
14еР _МАЗМ_ | | |
6 0668
еп! | |
: ризй оЁРзет РМептгу ; ЕТР
| „96 066 . . ;. Префикс размера операнда.
гес+ - ; Выполнить переход: в 32-битный сегмент.

'; Сюда передается управление, если произошла ошибка при’ инициализации ОРМТ
‚ (обычно, если ОРМТ просто 'нет).
ОРМТ_еггог:
ризп с3 О
рор 95° |
мо 9х,
о зе порт! -т$9 ВИ
моу ав,ЭП 2... : Вывод строки на экран.
м 2 ' ..
мо ` ай, 4СА : „; Конец ЕХЕ-программы.
1 Ра :
побрт1 _тз9 96 &— “Ошибка ОРМТ$”
ВМ_5е9 еп |

; Сегмент РМ_5е9 содержит код, данные и стек для защищенного режима.


ВМ 5е9 `зедтепе Буфе руб11с. о изе32 ‘ г.
аззиве 93:РМ_3е9, ед,
с$:РМ_5 $3 :РМ_5е0`

‚ Таблица дескрипторов. - -*
вот ]аъе1 Буте
; Дескриптор для 65. |
бОТ_11атС$ 5 _ ОЕЕи, ОРЕВ, ОН;ОН, О, ОЕАВ, ОСЕН, ОН
; Дескриптор для 0$.:_ г.
ОТ_#1а10$ [°]9) ОРЕВ, ОРЕА ‚ОН, ОВ, Он, ОЕ2И, ОСРА, ОВ

; Точка входа в 32-битный режим - загружен только С5.


РМ_ептгу: 7
ое ах; мог руг $е1_Р1ат0$ ; Селектор для данных
° ОУ 43, ах: ;-в-: 05,
Программирование в РМ
моу 3, ах‘ ; в Е
моу $$, ах р гив 3$.
тоУ езр, оРРзет РМ_.зфаск_оостот ; И установить стек, |
. ЕЕ тает аира о тис сатисенананее

, Отсюда. начинается текст собственно программы.


; Программа работает в модели памяти. Раф с ненулевой базой,
; база 0$, 0$, ЕЗ и 55 совпадает и равна линейному адресу начала РМ_зед,
‚ все лимиты - 4 Гб.

Те ах, 03001 ; Функция ОРМТ 03001.


мо\ Ьх, 00211 ‚ Прерывание 00$ 218.
хог есх, есх ; Стек не копировать.
, Дед е41 ‚оЕЕзет 86 _гедз ; ЕЗ:ЕОТ - адрес %86_гедз.
11 З1В ‚ Вызвать прерывание.

моу ап, 4Сл ; Это единственный способ


111 218 ; правильно завершить ОРМТ-программу.

пе110_п39 95 “Не110 мог] из 32-битного защищенного режима!$"

У86_гедз: ; Значения регистров длЯ функции ОРМТ 03008.


94 0;0,0,0,0 ; ЕОГ, ЕЗТ, ЕВР, 0, ЕВХ
у_86_еах „99 оРРзет: Не110_тза ; ЕОХ
94 о. , ; ЕСХ .
\у86_еах ‘ 94 ‚ 09008 | ; ЕАХ (АН= 091, ВЫВОД строки на экран)
| м 0,0 ; РАбЗ, ЕЗ |
\86_@3 дм РМ вед °_ ; 05
9% — 0,0,0,0,0;0 ; 25, 65, 0, 0, $Р, 3$
: Различные временные переменные, нужные для переключения режимов.
ОРМТ_Модебу1 сн 94 ? ; Точка входа ОРМТ.
РМ_зед_аддг 99 ? ; Линейный адрес сегмента РМ_3е9.

; Значения селекторов.
зе1естогз:
5е1_#1а{05 Чи ? -
53е1_Е1а16$ _ Чи’. ? : ,

; Стек для нашей 32-битной программы


ОРМТ_дата: ; и временная область данных ОРМТ одновременно,
6 ‚16384 Чир (?).
РМ_зтаск_Ботфот:
РМ_зеб епдз } .

; Стек 16-битной программы, который использует ОРМ-сервер при -переключении режимов.


; №1пд0\$ 95 требует 16 байт, | .
; СМЗОРМТ требует 32 байта, ,
‚ ООРМТ требует 96 байт.
; Мы выберемпо максимуму. ..
АМ_этаск зедтелт Буте эТаск “зФасК” изе16.
ЧБ 96 Чир (?)
АМ_зфасК еп4$ и. В
епд АМ ептгу ; точка входа для 005 - ВМ_епсгу

И
Расширители 05.
Несмотря на то что ОРМЕ разрешает пользоваться многими прерываниями
напрямую и всеми через функцию 0300}, он все равно требует некоторой подго-
товки для переключения режимов. Кроме того; программа, работающая с ОРМ1
для переключения режимов, должна сочетать. в себе 16- и 32-битный сегменты,
что неудобно с точки зрения практического программирования. На самом деле
для написания приложений, идущих в защищенном режиме под РО$, никто не
применяет переключение режимов вообще- это делают специальные программы,
называющиеся расширителями ОО$.

6.4. Расширители 00$


Расширитель 005 (2О$ Ежепдег) - это средство разработки (программа, на-
бор программ, часть компоновщика или просто объектный файл, с которым нужно
компоновать свою программу), позволяющее создавать 32-битные приложения,
которые запускаются в защищенном режиме с моделью памяти Йаё и с работаю-
щими функциями РМТ. Расширитель сам выполняет переключение в защищен-
ный режим, причем, если ‘в системе уже присутствует ОРМТ, УСР! или другие
средства переключения в защищенный режим из.У86, он пользуется ими, а если
программа запускается в'настоящем реальном режиме, РО5$-расширитель пере-
водит процессор в защищенный режим и осуществляет все необходимые действия
для поддержания его работы. Кроме полного или частичного набора функций
ОРМЕ, расширител и обычно поддерживают некоторые функции прерыва-
2О$
ния 21Ъ, за что и получили свое название. В частности, практически всегда под-
держивается функция ОО$ 091 вывода строки на экран: в О5:ЕОХ помещают се-
лектор:смещение начала строки, и расширитель это. правильно интерпретирует
(многие ОРМТ-серверы, включая встроенный сервер \УЛп4о\з 95, тоже эмулиру-
ют данную функцию РО5).
Так как при старте программы расширитель должен первым получить управ-
ление, для выполнения переключения режимов его код нужно объединить с на-
шей программой на стадии компиляции или компоновки.

6.4.1. Способы объединения программы с расширителем


Первые популярные ОО5$-расширители, такие как 54аг432, Ва\32, ЗузетбА,
386Ро\мег, РМОПЕ и другие, распространялись в виде исходных текстов (542732
и РМОБЕ оказали решающее влияние на развитие ОО5-расширителей в целом).
Чтобы использовать такой расширитель, надо скомпилировать его любым ассем-
блером в объектный файл, который ‘необходимо скомпоновать вместе со своей
программой: В большинстве ‘случаев нужно назвать точку входа своей програм-
мы ша или _ таз и закончить модуль директивой еп4 без параметра, тогда РО5-
расширитель получит управление первым и передаст его на метку тай после того,
как будут настроены все сегменты для модели памяти На.
Самым популярным из профессиональных компиляторов, поддерживающих
расширители ОО$З, стал \Максот С/С++. Он использует модификацию коммер-
ческого РО$-расширителя РО$4С, названную 2О5/4С\УУ. Дело в том, что ком-
поновщик \НаК.ехе поддерживает, среди большого числа различных форматов
НН Программирование в РМ ьи
А

вывода, формат линейных исполняемых файлов ГЕ, применяющийся в опера-


ционной системе О5/2 (а также, с небольшими модификациями, для драйверов
в \п4о\5). Достаточно дописать файл в формате О$/2 Т.Е.в конец загрузчика
РО5$-расширителя, написанного соответствующим образом, чтобы потом его за-
пускать. Загрузчик расщирителя можно указать прямо в командной строке Нок
(командой ор за) или скопировать позже. В комплект поставки расширителей
часто входит специальная утилита, которая заменяет загрузчик, находящийся
в начале такой программы, своим.
Чтобы скомпилировать, например, программу Шйге.азт, которую мы рассмот-
рим далее, нужно воспользоваться следующими командами:
Компиляция: :
`мазт 161 ге. азт
Компоновка с рО5/4С\ (стандартный расширитель, распространяемый с У’а(-
сош С):
“Ник 111е 1751ге.06] Роги 032 1е-ор зТибтивиь.ехе
Компоновка с РМОРЕ/У (самый популярный из бесплатных расширителей)
Чик ‘1116 1е5е1Ее. `оБ} отт 082 1е’ ор $+иБ=ртодем. ехе

Компоновка с ВОХ (более строгий с точки зрения реализации):


и11пк Е11е ТРБЕге.о6] Тогт 0$2 1$ ор’ зТиб=ггах. ехе

Компоновка с \РО$Х (самый универсальный расширитель):


мИ лк. 11]е 1тЬаге. о} Тогт 0$2 1е ор зфиб=иФозх1е.ехе

И так далее,
К сожалению, формат исполняемых файлов 2О$ (так называемый формат
М2), вкотором по умолчанию создают программы другие компиляторы, очень не-
удобен для объединения с расширителями, ‘хотя универсальный расширитель
У/РО$Х способен обработать и такой файл, и даже просто файл с`32-битным
кодом без всяких заголовков (какой можно получить, создав СОМ-файл с дирек-
тивой оге 0), и файл в формате РЕ (см. главу 7), правда, не во всех случаях такие
1
программы будут работать успешно.
И наконец, третий подход к объединению расширителя и программы можно
видеть на примере 20532, ‚ куда входит программа ЧЙпК.ехе, являющаяся компо-
новщиком, который вполне подойдет вместо ок, (Чаю или ИК, чтобы получить
исполняемый файл, работающий с этим расширителем. |
Тем не менее популярность подхода; используемого в. \’а ош, настолько вы-
‘сока, что подавляющее большинство программ, применяющий идею расширите-
лей 205, написано именно на \/а(сот1 С или на ассемблере для \МА$М.
Прежде чем мы сможем написать обещанный в разделе 4.5.2 пример програм-
мы, работающей с линейным кадровым буфером ЗУСА, познакомимся еще с дву-
мя группами функций ОРМЕ которые нам потребуются. “1 .
Расширители 20$.
- 6.4.2. Управление памятью‘ в: ОРМИ
МТ З1В, АХ= 01001: Выделить память ниже- аницыРМб- и
Вход: ` АХ= 01008 ` к"
ВХ- требуемый размер в 16- байтних параграфах
-Выход: если СЕ= 0,
”. АХ сегментный адрес выделенного. блока для использования в реаль-
ном режиме;
ОХ- селектор выделенного блока для применения в защищенном ре-
‚ жиме
Обработчик этой функции выходит в 86 и вызывает функцию 2О$ 48. для
выделения области памяти, которую потом можно использовать. для передачи
данных между нашей программой и обработчиками прерываний, возвращающи-
ми структуры данных в памяти.
ТМТ З1В, АХ = ОЧОЧВ: Освободить память ниже границы 1 Мб
Вход: АХ= 01026
ОХ= селектор свобождаемого блока
Выход: СЕ= 0, если не было ошибок
Т№Т З1Е, АХ = 01025: Изменить размер блока, выделенного функцией 01008
Вход: АХ= 01026
ВХ - новый размер блока в 16-байтных параграфах
ОХ - селектор модифицируемого блока _
Выход: СЕ= 0, если не было ошибок
МТ З1В, АХ = 0500: Получить информацию -о свободной памяти
Вход: АХ= 0500.
ЕЗ:ЕБ- адрес 48-байтного буфера
Выход: СЁ= 0 всегда, буфер заполняётся следующей структурой данных:
+00Ъ: 4 байта — максимальный доступный блок в байтах |
+041: 4 байта- число доступных нефиксированных страниц ;
+08Ъ: 4 байта— число доступных фиксированных страниц
+0СЪ: 4 байта—- линейный размер адресного пространства в страницах. |
+10Ъ: 4 байта— общее число нефиксированных страниц .
+14Ъ: 4 байта — общее число свободных страниц
+18}: 4 байта — общее число физических страниц
+1СЬ: 4 байта— свободное место в линейном адресном пространбтве
+20Ъ: 4 байта — - размер зуар- файла или раздела в страницах
+24В: ОСЬ байт- все байты равны ЕЕЬ
ТМТ З1Ё, АХ- 05018: Выделить блок памяти
Вход: АХ= 05016
ВХ:СХ= размер блока в байтах, больше > нуля
. Выход: если СЕ= 0,
ВХ:СХ = линейный адрес блока; .
Е Пт = идентификатор блока для функций 0502 и 0503
406 1111] Программирование в РМ
“ИМТ 31, АХ = 05028: Освободить блок памяти
Вход: АХ = 05026
51:01 = идентификатор блока
Выход: СЕ = 0, если не было ошибки
Т№Т З1Ё, АХ - 05038; Изменить размер блока памяти
Вход: АХ = 0503
ВХ:СХ = новый размерв байтах
ЗЕОГ = идентификатор блока
Выход: если СЕ = 0, |
ВХ:СХ = новый линейный адрес блока;
ГОТ = новый идентификатор |
Нам потребуются еще две функции ОРМГ для работы с устройством, которое
отображает свою память в физическое пространство адресов. |
ТМТ З1Ь, АХ= 0800}: Отобразить физический адрес выше границы 1 Мб на ли-
нейный
Вход: ВХ:СХ = физический адрес
ЗЕОТ = размер области в.байтах
Выход: если-СЕЁ= 0, ВХ:СХ`= линейный адрес, который можно использовать
ба
ба
о
ав
для доступа к этой памяти
ГУТ 31}, АХ= 0801#: Отменить отображение; выполненное функцией 08005
Вход: АХ= 08016
ВХ:СХ= линейный адрес, возвращенный функцией 0800ь
Выход: СЕ= 0, если не было ошибок с’ок
ашьы
ва
льад

6.4.3. Вывод на экран через линейный кадровый буфер


; 1ТЬР1ге. аэт
; Программа, работающая с ЗУСА при помощи линейного кадрового буфера (+В).
‚; Демонстрирует стандартный алгоритм генерации пламени. ,
; Требуется поддержка (ЕВ видеоплатой (или загруженный эмулятор ип1уе),
и
; для компиляции необходим 00$5-расширитель.

; 486р ; Для команды. хадд.


.тоде].. Гат ; Основная модель памяти
| ; в защищенном, режиме.
.соде №
аззите 15: Поти 19 ; Нужно только для МАЗМ.
_зФагт:
Этр ЗНогт _па1п
4 — "МАТСОН" : Нужно только для 008/46. .
; Начало программы. п |
; На входе обычно (0$, 05$ и $$ указывают на один и тот же сегмент с лимитом 4 Гб,
‚ ЕЗ указывает на сегмент с РЗР на 100н байт, остальные регистры ме определены.
Расширители 20$:
_мафп: , | , |
$11 `; Даже флаг прерываний не определен, ,
с19 . | ; не говоря уже о флаге направления.

по\ ах,01001 ; Функция ОРИТ 01001.


му Ьх, 1000 ; Размер в. 16-байтных параграфах.
1 ЗИ о . : Выделить ‘блок памяти ниже 1 №.
с ОРМТ_еггог |
оу +3, 9х ; ®- селектор для выделенного блока.

; Получить блок общей информации о. УВЕ 2.0 (см. раздел 4.5.2).


оу Чиогд’ руг 1№$:[0],'2ЕВ\’ ; Сигнатура УВЕ? в Начало блока;
мо\ мог ртг \%86_еах, 4ЕббН. =; Функция УВЕ ООП.
тому мог рфг у86_е$,ах ; Сегмент, выделенный .ОРМТ:
оу ах, 03001 ; Функция ОРМТ 3001.
моу 6х, 00101 р _. ; Эмуляция. прерывания 101.
хог есх, есх | г
< МОУ ед1, отТэет у86_гедз.,
ризй 4$
рор ез у ‚ ЕЗ:ЕОТ - структура %86_гедз.
101 З1В „. общую ‘информацию
; Получить УВЕ2.
< — ОРМГеггог и 7
’ стр Буте ртг .у86_еах, ДЕР. ь Проверка ‘поддержки \ВЕ.. `
Зте \УВЕ_еггог . :

моУ2х ебр,мога рег 1$:[18] ; Объем 5МбА-памяти в ЕВР !


$1] ебр, 6 ` _; в килобайтах. |
; Получить информацию о.видеорежиме 1018.
Се могФ рёг у86_еах, 4Р01В ТМТ 108.
; Номер функции.
том мог рег \У86_есх, 1011 ‚ Режим 1011 - 640х480х256.
` п р ; _; Е5:ЕБТ -. те же. самые. _
тоу ах, 03001 ; Функция ОРМТ 3001 - эмуляция
оу ьх, 00108 т ; прерывания ТМТ 101.
хог есх, есх |
1м З1А ; Получить данные о режиме.
с ОРМТ_еггог | |
стр Буфе рег у86_. еах, ЕВ.
пе УВЕ _еггог
тезт Буте руг 13:[0}, во. . Бит 7 байта атрибутов = 1 < ЕВ есть.
32 КЕВ_еггог |

; Построение дескриптора
-сегмента, описывающего ЕЕВ,
; Лимит. -
том еах, евр . ; Видеопамять в килобайтах.
$11 вах,10° | ; Теперь в байтах.
дес еах ; Лимит = размер: - 1.
эАг еах, 12 ; Лимит в 4-килобайтных единицах.
моу мог руг \14е09$с+0,ах ‚ Записать биты 15-0 лимита
$ИАГ еах, 8. :
апд ай, ОЕН. -
"ЕН Программирование ® РМ
ог Буте ртг у19е043с+6,ав ; и биты 19-16 лимита. |
оу еах, евр ; Видеопамять ‘в килобайтах,
$11 еах, 10 . , ‚ В байтах. И
моу едх, амога рфг 1$:[40] ; Физический адрес (ЕВ.
моу сх,ах
$114 ебх, едх, 16 ‚; Поместить его в СХ:0Х,
МОУ 91, ах
$114 е31, еах, 16 ‚ а размер -- в 5Т:0Т
оу ах, 8008 ‚ И вызвать функцию ОРМТ 08008:. ,
11 ЗАВ | ; Отобразить физический. адрес в линейный.
с ОРМТ _еггог ,
эВга еах, еБх, 16 ; Перенести полученный линейный адрес
оу Чх, сх ‚ из В5:СХ в ЕБХ
оу мог рег \19е04$с+2,дх ; и записать биты 15-0 базы, }
Аг едх, 16 | т.
МОУ уфе рег у19е04$с+4,41 —; биты 23-16
по\ °Буте рАг у19е04$6+7,9 ;ои биты 31-24.
; Права. .1
’ оу ох, сз
]аг сх, 6х ; Прочитать права нашего сегмента
апд сх, 60008 ; и перенести биты ОР |
ог Буте ртг у19е09$с+5,сп ; в строящийся дескриптор.

; Поместить наш дескриптор в ЁЕОТ и получить селектор.


ту сх, 1 ` ; Получить один новый дескриптор, й
том ах, 0 ру ОРЫГ.
1 о ЗВ
< `ОРМТ_етгог ”
том могд ртг у1деозе],ах ` ; Записать его селектор. -
ризН 95
рор ез
тпоу е91, оРЕзет м14е049$с. ; ЕЗ;ЕОТ - адрес нашего дескриптора.
тому ох, ах. В . ; ВХ - выданный нам селектор.
тоу ах, осн ; Функция ОРМТ ОСВ:.
111 ЗАЛЕ ‚ Загрузить дескриптор в ЕТ.
3с ОРМТ_еггог | ; Теперь в \14еозе1 лежит селектор на (ЕВ.

; Переключение в режим 41018 (101н + ЕВ). .


тому мога рфг \86_еах, 42028 ‚ 4Е02в - установить ЗМбА-режим.
мо мог рфг у86_еБх, 41011 ; Режим 41011 = 10148 + (ЕВ.
оу е91, оГРзет м86_гедз ; ЕЗ:ЕОТ - структура \86_гедз.
том ° ах, 03008 ‚ Функция ОРМТ 300.1. —
му рх, 00108 у ; Эмуляция прерывания 10.
хог есх, есх |
171 ЗВ

МОУ ах, мог рфтг у14еозе] °_; АХ - наш селектор.


ептег_Р1ате’: ; Сюда придет управление с селектором в АХ на А000н:0000,
‚ если произошла ошибка в любой УВЕ-функции.
‚ МОУ ез,ах ; Е - селектор видеопамяти или 1ЕВ.
Расширители 20$ .._ 203
; Отсюда начинается процедура. генерации пламени.

; Генерация палитры.
для ‘пламени. ` ‚.. . ,
ь хог е41, ед} ; Начать написание палитры с адреса Е$:0000.
хог есх, есх о, а | -`
ра1е{Те_деп:
хог ах, еах. : Цвета’ начинаются с. 0, 0, .0.
оу с1, 63 ; Число значений для одного компонента.
ра1етте 11“ у
ЗТозЬ ; Записать байт,
°фйс еах | ‚ увеличить компонент,
стрзи ; пропустить два байта,
1оор ра1ет{е_11 ‚ и так 64 раза.. ,

ризп = е91 |
то с1, 192`
ра1ете_12:
$т0$м . ; Записать два байта
1йс 91 ; и пропустить один,
1оор ра1е{Те_12 ; и так 192 раза (до конца палитры).
рор — ©е01 ; Восстановить ЕТ.
1пс 91 |
)п5 ра1етТе_деп

‚ Палитра сгенерирована, записать ее в регистры УСА БАС (см. раздел 5.10.4).


моу ‚а1,0 ; Начать с регистра 0.
моу 9х, озС8® ; Индексный регистр на запись.
ош 9х, а} .
ризИ е5 р
ризН 9$ ` ; Поменять’ местами ЕЗ и 09$.
рор е5 `
рор 93
хог е31, е31
мо есх, 256*3 ‚ Писать все 256 регистров.
оу едх, 03694 `. ° -; в порт данных МА ПАС.
гер ОитЗЬ ть
` ризв `ез :
‚ ри 98 | ; Поменять местами ЕЗ и 0$.
рор е5
рор 95
; Основной цикл - анимация. пламени, пока не ‘будет нажата любая клавиша.
хог = едх, едх и : Должен быть равен нулю.
оу ебр, 7777Н ” ``; Любое число. | р
оу есх; иог9 р&г`зсг м1 атН о ; Ширина экрана.
ма{п_1о0р:
ризй ез ``; Сохранить Еб.
рузп 0$ |
рор е$ . ; ЕЗ = 0$ - мы работаем только с буфером.
; Анимация пламени (классический алгоритм).
„Лис ` есх...
[4 а Пи! -
Программирование вРМ :
оу е91, оРРзет рыГТег
поу ебх, дога рёг зсг_пе19ит
ИГ ебх, 1
дес еБх
оу е31, зсг м1
ап1тате_Т1ате:
во\ ах, [е91+е$1*2-1] Вычислить среднее значение. цвета
ада а1,ап в данной точке (ЕСТ) из значений
зетс ап цвета в точке слева и на две строки
по\у 91, [е91+е31*2+1] вниз, справа и на две строки вниз
а94 ах,9х
поу _ 91, [е91+е$1*4] и на четыре строки вниз,
а99 ах,дх причем первое значение
$Аг ах,2 модифицировать.
7 а] геаду_тего Уменьшить яркость цвета,

дес ах
а]1геаду_2его:
$036 Записать новый цвет в буфер.
ад9 еах, едх
$Вг еах,1
поу руе р&г [е91+е$1-1],а1
1оор “ апзмахе_Р]аме
оу есх, ез1
а4 е91, есх
дес. ебх
912 ап1тафе_Г]ате

: Псевдослучайная полоска в низу экрана, которая служит генератором пламени.


депегатог_Баг:
| хада Бр,ах
310$м
$105
1оор депегатог_Баг

рор е5 Восстановить ЕЗ для вывода на экран.


` Вывод пламени на экран.
хог е91, е91 ЕЗ:ЕОТ - ЕВ.
рузв е$1 .
ада е$1, оРЁР5еф риРег 0$:ЕЗТ - буфер.
оу есх, Чиогд рАг зсг_$12е Размер буфера в двойных словах.
гер ее Скопировать буфер на экран.
рор е31

мому ай,1 Если не была нажата


171 160 никакая клавиша,
32 та1п_1оор. продолжить основной цикл.
оу ай,0 Иначе -
1 168 считать эту клавишу.

ех11_а]1:
Мом ах, ОЗВ Восстановить текстовый режим.
Расширители 205...
101
‚ах; 40008 ; =.40А —
218 ; од ИЗ - программы под расвирителем 00$.

; Различные обработчики ошибок.


ОРМТ_еггог: Ошибка при выполнении одной из ‚ функций ОРМТ.
‚ МОУ едх, оРЕзет ОРИТ:>еггбг$9
во\у ап,9
11 24и ; Вывести сообщение об ошибке
Лир эВогЕ ех1т. а ; и выйти.
УВЕ еггог: : Не поддерживается УВЕ.
мо\ едх, оРРзет УВЕ еггог_тз9
ап,9
1 21 ; Вывести сообщение 0б ошибке
тр зпог®. зтаге. м1 И_мда ‚ и использовать’ \бА.
ЕЕВ_етгог: ‚ Не поддерживается 1РВ.
| по ебх, оРЁзет (РВ_еггог_м$9
поу ав, 9 :; Вывести сообщение об ошибке.
1 Оли
зфаге_ мИП_уда:
моу ав,0 : Подождать нажатия любой клавиши.
168
ах, 131 ‚Переключиться в видеорежим 131,
108 ; 320х200х256. :
ах,2 ; Функция ОРМТ 00021:
Бх, ОА000В ; построить дескриптор для реального
ка ; сегмента.
Фиога рфг зсг_м1911,320 |; Установить параметры режима
Фиога рег $сг “петовт, 200
днога рег 5сг_в12е, 320*200/4
Зтр 6птег_Ё1ате ; и перейти к`пламени.

‚дата
‚ Различные сообщения об ошибках. _
УВЕ_еггог_т59 „@6 “Ошибка УВЕ 2.0“, 001, ‚ (АВ
|] “Будет использоваться режим \УбА 320200", ОО, ОАН, ' $’
ОРМТ_еггог_м$0 Ге]. “Ошибка ОРМТ$"
ЕЕВ_еггог_ 39 95 “ЕЕВ недоступен”, о0н, бАВ"
96 “Будет использоваться режим УбА 320х200“, ООВ, ОАВ, '$'
; Параметры видеорежима.
5сг_м19ЕА [9 640
эсг_Ве19ве 94 480
3сг_$17е 39 640*480/4
; Структура, используемая.
функцией ОРМТ 03001.
у86_гедз 1абе] Буфе
у86_е91 94
\86_е$1 [ее
У86_ебр 99
у86_гез 99
у86_ебх 94 ррозФеос
ВЫ ей
|...
Программирование в РМ :
у86_едх 39 0
\у86_есх 94 0
\86_еах . 94 0
У86_Р]а95 м 0 р

\86_е5 Ом 0
№86_05 - бы 0.
\86_Р5 9м 0
\86_0$ - @м 0
у86_1р м 0
\86_с$, Фи 0.
\86_5р ^ Чи 0
\86_$5 ом 0
; Дескриптор сегмента, соответствующего иг.
\1де0дс би 0 в Биты 15-0 лимита.
ре | 0. ‚Биты 15-0’ базы. .`
. |) .0 ‚ Биты 16-23 базы. баа
а
лав
ль
ащ
олл
асеа

„о |] 460100106. ‹ Доступ. ^^
. _ 96 10000000 ° ; Биты 16-19 лимита и другие биты.
6 .0 ; Биты 24-31 базы. , |
; Селектор сегмента, описывающего РВ.
\19е03е1 ди 0 Г :
„Чата?“
; Буфер для экрана: .
‚ БуРег [е]°) 640*483. 9ир{?)
: стек. С
‚ЗТаско 10008
епа _зтаге. ^

Программирование с ОО$-расширителями — один ‘из лучших выходов для


приложений, которые должны работать в любых условиях, включая старые вер-
сии 2О$, ив то же время требуют 32-битный режим. Еще совсем недавно боль-
шинство компьютерных игр, в частности знаменитые Роот и Опаке, выпускались
именно как программы, использующие расширители РО5. На сегодняшний день
в связи с повсеместным распространением операционных систем для, РС, работа-
ющих в 32-битном защищенном ‚режиме, требование работы в любых версиях
20$ становится менее актуальным и все больше программ выходят только в вер-
сиях для УЛпдо\з95 или МТ, чему и посвящена следующая глава.
Глава 7. Программирование
для МИпдоми$ ЭЛТ.
Несмотря на то что УЙпдо\з 95/МТ кажутся более сложными операционными
системам по сравнению с 2О$, программировать для них на ассемблере намного
проще. С одной стороны, \Лшдо\з-приложение запускается в 32-битном режиме
(мы не рассматриваем УЙпдо\з 3.11 и более старые версии, которые работали
в 16-битном режиме) с.моделью памяти Йаё, так что программист получает все те
преимущества, о которых говорилось в предыдущей главе, а с другой стороны —
нам больше не нужно изучать в деталях, как программировать различные устрой-
ства компьютера. на низком уровне. В настоящих операционных средах приложе-
ния пользуются только системными вызовами, число которых здесь превышает
2000 (около 2200 для УЛидочз 95 и 2434 для Лидо МТ). Все УЛ пом з-прило-
жения используют специальный формат исполняемых файлов — формат РЕ
(РогаЫе ЕхесшаЫе). Такие файлы начинаются как обычные ЕХЕ-файлы старо-
го образца (их также называют МА. по первым двум символам заголовка). Если
такой файл запустить из ОО$, он выполнится и выдаст сообщение об ошибке
(текст сообщения ‘зависит от используемого компилятора), в то время как
УЛадо\5 заметит, что после обычного М7-заголовка файла идет РЕ-заголовок,
и запустит приложение. Это будет означать лишь то, что для компиляции про-
грамм потребуются другие параметры В командной строке.

7.1. Первая программа


В качестве нашего первого примера посмотрим, ‘насколько проще написать под
УЛпдо\мз программу, которая загружает другую программу. В вех (см. раздел
4.10) нам приходилось изменять распределение памяти, заполнять специальный
блок данных ЕРВ и только затем вызывать 20$. ‚Здесь же не только вся процеду-
ра сокращается до одного вызова функции, а еще оказывается, что можно точно
так же загружать программы, документы, графические и текстовые ‘файлы и даже
почтовые и Пиегпе(-адреса- все, для чего в реестре УЯпдо\уз записано действие,
выполняющееся при попытке открытия.
; \м1пыгТ. а5т
; Пример програмы- для м1п32.
; Запускает установленный по умолчанию браузер. на адрес, указанный в строке ИНЬ.
; Аналогично можно запускать любую программу, документ и какой угодно файл,
; для которого определена операция ореп.

11с1и4е зпе1132.1пс
11с1и4е Кегле132. 1пс
№! Программирование для МИп4о\ми$ 95/МТ. |
.386
.тоде] ^ Е]а*
сопзт
ЦВЕ [@6) "Пер: /Иммм, П1опК1п9. огд/^сиЬЬ
И", 0
соде |
_зтаге: ; Метка точки входа должна начинаться с подчеркивания.
хог ерх, ебх .
ризп ебх ; Для исполняемых файлов- способ показа.
ризй ебх ; Рабочая директория.
рузв ебх ; Командная строка.
ризв оРзет ИА. ; Имя файла с путем.
ризй е5х ; Операция ореп или рг1п{ (если МУЦ - ореп)
ризв ебх ; Идентификатор окна, которое получит сообщения:
са]11 Эпе11Ехесите ; злейЕхесифе (МАЕ, м, уг, ми, МОЕ, МУ}
“`` ризН ебх ”_^” Код’ выхода,
са] Ех Ргосе$$ ; Е Ргосезз(0)
епд _з\агт К та
Итак, в этой программе выполняется вызов двух системных функций 32 -
ЗВеПЕхесше (открыть файл) и ЕхРгосезз (завершить процесс). Чтобы активизи-
ровать системную функцию Уллдое, программа должна поместить в стек все пара-
метры от последнего к первому и передать управление дальней САТТ.. Данные функ-. 1
ции сами освобождают стек (завершаясь ВЕТ №) и возвращают результат работы
в регистре ЕАХ. Такая договоренность о передаче параметров называется ЭТОСАТГ.
С одной стороны, это позволяет вызывать функции с нефиксированным числом
параметров, а с другой — вызывающая сторона не должна заботиться об освобож-
дении стека. Кроме того, функции УИп4до\$ сохраняют значение регистров ЕВР,
ЕЗТ, ЕРГ и ЕВХ, этим мы пользовались в нашем примере - хранили 0 в регистре.
ЕВХ и применяли 1-байтную команду РОЗН ЕВХ вместо 2-байтной РОЗН 0.
Прежде чем мы сможем скомпилировать уЧпи!.азт, нужно создать файлы
Кегпе!32пс и $Ве32.4пс, куда поместим директивы, описывающие вызываемые
‚ системные функции.
>

; Кегпе132. 1пс | : : ‹
; Включаемый файл с: определениями фуный из , Кегпе132. 911.
1ЕдеЁ _ТАЗМ_
1пс144е135. 1прогё32. 116
; Имена используемых функций.
ехтгп Ех {Ргосе$$ :пеаг
е1зе
116119116 Кегпе132.116
; Истинные имена. используемых функций. _
ехегп __ир.._ЕхРгосе$@4 ; дмога - с
; Присваивания для облегчения читаемости кода.
Ех1{Ргосез$ еци __зтр__Ех1{Ргосез$@4
ета

‚ $1е1132. 1пс
Включаемый файл с определениями функций из 31е1132. 611.
Первая программа. :-
174ег _ТАЗМ_
зистиве11Ь 1трог\ 32.116
\ ; Имена используемых ‘функций.
ехфгп пе] }Ехеситед: пеаг
; Присваивания. для облегчения читаемости кода.
. Зле11Ехесите еди Зпе11Ехеси{еА
е1зе о.
—_ нешвень 51е1132. 316
; Истинные имена используемых функций.-
ег — __1пр_`ЭлеЕхеситеАе24:
дога
’; Присваивания дяя облегчения читаемости кода.
`’ Зве}1Ехесите` еди _ __Жр__бнеЕхеситеА@24
еп 1 Е | ВВ ` .

Имена всех системных функций \1132 модифицируются так, что перед име-
нем функции ставится подчеркивание, а после - знак @ и число байтов, кото-
рое занимают параметры, передаваемые ей в стеке: так ЕхиРгосез$ превращается
в _ЕхИРгосез@4. Компиляторы с языков высокого уровня часто останавливают-
ся на этом и вызывают функции по имени _ЕхиРгосез@4, но реально появляется
небольшая процедура-заглушка, которая ничего неделает, алишь передает управ-
ление на такую же метку, но с добавленным_ _нар_- _ _пар_ _ЕхИРгосез$@4..
Во всех наших примерах мы будем обращаться ннапрямую к _ _Нпр__ ЕхИРгосе5$
94.
К сожалению, ТАЗМ (а точнее ТТ МКЗ2) использует собственный способ вызова
системных функций, который нельзя обойти подобным образом, и программы,
скомпилированные с его помощью, оказываются ‘немного больше и в некоторых
случаях работают медленнее. Мы отделили описания функций для ТАЗМ во
включаемых файлах при помощи директив условного ассемблирования, которые
будут использовать их, если в'командной строке ассемблера указать /О_`ТАЗМ_.
Кроме того, все функции, работающие со строками (как, например, ЗвеЙЕхесие),
существуют в двух вариантах. Если строка рассматривается в обычном смысле,
как набор символов АЗСИ, к имени функции добавляется А (ЗВеПЕхесщеА). Дру-
гой вариант функции, использующий строки в формате ОМСОРЕ (два байта на
символ), заканчивается буквой О. Во всех наших примерах будут использоваться
обычные А5СП-функции, но, если вам потребуется перекомпилировать програм-
мы на ОМСОТЬЕ, достаточно поменять А на 1 во включаемых файлах.
Итак, теперь, когда у нас есть все необходимые файлы, можно скомпилировать
первую программу для УЛпдо\5.
Компиляция МАЗМ:
т] /с /со{Е /бСр м1пиг1. азт
Пок м4пиг1. 05} /зибзузсет:и1пд0м8
(здесь и далее используется 32-битная версия НпК.ехе)
Компиляция ТАЗМ:
тазт /м /т1 /0_ТАЗМ_ им1пиг].азт
{11пК32 /Тре /аа /с /х м1пиг1. 06}
а

№! Программирование для МИпао\мз 95/МТ:


Компиляция У\А$М:
мазт м1лпиг1. азт .)
мИпк Ре м1пиг1.06] Рогт м1п90м$ пе ор с

ь Также для компиляции потребуются файлы Кегпе]32.1Ь и зВе 32.16 в первом


и третьем случае и ипрогё32.1Ь — во втором. Эти файлы входят в дистрибутивы =
любых средств разработки для \1п32 от соответствующих компаний — Мгсгозой, 1
У’акот (ЗуБазе) и ВоЙап4 (пргзе), хотя их всегда можно воссоздать из файлов }
Кегпе!32.41 и зве!132.41, находящихся в директории \/ТМРО\5\$УЗТЕМ.
Иногда вместе с дистрибутивами различных средств разработки для УЛп4о\з .
поставляется файл \/пдо\ тс, в котором дано макроопределение Гпуоке или :
заменена макросом команда са так, что при вызове можно передать список аргу- }
ментов, первым из которых будет имя вызываемой функции, а затем через запя- }
тую - все параметры. С использованием данных макроопределений наша про-.
грамма выглядела бы так:
_з%аги:
хог ебх, ебх _
Тлуоке Зпе11Ехесите, ебх, еБх, ‚оРРзет ЦВЕ, еБх, \
ебх, ебх .
‚Тпуоке Ех {Ргобезз, еБх- О.
епа _зфагт” В
И этот текст компилируется в точно такой же код, что. и у нас, но выполняет- 3
ся вызов промежуточной функции _ЕхиРгосез$@4, а не функции - _пар_.
_ЕхИРгосез:@4. Использование данной формы записи не позволяет применять |
отдельные эффективные приемы. оптимизации, которые мы будем приводить в.На-..
ших примерах, —- помещение параметров в стек заранее.и вызов функции коман- :
дой ] МР И наконец, файла мшдоу’зшс у вас может просто не оказаться, так что`
будем писать ризВ перед каждым параметром вручную.

7.2. Консольные приложения


Исполнимые программы для УЛп4о\з делятся на два основных типа — кон-
сольные и графические приложения. При запуске консольного. приложения от-
крывается текстовое окно, с которым программа может общаться функциями
\\МтиеСопзое/Кеа4Сопзое и другими (соответственно при запуске из ‘другого
консольного приложения, например файлового менеджера ЕАК, программе отво- +
дится текущая консоль и управление не возвращается к ЕАК, пока программа не *
закончится). Графические приложения соответственно не получают консоли и дол-
жны открывать окна, чтобы вывести что-нибудь на экран. ‘г
Для компиляции консольных приложений мы будем пользоваться следующи-
ми командами.
МАЗМ: . в | и
м] /С /соЕЕ /бр м1пиг!.азт` _ ани: ини
ИПК \м1пиг1.азм /зибзузтет: сопзо]е |
ТАЗМ: до
тазю /й /м: /О_ТАЗМ. мГпиг1. азт
1 1пкЗа. /Тре {ар /с /х м1пиг1. 05}.

У\А$М:
мазт и1пиг]. аз
м Чик Р11е м1пиг1.06} Рогт ип фоме пт тип те сопзо1е ор с

` Попробуйте скомпилировать программу зипий ат указанным способом, что-


бы увидеть, как отличается работа консольного приложения от графического.
В качестве примера полноценного консольного приложения напишем программу,
которая неречислит все подключенные сетевые ресурсы (диски и принтеры), исполь-
зуя системные функции У/МеОрепЕпит, \УМе(ЕпитКезоигсе и \/Ме(СозеЕпит.
; петепим. азм
; Консольное приложение ля \1132, перечисляющее сетевые ресурсы.
1пс144е де132.1пс
1пс]и4е Кегпе132. 1пс
1пс1иде трг. 1пс

„386
‚воде Гат
. сопзт
дгее{_теззаде Ге 'Ехатр1е м1п32 сопзо]е ргодгам’
, ООН ‚ОА, ООН, АН, 0
еггог1_теззаде 96 Оп, ОА, 'С0и19 пот дет сиггеп{ изег папе’,
оО, ОАВ,0
еггог2_тмеззаде 45 ООН,
ОАВ, 'Соу19 пот епимегате”
, 90; ОАВ, 0
0004_ех11_ 159 (2) ‚ ООН, ОАВ, ООВ, ОДА, '№гма} Чегилпат1от” , ООВ, АВ, 0
епит_т501 6 00,
ОАВ, °[оса1 ',0
епит_ 1302 - 4 ’ гемоте- ',0
‚ Фата . .
узег_пате 96 "[1$т 0Г соппестед гезоигсез Фог ибег”
узег_БитР 6 64 дир (?) ; Буфер для. ИМетбетузег.
изег_ риЕЁР_1 99` $-изег. Буй? - ; Размер буфера для ММетбетузег.
епит_Ъие_1 99 1056 ; Длина епит_БиР в байтах.
епит_еп{г1ез . 44 1 | ; Число ресурсов, которые в нем помещаются.
„дата? | у
епит_Би МТВЕЗОЦВСЕ <?,?;?,?,?,?,7,3> ; Буфер для ММетЕпитВезоигсе.
49 256 Чир (2) ; 1024 байта для строк
меззаде_1 94 ? ° р Переменная для Иг1ТеСопзо]е,
епит_Папа]е ва ? . . ; Идентификатор для ИМетЕлитвезоигсе..
. 604е
_зтаге:
‚ Получить от системы идентификатор буфера вывода $190.
ризв $Т0_ОУТРУТ_НАМОЕЕ .
са11 бет5{4Напа1е : Возвращает идентификатор ЗТОО0УТ в еах,
том еБх, еах ` ; а мы будем хранить его в ЕВХ.
‚ Вывести строку дгеет_теззаде на экран.
по\ е$1, оРРзет дгее{_меззаде
са11 оитрит_$1г1п9

14 Зак. 459
ч

ГИ Программирование для МИпдому$ 957 Е


; Определить“имя пользователя, которому принадлежит наш процесс.
оу е$1, оРЕзет изег_БитЕ
ризй ОЁРзет изег_БиРР_} Адрес переменной с длиной буфера.
ризв е$1 Адрес буфера.
ризв 0 м
са} 1 \МетбетИзег
стр еах, №0_ЕВАОЯ `Если произошла ошибка, :
пе еггог_ех1т1 выйти,
мо\ е51, оРЕзеЕ изег_паме иначе - вывести строку на’ экран.
са11 оитри{_ $7119

; Начать перечисление сетевых ресурсов.


ризН ОЁРзеф епим_Пап]е Идентификатор для ММетЕпитВезоигсе.
ризв 0
ризй ВЕЗОЦАСЕУЗАСЕ _СОММЕСТАВЕЕ ; Все присоединяемые’ ресурсы,
ризй ВЕЗОЦВСЕТУРЕ_АМУ Ресурсы любого Типа.
рии ВЕЗОЦВСЕ_СОММЕСТЕВ Только присоединенные сейчас.
са11 ММетОрепЕпит Начать перечисление.
сир еах, №0_ЕВВОВ Если произошла ошибка,
Эпе еггог_ех112 выйти.
‚ Цикл перечисления ресурсов.
епитегат1оп_]о0р;
ризв` ОЁЕзет епит. Би Р_1 Длина буфера в байтах.
рузН ОРЕзет епим_БиР Адрес буфера. |
ризи оЕЁзе{ епит_ептг1е$ Число ресурсов.
ризп Фиога рфг епит_папа1е Идентификатор от УМетОрепЕпим.
са11 ИМетЕпитВезоигсе
стр еах, ЕЯВОЕ_№0_МОВЕ_ТТЕМ$ Если они закончились,
` де епд_епимега {оп завершить перечисление,
стр еах, №0_ЕВВОН если произошла ошибка,
пе еггог_ех112 выйти с сообщением об ошибке.
_: Вывод информации о ресурсе на экран.
МОУ _ е$1, ОР зе{ епит. 1591, ; Первая ‘часть строки -.
са1] ° ори э19 на консоль.
р тоУ е$1, диог@ рфг епит_БиР. 1 ргоса1Мапе ; Локальное имя устройства -
`‘са11 оитрит_3з1г1пд ; на консоль.
` по\ е$1, оРРзет епит_т$92 ; Вторая часть строки -
са11 оцфрит_$1г119 ; на консоль.
поу ° е31, Чмог@ рфг епит_виТ. 1рВетотемате ; Удаленное имя устройства -
са11 оирий_э1г1п9 "”; Туда же, —°
Этр $АогЕ епитега{1оп_100р’. ; Продолжить перечисление.
; Конец цикла. и.
епд_епитега*1оп: | . 7‘
ризи мог рфг епим_вВапд1е
са11 ИМетС озеЕпит ` ; Конец перечисления. |

оу е$1, оРРзет 9004_ех1*_т$9 ь


ех1{_ргодгам:
са11 оцЕру{_$1г1п9 ‚ Вывести строку.
ризп 0 р Код выхода.
Консольные приложения.
са] 1 Ех11Ргосезз : ; Конец программы.
; Выходы после ошибок.
еггог_ех1т1:
во\ е$1, ОТТзет еггог1_теззаде
Этр ЗНогЕ. ех1{_ргодгат
еггог_ех112: .
А е$1, огРзет еггог2: меззаде
зтр зНогЕ ех1“_ргодгат С:
; Процедрура оцтрит_3тг1п9.
; Выводит на экран строку.
; Вход: е$1 - адрес строки. |
; ебх - идентификатор зфдоие или другого консольного буфера.
оиутрит-$4г1п9 ргос пеаг”
‚: Определить длину строки.
С19
хог еах, еах
моу е91, е51
герпе зсазь
“дес е41
56 е4}., ез1
; Послать ее на консоль.
ризй 0 ,
риев оТРзет тезбаде_1 ; Сколько. байтов. выведено на консоль.
ризВ е41 ‹ Сколько байтов надо вывести на консоль. _
ризв е$1 ‚ Адрес строки для вывода на консоль. |
рип еБх ; Идентификатор буфера вывода.
са11 Ин теСопзо]е . ; Игбебопзоте (ПСопзо1ебитрит, 1руВи Рег,
; сспТомиуте, 1ресН\г1 ем, 1руВезегуе4)
ге }
оитри{_31г1п9 еп@р

[8] _зтаге

пс надо добавить между Че! _ТАЗМ_ и ебе строки:


В файл Кегпе!32
| ехргп бесбтаНапд1е:пеаг ^
‚ ежги иг КеСопзо]еА:пеаг
Иг1 теСопзо]е еди Уг1тебопзо1еА
и между е|зе и епаЙ:
ег __Иир__бет5таНап91е64
. ехгп — _ Шир. _ИгИеСопзо1еАе20
бет5тЧНапа]е еду __1тр__бет5\аНапа 1ее4
Иг1ТеСопзо]е еаи 2_4тр__
Мг еСоп$о1еАе20

‚Кроме того, надо создать файл шрг/шс:


; мрг.1пс
: Включаемый файл с определениями функций из прг. 911.
1Е4еГ. _ТАЗМ_ |
116]49е116 1трог{32. 116
; Имена используемых функций. `
ехтгп УМетбетузегА: пеаг
и
ехегп — УМетОрепЕпимА:леаг
ШИ! Программирование для \Мпдомуз 95 /МТ.
ехегп иМетЕпитЯезоигееА:пеаг
ехфгй ИМетС1озеЕпию:пеаг
; Присваивания для облегчения читаемости кода.
УМетбетИзег еди ММетбетОзегА
ИМетОрептЕлит _ еди УМетОрепЕпитА
ИМетЕпитАезоигсе еаи ИМетЕпитАезоигсеА
‚ е1зе
,
11с]иде116 арг. 116
‚ Истинные ‘имена используемых функций.
ехфгп __1пр__ММетбехузегА@12 : Чмотд :
ех{ гп __1пр__УМ№ТОрептЕпьтА@20: диога | 1
ехтгп __Лтр__ММетЕпитАезоигсеА@16 : дога
ехеги _ утр_- ММетС1 озеЕпит@4 : Фиога |
; Присваивания для облегчения читаемости кода.
ИМетбетИзег .. еди __1тр__ММетбет0зегА@12
М№МетОрепЕпит еду __1ир__ИМе{ОрелЕпитА@20
ИМетЕпитАезоигсе еди __1тр__ММетЕпимВезоигсеА@16
ИМетс1озеЕпит еду _. Чар__М№тС1озеЕпите4
епа1Т

‚ Еще потребуется файл 4е32.1пс, куда мы поместим определения констант 1


и структур из разных включаемых файлов для языка С. Существует утилита В21щс,
преобразующая эти файлы целиком, но нас интересует собственный включаемый*
файл, в который будем добавлять новые определения по мере надобности.
; 9е132.1пс
;, Файл с определениями констант и типов для примеров программ под
; №1132.

; Из м1пбазе.в.
$ТО_ОИТРОТ_НАКОЕЕ ед {#-11
; Из м1пеггог.п:
М№_ЕВАОВ ечи 0
ЕНРОН_М№0_МОВЕ_ТТЕМ$ еду 259

; Из маппетик.п.
НЕЗОЦНСЕУЗАСЕ _СОММЕСТАВЕЕ еди 1- 2 .
ВЕЗОУНСЕТУРЕ_АМУ - еаи 0
ВЕЗОЦВСЕ_СОММЕСТЕВ _е9в 1
МТНЕЗОУВСЕ этгис
дибсоре, 99 2
аиТуре ва 7. й
901 зр1ауТуре 94 2
9\/за9е 949 -?, й
1рЁоса1Мате 99 ?
]1рАетотеМамте 99 2.
1рСоттепт 99 ?
1рРгоу1аег 09 ? >
МТВЕЗОЦВСЕ епа$ : | '
=.

Этот пример, разумеется, можно было построить эффективнее, выделив боль-


шой буфер для \/Ме[ЕпилВезочгсе, например при помощи Госа!АПос или:

=
Графические приложения
С/оЪа!АПос (в мп32 это одно и то же), а потом, прочитав информацию обо всех
ресурсах, хранящихся в нем, пришлось бы следить за тем, кончились они или нет,
и вызывать \/МеЕпитВезоигсе еще раз.

7.3. Графические приложения


7.3.1. Окно типа Ме5задеВох
Для того чтобы вывести на экран любое окно, программа обычно должна сна-
чала описать его внешний вид и все свойства,то есть то, что называется классом
окна. О том, как это сделать, - немного позже, а для начала выведем одно из окон
с предопределенным классом - окно типа МеззавеВох. МеззавеВох — это малень-
кое окно с указанным текстовым сообщением и одной или несколькими кнопка-
ми. В нашем примере бообщением будет традиционное’`Нейо мой 4!
; м1пре110.
аз
Графическое м1п32-приложение.. -
; Выводит окно Типа меззадебох с текстом “Не? 1юо. мог1 9!”

1пс1и9е дег32.1пс
1п61и4е Кегпе132.
1пс
Зпс1ибе изег32. 115:

.386 Е
.Воде1 Е1ат+
. сопзт
; Заголовок окна. .
ве] }о_1141е 96 “Е1гзт
ом1п32 ИТ ргодгат”,0
; Сообщение. | `
ле] 1о_теззаде 96 ”Не]110 мог19!”,0
‚ соде , -
_втагт: р ` - ,
рызй МВ_ТСОМТНЕОНМАТТОМ ‚ Силь окна;
ризН оРРзет Ве]10.1111е ; Адрес строки с заголовком.
ризп отЕ5ет пе110_теззаде ; Адрес строки. с. сообщением. ..
ризВ 0 . | ; Идентификатор предка.
са11 МеззадеВох

ри 0’. ; Код выхода.


са1] Ех{Ргосез$ ; Завершение .программы. .
епа _втагте
Естественно, нам потребуются новые добавления к включаемым файлам:
‚добавить к файлу 4е{32.шс строку
; Из им1пузег. п.
МВ_ТСОМТМЕОВМАТТОМ еди дон

и создать новый файл, изег32.1пс, куда будут входить определения функций из


цзег32.АЙ- библиотеки, где расположены все основные функции, отвечающие за
оконный интерфейс:
ЕЕЕНШИШИИШИ Программирование для МЛпдому; 95 /МТ
; и3еЕ32.1пс
‚ Включаемый файл с определениями функций из изег32. 911.

114еЕ _ТАЗМ_ |
1п6с104е115 1трог{ 32. 116
; Имена используемых функций.
| ех{гя МеззадеВохА: пеаг
; Присваивания. ^
МеззадеВох еду МеззадевВохА
е15е
11с1и9е116 узегЗ2. 115
; Истинные имена используемых функций.
ехфгп __1тр__МеззадеВохА@16 :днога
‚; Присваивания для облегчения читаемости ‚кода. ь
МеззадеВох еды ар Неъзадовохлел6 7
епт! | :

. _ Теперь можно скомпилировать эту программу аналогично тому, как мы компи-


лировали \/пи.азт, и запустить.- на экране появится маленькое окно с нашим
сообщением, которое пропадет после нажатия кнопки ОК. Если скомпилировать :
улипреПо.эзт как консольное приложение, ничего не изменится, но текстовое окно
с именем программы будет открыто до тех пор, пока не закроется окно с нашим
„сообщением.

7.3.2. Окна .
Теперь, когда мы знаем, как просто выводится окно с предопределенным клас-
сом, возьмемся за создание собственного окна — процедуры, на которой будут
базироваться все последующие примеры, и познакомимся с понятием сообщения.
‚В РО$ основным средством передачи управления программам в различных ситу-
ациях служат прерывания. В \УЯп4о\из прерывания используются для системных
нужд, а для приложений существует аналогичный механизм-—механизм событий.
Так, нажатие клавиши на клавиатуре, если эта клавиша не используется УЯп4о\уз,
генерирует сообщение \/М _КЕУРОУ/М или \/М_КЕУОТР которое можно пере-
хватить, добавив в цепь обработчиков события собственное при помощи ак
ал

Зе \Ип4о»НооКЕх. Затем события преобразуются в сообщения, которые рассы-


лаются функциям — обработчикам сообщений - и которые можно прочитать из
основной программы при помощи вызовов СеМеззаре и РееКМеззаве.
Для начала нам потребуется только обработка сообщения закрытия окна о
о

(\УМ_РЕЗТВОУ и \УМ_ОП1Т), по которому программа будет завершаться.


; \1пдом, аз = Чоо
; Графическое м1п32-приложение, демонстрирующее базовый вывод окна:

1пс]и4де де!32.1пс
1пс1и4е Кегпе132.
1пс $
1пс1иде изегЗ2. 1пс
.386._ л
щ
.1оде]. #1а{
. дата
т

Зе
Графические приложения
с}а3з_паме [#18 "уЧпдом с1азз 1”;0 |
м1 пдом_пате Г "и1132 азземЛу ехатр1е”,0
; Структура, описывающая класс’ окна.
ис ММОСЬАЗЗЕХ <4»12, С5$_НАЕОВАМ ог ©$_УВЕОВАИ, оРРзет м1п_ргос,0,0,7,?,?, \
СОЕ08_МТМООМ+1, 0, отРзет с1аз5_пате,0>
; Здесь находятся следующие’ поля:
; №. 65$126е = 4*12 - размер этой структуры
; мс. зтУ1е - стиль окна (перерисовывать при изменении
размера)
ис. 1рЕиМпаРгос - обработчик событий окна (м1п_ргос)
; мс. сЬС1зЕхига - число ‘дополнительных байтов после структуры (0)
; мс. сСЫМАЕХЕГа - число дополнительных байтов после окна (0)
; мс.|Тлзтапсе‘- идентификатор нашего процесса (?)
; мс.АТсоп - идентификатор иконки -(?)
; ме.ВСигвог - идентификатор курббра (7)
; мс. ПЬгВаскогоипд - идентификатор кисти или цвет фона + 1 (СОЕОВ| итнрои+1)
; мс.1р32МепиМате - ресурс с основным меню (в этом примере - 0)`
; мс. 1ре2С1аззМате - имя класса (строка с1аз$_паме} :
; м. НГсоп$т - идентификатор маленькой ‘иконки (только в 4 пдонв 95,
; для МТ должен быть 0).

. Вата?
50 и5б <?,2,2,?,?,?> ЗА это - структура, в которую возвращается
| , , сообщение после бе{Меззаде.
. соде . ‚
_зтагт: : -_.
хог ебх, е5х . ; В ЕВХ будет 0 для команд ризй 0.
; Определить идентификатор нашей программы
ризй ебх . .
са11 бетМоди]еНала1е
тоу е31, вах ; и сохранить его в ЕЗТ.
; Заполнить и зарегистрировать класс. . ‚
му - диог@ руг мс. НТлзтапсе,
еах ; Идентификатор предка,
; Выбрать иконку.
рузП ТОТ АРРЕТСАТТОМ ; Стандартная’ иконка приложения. -
ризв ебх -; Идентификатор ‘модуля с иконкой.
са} 1 ЕоадТсоп
` МОУ мс. ИТсоп, еах ; Идентификатор’ иконки для нашего класса.
; Выбрать форму курсора. ,
ризи — ТОС АВАОМ о; Стандартная стрелка. °
ризй ех . ; Идентификатор модуля с курсором.
са11 фоадСигзог 7 `
моу мс. ПСигзог,еах ; Идентификатор курсора для нащего класса.
ризН оТЕзет ис
са11 Ве91$тегС1аззЕх ; Зарегистрировать класс.
; Создать окно.
МОУ есх, Си_УЗЕВЕРАШТ; ризп есх короче ризН № в. пять ‘раз.
ризп ебх ; Адрес структуры СНЕАТЕЗТВУСТ (здесь №1).
ризв е51 , ; Идентификатор процесса, который будет получать.
„ ; сообщения от окна (то есть наш).
° риэй ‚ебх ; Идентификатор меню или окна-потомка.

1
'ЕЕЗИВНШИИШИИ! Программирование для МИпдо\миз 95/МТ 1
ризв ‚ ебх ; Идентификатор окна-предка.
ризп есх ; Высета (Си ИЗЕБЕРАЦСТ - по умолчанию).
ризВ есх ; Ширина (по умолчанию).
ризй есх ‚; У-координата (по умолчанию).
ризй есх ; Х-координата (по умолчанию).
ризй и — ОЕВЕАРРЕОАТНООИ ; Стиль окна.
ризй оЁРзет м1пдом_пате: . ‚ Заголовок
окна.
ризН ОРЕ5еф с1аз$_паме; Любой зарегистрированный класс.
ризй ебх ; Дополнительный Стиль. -
са11 Сгеате\1ивомЕх <; Создать окно (еах - идентификатор окна).
‘ ризй еах ; Идентификатор для Урдатемтдом.
рун ЗИ_ЗНОММОНМАТ. ; Тип показа для для ЗНом\1пдом..
ризй еах ‘_; Идентификатор для Звом\1паом.
; Больше идентификатор окна нам не потребуется.
са] Зои пом ‚; Показать окно
са11 Урдатем1пдом ‚ И послать ему сообщение. \М_РАТАТ;

; Основной цикл - проверка сообщений ‘от окна и выход по им СИТ.


ПОМ е41, оРГзет пз9_ ; ризп ‘е91 короче ризп № в `5 раз
меззаде_10оор:
ризй е5х ; Последнее сообщение.
ризп. . ебх ; Первое сообщение.
ризН ебх ‚ Идентификатор окна (0 - любое наше окно).
ризп е91 ; Адрес структуры М5в.
са11 бетМеззаде ; Получить сообщение от окна с ожиданием -
‚ не ‘забывайте использовать. РееКМеззаде,
‚ если нужно в этом цикле. что-то выполнять.
тез1 еах, еах ‚ Если получено ММ_О\ЛТ,
р ех1*_т59_100р ‚ выйти.
ризй е91 ‚Иначе - преобразовать сообщения типа
са11 Тгап$]атеМеззаде ; ММ КЕУИР в сообщения типа \М_СНАВ
ризй е91
са11 01зратсИМеззаде ; и послать их процедуре окна {иначе его просто
‚ нельзя будет закрыть).
тр эпогЕ теззаде_1оор ; Продолжить цикл.
ех1{_т59_10оор:
; Выход из программы.
ризН еБх
са11 Ех1{Ргосе$$

‚ Процедура мап_огос. .
; Вызывается окном каждый раз, когда оно получает какое-нибудь сообщение. р
; Именно здесь будет происходить вся работа программы. у

‚ Процедура не должна изменять регистры ЕВР, ЕОТ, ЕЗТ и ЕВХ!.

м1п_ргос ргос
‚ Так как. мы получаем параметры. в стеке, построить стековый кадр.
риузВ ебр
пу ебр, езр
; Процедура типа \1п4домРгос вызывается со следующими параметрами:
пр: |
Графические приложения
мр_П\па еду’ @мога рфг [ебр+08#]; идентификатор окна,
мр_иМ59 еди Чмога рег [ебр+0Сн]; номер сообщения,
- ир_мРагат еди @мог@ рег [еБр+101]; первый параметр,
. мр_1Рагам еди мог руг [ебр+141}; второй параметр.
‚ Если мы получили сообщение ММ ОЕЗТВОУ (оно означает, что окно уже удалили
; С экрана, нажав АМ-Е4 или кнопку в верхнем правом углу),
‘ То отправим основной программе сообщение ММ_О\Т.
Стр мр_иМзд, ИМ_ОЕЗТВОУ
те поф_мт_дезтгоу
ризп 0 ; Код выхода.
са11 Роз10ч1{Меззаде . ; Послать ММ ОТ
тр эпогЕ епд_имт_спеск 5 и выйти из процедуры.
пот ми_дезтгоу:
; Если мы получили другое сообщение -. вызвать его обработчик по умолчанию.
]еауе ; Восстановить ебр
Зтр бе иНпвомРгос ; и вызвать БеРи1пдомРгос с нашими параметрами.

; и адресом возврата в стеке.
еп4_мт_свеск:
]еауе ; Восстановить ебр ”
гет 16 ‚ и вернуться самим, очистив стек от параметров.
м1п_ргос епар р
- епа _$Тагт

Необходимые добавления в ‘файл 4е32.1 Ш:


; Из итпизег. п.
ТОТ. АРРЕТСАТТОМ еду 32512
, ММ_ОЕЗТАОУ еаи 2
_ С$_НВЕВНАИ еди 2
С$_УНЕОНАМ ` еду 1 _.
С ИЗЕБЕРАЦЕТ еди` 800000001 `
\$_О\МЕВЕАРРЕВМТЮМООМ еди ` 0650000 -_ .
Т0С_АВВОМ ед 32512
$М_ЭНОММОВМАЕ. еди 1 /
СОЕОВ:мтмО0м еди .5 |
ИМОСЕАЗЗЕХ — Тис
с6512е - 99 ? '
зтуде [ее] ?
1реп\мпаРгос . 99 - ?
СЬС1зЕхтга 49 ?
СБИпаЕхтга [ее ?
| Тпзтапсе 04 7.
ВТсоп 96 -?
ЮСигзог | 99 ?
ВБгВаскогоип@ — 04 7.
1рэз2МепиМате 94 2.
1р$2С1аззМате 94 ?
ВТсоп$м 94 2.
ИМОСТАЗЗЕХ еп4$
За ЗЕгис
| ВМО 33 ? `
‚“

№! Программирование для МИпому$ 95 мт -


й
пеззаде 94 ?
урРагат 99 ?
1Рагат ’ 99 ? '
{ле 99 ? -
рт [ее ?
М6 епд$

Добавления в файл изегЗ2.1с:


между ИЦе! _ТАЗМ_ ие|5е:
. ехёгп 015ратспМеззадед: пеаг
ех{ги — Тгапз}атеМеззаде: пваг
ехфгп бетМеззадед : пеаг
ехфгп [оадТсопА: пеаг
ехфгп Ордатем1лдом : пеаг
ехфгп Зпомм1 пдом: пеаг
ехгп СгеатеМ1пдомЕхА: пеаг
ежгл — Бе паонРгосА: пеаг
ехфгп Роз{(и1{Меззаде: пеаг
ех{гп ВеддэтегС1аззЕхА: пеаг
ехЕгп {оадСигзогА: пеаг
О1зратспМеззаде еды 01зрафсиМеззадед
бе{Меззаде еци бетМеззадеА
1 оад1соп- еду Гоа4ТсопА
Сгеатей1пдомЕх еду Сгеате\1паомЕхА —
Бе 1 паомРгос еди ° Беги паомРгосА
Аед15тегС1аз3Ех еди Вед1зтегС1а$ЕхА
ЕоааСигзог еди {саЯбигзогА

и между е[5е и еп
у ехтгп __Чр__О1зратсНМеззадеА@4 :днога
ехфгп __1тр__Тгапз1а+еМеззаде@4 : ога
ехтгп = __1тр. _бе{Меззадед@16 :дога
ехтгп __утр__1оа9ТсопА@8 : Чиога
ехегп __1тр__Урфатем
1пдом@4 : диога
ехтгп __итр__ помп 90м@8 :Фиогд
`ехп =__1пр__СгеатенупдомЕхА@48 : дмога
ехЕгп __1тр__беР\ пвомРгосА@16 :мог
ехфгп 21тр__Розт0ц4иМеззаде@4 : мог ^
ехфгп __1тр__Ве91$ТегС1аззЕхА@4 : @могд
ехтгп __Нтр__Коа@СигзогА@8 : диога
О1зратсНМеззаде еды ._1тр__О1зрассАМеззадеА@4 :
Тгапз} атеМеззаде еди __4тр__Тгапз1а<еМеззацев4 .
бе{Меззаде. еди __1тр__ве*Меззадеде16 у
ГоааТсоп еди __1пр__Коа9ТсопА@8 . 3
Урдатей1пдон еду __1тр__урватемапдоне4 :
Эпоми1 дом, еди __1тр__ЭВом 19088 В:
Сгеате\1пдомЕх еди __1тр__Сгеатем\1пдомЕхА@48 --
Веги 1 пдомРгос еди __1тр__ бег пдомРгосА@16 |
РозтОи11Меззаде еди _. 1тр__Розт0и{Меззаде@4 р
Вед1зТегС1аззЕх. еди ._1тр__Ве91зтегС1аз$ЕхА@4 : |
оадбигзог еаи __тр__Коа9бигзогА@8

Н
графические приложения
и в файл Кегле!324пс между И4е!_ТАЗМ_ и е]зе;
, ехфрп бетмоди1еНапа1еА: пеаг
бетМови1еНала1е еди бетМоди]еНапа@1еА
и между е1зе и епИ:
| ехегп `_1тр__бе{Моди1еНапд1еА@4
:дмога
бе{Моди1еНапа1е еди —_Зпр__бемоди1енапазеле4
В начале раздела говорилось, что программировать под \Лп4о\$ просто, а в то
же время текс? обычной программы вывода пустого окна на экран уже занимает
больше места, чем, например, текст программы проигрывания \ау-файла из раз-
дела 5.10.8. Где же обещанная простота? Так вот, оказывается, что, написав
умадо\азт, мы уже создали значительную часть всех последующих программ,
а когда мы дополним этот текст полноценным диалогом, обнаружится, что боль-
ше не нужно писать все эти громоздкие конструкции, достаточно лишь копиро-
вать отдельные участки текста.

7.3.3. Меню
Меню - один из краеугольных камней идеологии УЛпдо\$. Похожие друг на
друга меню разрешают пользоваться абсолютно незнакомыми программами, не чи-
тая инструкций, и узнавать об их возможностях путем просмотра содержания раз-
личных пунктов меню. Попробуем добавить меню и в нашу программу \пдо\азт.
Первое, что нам нужно получить, — это само меню. Его, так же как и иконки,
диалоги и другая информация (вплоть до версии программы), записывают в фай-
лы ресурсов. Файл ресурсов имеет расширение *.В.С для текстового файла или
* ВЕЗ для бинарного файла, созданного специальным компилятором ресурсов
(ВС, ВВССЗ2 или \/КС). И те, и другие файлы ресурсов можно редактировать
особыми программами, входящими в дистрибутивы С/С++, или с помощью, дру-
гих средств разработки для \\Мп4о\, но мы не будем создавать слишком сложное
меню и напишем КС-файл вручную, например так:
// муптепи.гс
// Файл ресурсов для программы м1птепи. азм.

#деЁ1пе 277_ТЕЗТ 1
#4е1те 222_ОРЕН 2
вдеР1те 222_5А\Е 3
#4еЁ1пе 222_ЕХТ 4
777_Мепи МЕМО{ . Виж -
РОРУР “&Е11е” {. - |
МЕМЛТЕМ “&0реп“, 277_ОРЕМ
МЕМИТТЕМ “&бауе”, 727_ЗАУЕ ^. ,
МЕМИТТЕМ ЗЕРАВАТОВ.” |
МЕМИТТЕМ “Е&Ж4т”, 777_ЕХТ
}
МЕМИТТЕМ “&ЕЗ1т”, 272_ТЕЗТ

Чтобы добавить этот файл. в программу, его надоо скомпилировать и указать


имя *.КЕ$-файла для компоновщика: |
Е | Программирование для \Мт4о\м/$ 95/мТ. |
ЕРЕИШИШИИЕНИИ
МАЗМ: .
м1 /с /сотЕ. /Ср м1птепи.
азт
гс /г м1птепи.гс
1иК. м1пмепи. 06] м1птепи.
гез /зибзузТет:м1п40м$

ТА$М: ,
Тазт /х /м /т1 /0_ТАЗМ_ м1птепи.
азт \ р
6гсс32 м1птели.гез .
1111К32 /Тре /аа /с и1птепи.о6},,,,
‚м1птепи. гез

УУА$М:
мазм м1птепи.азт
гс /г /БТ=ПЕ итатепи.гс
ге Гогт
м11пк 111е и1птепи.о5] гез и1птепи. м1пд0мз пФ ор с \

А теперь сам текст программы. Чтобы показать, как мало требуется внести
изменений в программу \п4о\.азт, комментарии для всех строк, перенесенных
оттуда без поправок, заменены символом *.
; у1имепи, азм
, Графическое м1п32-приложение, демонстрирующее работу с меню.
’ Звездочками отмечены строки, скопированные из файла ч1п4о\м. азт.
*
2272 ТЕЗТ еци 0 ; Сообщения от нашего меню
227 ОРЕМ еду. 1 ; должны совпадать с определениями из \м1птепи. гс.
227 _БАУЕ еци 2 ‹ Кроме того, в нашем примере- их номера важны,
И22_ЕХТ | еди 3 ; потому что они используются как индексы для
` : таблицы переходов к обработчикам.

1пс]1и4е 9е132.1пс о
1п61и4е Кегпе132.
1пс ;*
1пс1иде изег32. 1пс :я `
‚ 386 ‚*
.104е1 Тат ‚*
. дата ;*
с]азз. пате 96 “иЧпаом с1азз 1”,0 :*.
м1 пдом_пате 6 "и1п32 аззетб]у ехатр?е”,0 ;* 1
тмепи_пате ЧБ "227 _Мепи", 0 ; Имя меню в файле ресурсов. |
те$1_тз9 6 "Уои зе1естед мепи 11ет ТЕЗТ”,0 ; Строки для |
ореп_тз9 ЧБ “Усуи зе1есте мепи 1{еш ОРЕМ",0 —; демонстрации работы :
зауе_1$9 [ее] “Уои зе1естед мепи 14ет ЗАУЕ",0 ; меню. |
мс ИМОСЕАЗЗЕХ <4»12,С5$_НВЕОНАМ ог С$_МУВЕОВАИ, оГРзеЕ м1п_ргос,0,0,2,7,7,\
0, оРзет с1азз_пате,0> ;*
СОГОВ_МТМООМ-Т,
„Вата? ‚*
1$9_ мб <7,2,?,?,?,?> ; .
. соде ‚*
_зтагт: у
хог еБх, ебх ;*
ризв еьх ;*
са11 бетмоди1еНапа1е я | .
оу ез1, еах К |
тоу амога р\г мс. АТлзтапсе, еах ;*
з

О
ризй ТОГ_АРРЕТСАТТОМ ‚*
ризв ебх .*
са} 1 тоад1соп ;*
то\ мс. Тсоп, еах о:
ризй ° ТОС_АВАОМ ;* `
ризп е5х у .*
са11 | оаабитзог я
оу мс. ПСигзог, вах 1.
рип оРРзее мс соя
са11 Вед1зтегС1аззЕх ;=

отЕзет мепи_паме ; Имя меню. |


ризй
е$1 . °_; Наш идентификатор.
ризп
са] 1 | оадМепы . . : Загрузить меню из’ ресурсов.
мо есх. Си УЗЕОЕРАИТ ;*
ебх :*
ризй
ризП е51 | *
: ; Идентификатор меню или окна-потомка.
рип еах
— е5х : .* `
ризй
. 1* - р
рузй есх
ризи есх : р
, ризй есх ;*
_ рузй есх .° И | р =
ризй \$_ОМЕВЕАРРЕВИТМООМ :*
‚ ризв оЁЕзеё м1пдом_пате :*
_ ризй отРзет с1азз_паме ;*
ризп еБх о я
са11 Сгеатей1пдомЕх ;*
ризв еах ;*
ризй $М_ЗНОММОВМАЕ ‚*
ризй еах ;*
са11 ° бпом пом .*
са11 Урдатемтаом - ;*
тоу е41, оЕЁзеф пзд_ ;*
меззаде_1оор: в ;*
ризй ебх ;*
ризй ех . : ;*
ризй еБх ВЫ
ризй е1. . 5. . *
са11 ° бе{Мевзаде- г ‚*
тех еах, еах а ;*.
37 ех1{_тз9_1о0р д*
ризп ©е91 ` - ‚я
са11 Тгапз] атемеззаде ` ;*
ризв е91 ;*
са11 01 зратспМеззаде ;*
3тр `зпогт теззаде_1оор ;*
ех1{_тз9_100р: ;*
ризй ебх ;*
са1 1 Ех1Ргосе$$ 1
ЕЕТОИШШШИИНИННИИ\ Программирование для МИпдомуз 95 /МТ
; Процедура м1п_ргос. а
; Вызывается окном каждый раз, когда оно получает какое-нибудь сообщение,
; Именно здесь будет происходить вся работа программы.
м
з
,
; Процедура не должна изменять регист
.ЕВР, ры
ЕБТ, ЕЗТ и ЕВХ!
м1п_ргос. ргос :*
ризй ° @Бр ^ | :
оу еБр, езр ;*
ир_И\пв еду дмога рег: {е5р+088] ;*
мр_иМз0 еди @мога рег `[ебр+0бн] ‚*
`ир_мРагат еци @ога рфг [ебр+10н] ° ;*
мр_1Рагат еди дмогд руг’ [ебр+141] ;*
стр мр_иМ$9, ИМ_ОЕЗТАОУ ;*
ле пот мт_дезтгоу я
ризй 0 :*
са11 Роз{@и14Меззаде ;*
Лт Логф епамт_спеск — уж
пот_мт_дезтгоу:
стр. мр_иМ$9, М_СОММАМО ; Если мы получили ИМ_СОММАМО -
те по мм_соттапа ; это от нашего меню
Дей еах, мр_мРагат ; и в мРагам лежит наше подсообщение,
тр _ @могд рег тепи_вап91егз(еах»4] ; Косвенный переход
; (в 32-битном режиме можно осуществлять переход по любому регистру). н
щ
о

мели_Палд]ег$ 94 оЁРзеф тепи_тезт, оГРзет мепи_ореп й


`94 ОРРзет мепи_зауе, оРГРзет мепи_ех1+
; Обработчики событий тезф, ореп и заме выводят МеззадеВох.
; Обработчик ех1Т выходит из программы.
тепи_Тезт:
° МОУ. еах, оРРзет тезт_тз9 ; Сообщение для МеззадеВох.
тр ЭЗПОГЕ $ПОмМ_м89 `
мепи_ореп:
, вом еах, оРРзет ореп_тз9 ; Сообщение для МеззадеВох.
тр ПОГ ЗНом_т$9
тмепи_зауе:
| поу еах, оГРзе{т зауе_т$9 ; Сообщение для МеззадеВох.
ЗПо\_1$0 :
ризй МВ_ОК ; Стиль для МеззадеВох.
ризв оРЁ5ет тепи_пате ; Заголовок.
ризв еах; - .`; Сообщение.
ризН мр_ПИпа ; Идентификатор окна-яредка.
са11. МеззадеВох ‚ Вызов функции.
тр ЗПогЕ епд_мт_спеск >; Выход из м1п_ргос.
пепи_ех1т: Ср бели выбрали пункт ЕХГ,
ризй мр_ПИпа
са11 Безтгоум\ пасом | ; Уничтожить наше окно:
епа_мт_свеск:
1еауе
хог еах, еах ‚ Вернуть 0 как результат работы процедуры.
гет 16 ;* . : |
Графические приложения = = ^^ ОА ООН
; поф_ми_соттала, чтобы избавиться от лишнего зтр.
пот_мт_соммала:
]еауе .* р
‚. М беРи1пдомРгос ‚*
м1п_ргос епбр :*
= ° епд _зтагт :»
сама программа,
Итак, из 120 строк программы новыми оказались всего 36, а
м выглядит
с точки зрения пользователя, стала намного сложнее. Таким образо
написанная раз
программирование под \Лп4о\з на ассемблере —‹ берется одна
пишутся обработ-
и навсегда шаблонная программа, модифицируются ресурсы и
программирова-
чики для различных событий меню и диалогов. Фактически все
именно в этих процед урах-о бработ чиках.
ние оказывается сосредоточенным
аются незна-
Добавления к включаемым файлам в этом примере тоже оказыв
чительными по сравнению с у\а4до\'азт.
32 пс между Нае! __ТАЗМ_ и е|зе:
В изег
ехтгп_ |оадМепиА:пеаг |
’ ежгя Оезтгоум пом: пеаг й ь
| оадМепи еди Е оадМепиА
и между е1е и епа!: |
ехугп __4тр__КоадМепиАе8 : мо га
__1пр__ Безтгоумпдо\@4 :нога я
| ехЕ гп
[оадмепи еду __1тр__ГоадМепиАе8
Безтгоу\1 дом еди __+тр__безтгоу\1140%@8

ив 4е{324пс: .
_; Из и1пизег.п, . |
ММ_СОММАМО еду 1118
мВ_ОК еду 0
7.3.4. Диалоги
чиваются од-
Графические программы для УЛпдо\з почти никогда`не ограни
ввести реальн ую инфор мацию - только
ним меню, потому что оно не позволяет
. Конечн о, в цикле после СеМез заве
выбрать какой-либо пункт из предложенных
я передв ижения мыши и нажати я
или РееКМеззаре можно обрабатывать событи
ммах, наприм ер в играх, но если
клавиш, и так делают в интерактивных програ
ь файл на диске
требуется ввести текст и в дальнейшем его редактировать, выбрат
мации в програ ммах для УЛиадом ока-
ит. п. то основным средством ввода инфор
зываются диалоги.
но если меню легко
Диалог описывается, также каки меню, в файле ресурсов,
пользоваться каким-
написать вручную, то ради диалогов, скорее всего, придется
любим ым компилятором, при
нибудь редактором, идущим в комплекте с вашим
по каким коорди натам располага-
условии, конечно, что вы не знаете в точности,
ется каждый контрол (активный элемент диалога). _

// м1т919.гс . ь
я в: программе м1п919.а5м.
// Файл ресурсов, описывающий. диалог, который ‘используетс
можно заменить на #1пс1иае` <иализег.в>, если он есть.
// Все следующие определения

`
|| Программирование для МИпдомиз 95/МТ
// стили для диалогов.
#де1те 0$. СЕМТЕВ 0х0800
8де1пе 0$_МОВАГЕВАМЕ Ох80Е
#4е1пе 0$_30400К 0х00041.
// Стили для окон. .
#деР1пе и$_МТАТМТЕЕВОХ 0х000200001.
вде1пе №$_ЗУЗМЕМИ 0х00080000.
ндег1пе и$_УТЗТВЕЕ 0х100000001.
иде1пе №5_ОМЕНЕАРРЕВ 0х00000000Е.
Нае1пе №5 САРТТОМ 0хС00000. '
// Стили для редактора.
#9е71пе ЕЗ_АЦТОНУСАОН. — 0х801.
#9е1пе ЕЗ_ЁЕЕТ 0

#ае1пе 20Е6_МЕМИТ
// Идентификаторы контролов диалога. . йе
#9еЁ1пе ТОС_ЕОТТ 0
#0е71пе ТОС_ВУТТОМ 1
#9еНте 100_ЕХИ 2
Р
И
// Идентификаторы пунктов меню.
#4ее1пе ТОМ_СЕТТЕХТ 10
#9е1пе ТОМ_СЬЕАВ11 | `
#4ет1пе ТОМ_ЕХТ 12

277 _01а109 01А(06 10,10,205, 30 // х, у, ширина, выбота.


ЗТУЕЕ 0$_СЕМТЕН | 0$_МОБАТЕВАМЕ | 0$_30400К | М$_САРТТОМ | и$_ МТМТМТРЕВОХ |
\5_бУЗМЕМИ | М$_УТЭТВЕЕ | №$_ОМЕВЬАРРЕО
САРТТОМ “м1п32 аззетЬ1у 41а109 ехатр1е” // Заголовок.
МЕМО 20Е6_МЕМУ // Меню.
ВЕСТК // Начало списка контролов.
ЕОТТТЕХТ ТОС_ЕБП, 15, 7, 111, 13, ЕЗ_АОТОНЗСВОЕ. | ЕЗ_ГЕРТ
РУЗНВУТТОМ _ "Е8х1е”,, ТОС_ЕХП, 141, 8,52, 13
ЕКО . | ,
201.6_МЕМУ. МЕМИ // Меню.
ВЕСТМ
‚ РОРИР “Тезт”
ВЕСТМ
МЕМОТТЕМ “бет. Техг”, ТОМ_бЕТТЕХТ
МЕМИТТЕМ “С1еаг Техт”, 1ОМ_СТЕАВ
МЕМИТТЕМ ЗЕРАВАТОЯ
МЕМИТТЕМ “Е&хут”, ТОМ_ЕХТТ
ЕМО
ЕМО

На простом примере покажем, как можно применять диалог, даже не регист-


рируя нового класса. Для этого надо создать диалог командой СгеабеГаов или
одним из ее вариантов, не конфигурируя никакого окна-предка. Все сообщения
от диалога и окон, которые он создает, будут посылаться в процедуру-обработчик
_ типа ОуаюеРгос, аналогичную \УЛр4о%жРгос.
Графические приложения
; м11919. аз :
; Графическое 1132 приложение, демонстрирующее работу с диалогом:
; Идентификаторы контролов (элементов диалога}.
ТОС_Е01Т ед 0
ТОС_ВИТТОМ ед 1
106. ЕХТТ веди 2
; Идентификаторы элементов меню.
ТОМ_ВЕТТЕХТ еди 10
ТОМ_СЕЕАЯ еди 11
ТОМ_ЕХТ еци 12

1пс}иде де{32. 1пс


1пс1и4е Кегле132. 1пс
1п6]иде ивег32. 1пс

.386
‚моде: Т1ат
„Фата
91а109_паме Г) "777 _01а109",0 ‚ Имя диалога в ресурсах.
‚ Фата? ` .
Биетег 95 ‚ 512 @ир(?) ; Буфер для введенного текста.
.соде |
_$Тагт: : .
хог ебх, е5х — $ В ЕВХ будет 0 для команд ризп` 0
. ; (короче в 2 раза).
; Определить идентификатор. нашей программы.
ризй еБх
са11 бетМоди]еНапа1е
; Запустить диалог.
ризй еБх ; Значение, которое перейдет как параметр ММ_ТМТТОТАЕОС.
ризй оЁЕзет „.91а109_ргос ; Адрес процедуры типа О3а1одРгос.
ризв ебх ; Идентификатор окна-предка. (0 - ничей. диалог).
ризп оЕРзет 91а100_пате ; Адрес имени диалога в ресурсах.
ризв еах :; Идентификатор программы, в ресурсах которой .
; находится диалог (наш идентификатор в ЕАХ)..
са11 01а] 0о9ВохРагам
; Выход из программы.
ризп ебх
са11 Еж {Ргосе$$

; Процедура 41а109_ ргос. ‚


; Вызывается диалогом каждый раз, когда в нем. что-нибудь проиохедит.
‚; Именно здесь будет происходить вся работа программы.

; Процедура не должна изменять регистры ЕВР, ЕТ, ЕЗТ и ЕВХ!


74

912109 ргос ’ ре пеаг`’” п’


. Так как мы’ получёем. параметры в’ стеке, повтроим стековый: кадр.
ебр и
‚ризи
моу ебр, езр
И Программирование. для МУтаоми$ 95/МТ |
; Процедура типа О4а1одРгос вызывается со следующими параметрами:
бр_МИпа еди @могд ртг [ебр+о8н]. ; идентификатор диалога,
др_иМ$9 еди нога рег [е5р+0Сн] : номер сообщения,
Фр_мРагат еди дмогЯ руг [е6р+1011] ‚ первый параметр,
вр_1Рагат еди дмогд- рег [е5р+14н] ; второй параметр.
ту - есх, др_Н\па ; ЕСХ будет хранить идентификатор диалога,
моу вах, Чр_иМ$9 ; а ЕАХ - номер сообщения.
стр вах, ИМ_ТМТТОТА!
06 ‚ Если мы получили ИМ_ТМТТОТАЕОС,
ле пот_1п1101а109
ризп ТЬС_ЕБТТ
ризв Чр_И\пд
са11 бет
01 0Ттет ; определить идентификатор
ризй вах ‚ окна редактирования‘ текста.
са11 ЗетРосиз ‚; и передать ему фокус.
по{_1п1141а109;
стр еах, ММ_С105Е ; Если мы получили ИМ_СГОЗЕ,
ме пот с103е `
ризв 0
ризН есх
са11 - Еп901а109 ‚; закрыть диалог
по{_с103е:
стр «ах, ИМ_СОММАКО ; Если мы получили ИМ_СОММАМО,
те пот_соммапд
тоу еах, Чр_мРагат ; ЕАХ = мРагам (номер сообщения) ..
стр др_1Рагат, 0 ; Если Трагат ноль - сообщение от. меню.
- ]пе ]1Рагат- по{_0
стр ах, ТОМ_бЕТТЕХТ ;. Если это пункт меню бее Тех+.
пе пот деттехт
ризп 512 -; Размер буфера.
`ризН. ОЕРз6 БиРРег ; Адрес буфера. —.
ризй ТОС_ЕТТ ; Номер контрола редактирования.
ризп есх
са11 бет0191тетТехт ; Считать текст в буфер
„ . ризв МВ_ОК
ризй ОТР3е{. 91а109_пате
ризН ОРЁзеф БиуРРег
рузП др_ВИпа
са1] —` МеззадеВох .; И показать его в МеззадеВох. ер
за
во

пот_деттехт:
стр еах, 1ОМ_СТЕАН ; Если это пункт меню’ б1ваг:
пе пот с1еаг
ризН 0 м. й | | |
ризв ` 1ОС_ЕМТ ‚ Номер контрола. .
ризй есх
са11 $е10191ТемТехе __; Установить новый текст,
т О
пот сТеаг-
сир вах, ТОМ_ЕХТТ ; Если это’ пункт меню Ехо: ..
]пе ‚потехе
ризй 0 ‚ код возврата.
ризв есх. Идентификатор диалога. ^
са11 Еп001а109 Закрыть диалог, | .
1Рагат_по*_0: - ФРагат не ноль’ - сообщение. от контрола.
сир еах, ТОС_ЕХЛТ - Если
4.жеж сообщение`от кнопки ЕхТ.
_ пе пот_ех1т'
зпг ‚ вах, 16 |
сир еах, ВМ_СЕТСКЕВ =; Если ее нажали:
ризй 0. ‚.. + Юд возврата.
ризп есх (о ; Идентификатор диалога.
са} 1 Еп301а309 ; Закрыть диалог.
пот_ех1т: |
хог еах, вах ; "После обработки команды
1пс вах‘ ‚ О1афодРгос должен возвращать ТВУЕ (еах = 1).
]еауе .
гет . 16 ; Конец процедуры.
пот _соттапа: : Сюда передается управление, если мы получили
В .; какое-то незнакомое сообщение,
хог вах, еах : Код возврата ЕАЁЗЕ (еах =.0).,
]еауе ,
гет 16 у : Конец процедуры.
91а100_ргос епар |
епб _зтагт

Добавления в наш изег32.1лс.


Между ИЧе! _ТА$М_ ие!зе:
ежгп — 01а1одВохРагатА: пеаг
ехтгп — 6е10169ет: пеаг
ехгп — 5е1Росиз: пеаг
ех{го. 6е1010/4етТехтА:пеаг `
ех{гп — 501019 1етТехтА: пеаг
ех{гп Еп901а109: пеаг
01а] одВохРагат еди 01а} одВохРагатА
бе10191тетТех{ — еди бет0191теютТехтА
. $21019 {еяТехт — еди 5е10191тетТех{А

Между ее и еп
еххгт — _ 1ир__О1а1о9ВохРагамА@20 :дога
ег — _ 1тр__ 6е101911ет@8 : диогд
и ехфгп __фар__ЗетРосиз@4 :дога
ехтгп __1р.-бет019Т<етТехтА@16 :быо га
ехугп __{тр__$е10191<етТех{А@12 :дога
ег = __Змр__Еп901а1096@8 : @ногв
О1а1одВохРагая еди __ир__О+а1одВохРагамА@20
6е1010 тет еди __1тр__661019Пете8
ЗетРоси$ еди ` _1тр__$е1Росиз@4
бет019ТтемТехЕ — еаи __1тр__бет019хемТех{А@16
$е1019{ейТехх еду. __ тр. _Зер19Т{етТехтАв12
Еп901а109 еди __1ер__Е1904а10988
Добавления к файлу Че З24пс:
; Из мтлизег.п.
ИМ ТМГТОТАЦОб о еди 1108.
” | Программирование:
для МИпаомиз 95 ИМТ .
УМ_С10Е еди 10в
ВМ СИТСКЕЮ —- ви 0
7.3.5. Полноценное приложение
Теперь, когда мы знаем, как строятся программы с меню и диалогами, попро-
буем написать настоящее полноценное приложение, включающее в себя все то, что
требуется от программы, - меню, диалоги, комбинации клавиш для быстрого до-
ступа к элементам меню и т. д. В качестве примера создадим простой текстовый
редактор, аналогичный Мо(ерач. В этом примере увидим, как получить параметры
из ‘командной строки, прочитать и записать файл, выделить и освободить память.
// м1праад95.
гс
// Файл ресурсов для программы м1прад95. азт.

// Идентификаторы сообщений от пунктов меню.


#9е1пе ТОМ_МЕМ 0%1001
#9е1пе ТОМ ОРЕМ. 090х101 .. \
_ #ЧеР1пе ТОМ_ЗАУЕ 0х1021
#9е1пе ТОМ_ЗАУЕАЗ 0х403Е
#4е1пе ТОМ_ЕХШТ 0х1041
#ЧеЁ1пе ТОМ АВОИТ 0х105%
#ЧеР1те ТОМ_0№00 . . 0х1061.
#деЁ1пте ТОМ СИТ 0х107Е°,
#4еЕ1пе ТОМ_СОРУ 0х1081
#9е1пе ТОМ_РАЗТЕ 090х109
#4ет1пе ТОМ_СЕЕАВ | О0х10АЕ
#ЧеР1пе ТОМ_ЗЕТЗЕЕ 0х10в _
// Идентификаторы основных ресурсов.
&9е1те 10 МЕМУ 0х700Е
#4еЁ1пе 10_АССЕЕ 0х701Е
#ЧеГ1пе ТО_АВОПТ . 0х7021.
// Если есть иконка — можно раскомментировать эти две строки:
.// ваеете ТО_ТСОм 0х7031
// ТО ТСО ТСО “\1прад95. 1с0”

// Основное меню.
ТО МЕМУ МЕМУ ОТЗСАВОАВЕЕ {
РОРИР “"8Е11е”. { .
МЕМОТТЕМ “&Мем\&Стг1+№“, : ТОМ_МЕМ
МЕМИТТЕМ “&0реп...\1Схг1+0”", ТОМ_ОРЕМ
МЕМИТТЕМ "вбаме\тСтг1+5", ТОМ. ЗАМЕ
МЕМИТТЕМ “бауе &А$...\1С1г1+$111+5”. ТОМ_ЗАМЕА$ .
` МЕМУТТЕМ ЗЕРАВАТОН
МЕМИТТЕМ “Е&х1Е\4Стг1+0”, ТОМ_ЕХТТ
}.
РОРУР “ЕТ” {
МЕМИТТЕМ "вИпао\{Стг1-2”,. Том_им№00
МЕМИТТЕМ ЗЕРАВАТОВ |
Графические приложения _
МЕМИТТЕМ “Суё\хСтг1-Х", ТОМ_СИТ
МЕМАТЕМ “&Сору\хСтг1-С", ТОМ_СОРУ
МЕМИРТЕМ “&Разте\тСиг1-\М", ТОМ_РАЗТЕ
МЕМОТТЕМ “&0е1ете\\0е1”, ТОМ _СЬЕАЯ
МЕМИТТЕМ ЗЕРАВАТОВ
МЕМЛТЕМ “Зе1ест &А11\1С1г1-А”; ТОМ_ЗЕТЗЕЕ
}
РОРУР “&Не1р“ { |
МЕМИТЕМ “АБоцт”, ТОМ_АВОУТ
}
}
// Комбинации клавин,
ТО_АССЕЕ. АССЕСЕВАТОН$ -ОТЗСАВОАВЕЕ {
^№", ТОМ МЕН, СОМТАОЕ, УТВТКЕУ
, ТОМ ОРЕМ, СОМТАОЕ, УТАТКЕУ
", ТОМ_ЗАМЕ, СОМТВОЕ, УТАТКЕУ
", ТОМ ЗАМЕАЗ, СОМТВОЕ, ЗНТЕТ, УТВТКЕУ
ТОМ_ЕХШТ, СОМТНОЕ, УТВТКЕУ
", 10М №00, СОМТАОЕ, УТАТКЕУ
хчоюфоо
“, ТОМ $ЕТЗЕЕ, СОМТАОЕ, УТАТКЕУ
}
// Все эти определения можно заменить 81пс1иде >.
<и1пузег.
{де 1пе 0$_МООБАЕРВАМЕ 0х801.
вдег+те 05_30400К 4
89ег1те И5_РОРУР 0х800000001
‘заеГ1пе И№$_САРТТОМ 0хС00000%
‚ ваегте №$_ЗУЗМЕМИ _ 0х8. . -
#9е1пе Т100К 1
в4ее1пе Т0С_$ТАТТС -1
зает1пе ТОТ_АРРЕТСАТТОМ 32512
ндеРлпе №$_ВОЯОЕЯ 0х8006001
// Стандартный диалог “Абоцт”.
10_АВОИТ ОТАЕОб ОТЗСАВОАВСЕ 0, 0, 125, 75
ЗТУЫЕ 0$_| МОБАТЕВАМЕ | 0$_30400К | М№$_РОРУР |\$_САРТТОМ | №5 _бУЗНЕМИ
САРТТОМ “АБоцт Азтрад95”
{
тон ТОТ_АРРЕТСАТТОН, ТОС_ЗТАТТС, 12, 15, 21,20
СТЕХТ “Азтра995“, Т0С_ЗТАТТС, 0,30,40,8
“Ргототуре потерад- зту1е ебутог` Тог И1пвомз 95 игИТеп,
СТЕХТ
еп1ге1у 1п аззеть1у 1апдцаде”“, ТОб_ ЗТАТТС, 45,10,70, 45, №5 _ВОЯОЕЯ
БЕРРУЗНВИТТОМ “ОК”, ТО0К, 35,60, 40, 10
} !

Далее рассмотрим текст программы.


; м1прад95. азт
; Графическое м1п32-приложение - текстовый редактор.
|| Программирование для МИпЧо\из 95/МТ |
1пс1ч4е 4е{32. 1пс
1пс]и4е изег32. 1пс
1пс]и9е Кегпе]32.
1пс №
‚1исрае сот91932.
1пс

ТО МЕМО еди 700н


ТО_АССЕЁ еди 7о1н
ТО_АВОИТ ° еду 7028

МАХЭТЕЕ еди 260 ‚ Максимальное имя файла.


МЕМУТРЕ еди 65535 ; Максимальный размер временного буфера в памяти.
ЕТО еди 1

.386
.тоде] Тат
‚ СОП5Т ; .
с_м_ пате 46 “Азтрад95”, 0 ; Это и имя класса, и имя основного окна.
©4911 _с1а$$ 5 “е911",0; Предопределенное имя класса.для редактора.
спапдез_п$9 ЧБ "бауе спапдез?”, 0 и
ЕЦег_31г119 65 “А Е11е3",0,'*+.»',0 ; Маски для бетжЕ1еМапе.
* 95 “Техе Е11е3”,0,'*.1х1’,0,0 Ио
.дата
; Структура, испбльзующаяся бет*Р11еМате. о
оп ОРЕМЕТЬЕМАМЕ <517Е о{п,?,?, оРРзер 111тег_$1г1п9д,?,?,2?,
оРРзефх БиЕРег,\
МАХЗТ2Е, 0,?,?,?,?,?,7,0,?,?,?>
; Структура, описывающая наш основной класс.
мс ИМОСЬАЗ$ЕХ <5Т2Е ММОСЬАЗЗЕХ, СЗ-НВЕОВАМ ог С$_УАЕБВАМ, оеТзе м1п_ргос,0, \
0,7,?,?, СОГОВ МТМООи+1, Т_МЕМИ, оРРзет с_м папе, 0>
Р]ад_ипт1 ед 96 `1; = 1, если имя файла не определено’ (новый файл).

. дата? .
п_едТи1пдом 94 ? ‚; Идентификатор окна редактора,
№_ассе1 93 ? ; Идентификатор массива акселераторов.
р_тетогу 04 ? ; Адрес буфера в памяти. <
$12еНеадиг11е 94 ? |
. 199_ №56 <>
гес ЯЕСТ <> :
БиеРег. 96 МАХЗТ2Е 9ир(?) —; Имя файла.
_ м1пдом_111]е 6 МАХОТЕЕ 4ир(?), 12 4ир(?)

‚ соде-
_зтаге: , ,
са11 бетСоттапа
пе —; Получить наву командную строку.
ту е01, еах ее
оу а1,’'
моу есх, МАХЭТ2Е | |
герпе. зсазь _; Найти конец имени нашей программы.
ср — Буе риг [е91],0 а
]е ст911пе_етрту .
тоу е31, 201 < В
МОУ е91., оРЁЕзеф БиЁРег

А
НЕ
м
Графические приложения
гер АЕ)
ЮУ +1а9_ипт11е9,0
ст911пе_етрту:
$ Подготовить и зарегистрировать класс.
хог ебх, ебх
са11 бетМоди1еНапа1е `. ; Определить наш идентификатор
му е51, еах
тоу мс. ПТпзТапсе,еах ^ ; и сохранить его в мс. ВТпзтапсе
пу оЁп. _ИТлзтапсе, еах |
ризв ТОГ АРРЕТСАТТОМ ; или ТОТ_ТСОН, если иконка есть в ресурсах,
о ебх : или ез$1, если иконка есть в ресурсах.
ризй
са11 ТюадТсоп
моу мс. НГсоп, еах.
‘ризи 10С_АВНОМ „: Предопределенный курсор (стрелка).
ризВ ебх
са11 1оадбигзог
тоу ис. ПСигэог, еах
ризв огРзет мс
са] Вео1тегС1аззЕх
; Создать основное окно.
ризи еБх
ризй е31 ` ,
ризН еБх
ризй е5х
рузв 200
ризй 300
ризп . СМ УЗЕБЕРААТ
ризй СМ. ОЗЕБЕРАУЕТ
, разв \З_ОМЕЯГАРРЕОМТМООМ
ризА отРзет с_м пате
ризй отЕзет с_м_паме
ризп ` МЗЕХ_СЕТЕНТЕОВЕ
са11 Сгеате\пдомЕх
рузв еах | ; "Для рор ез1 перед меззаде_1оор.
рузп еах | ‹
рии $М_ЭНОИМОВМАЕ
ризй еах
са] Эпом\ 1пдом
са11 Урдатем1 пом
; Инициализировать акселераторы.
рии 10 АССЕЕ
. ризй 231 ..
са11 |оадАссе1егатог$
моу н_ассе],еах ^
; Цикл ожидания сообщения. .
рор 951 ; ЕЗТ - идентификатор основного окна.
е91, оРРзет т$9_ ; ЕСТ - структура с ‘сообщением от него.
воу
тмеззаде_1оор: . у и
ризй е5х
ризй ебх
| ТИ Программирование для МИп4оми$ 95./МТ
ризп еьх
ризН е91
са11 ‘ бе{Меззаде ; Получить сообщение.
тез+ еах, еах ; Если это ИМ_ОУТТ,
32 ех11_тз9_1оор ; выйти из цикла.°
ризВ е91
ризй н_ассе1
рузв е51 ‚ Мпа
са1]1 — Тгапз1атеАссе]егахог ; Преобразовать акселераторы в ТОМ»
тез1 еах, еах
12 меззаде_1оор
ризй е91 а
ав
аво
орать
са} ] Тгапз]атеМмеззаде ; Преобразовать сообщения от клавиш
ризИ е91
са11 О15рахспМеззаде ; и отправить обратно.
Эр зпогЕ меззаде_Тоор
ех1т_т39_100р:
ризй 159_. мРагат
са11 ЕхИРгосез$ ‚ Конец программы.

; Процедура“ м1п_ргос.

; Процедура не должна изменять регистры ЕВР, ЕБТ, ЕЗТ и ЕВХ!


и1п_ргос ргос пеаг
; Параметры (с учетом ризй еБр).
мр_И\Мпа еди Чмога рег [ебр+088]
- мр_9Мз9 еди дмога рег [ебр+0Св]
мр_мРагам еци дмог@ рфг [ебр+108] -
ир_1Рагам еди Фмог9 руг [еБр+14в]
; Инициализируем стековый кадр.
риэН ебр
моу ебр, езр ; Создать стековый кадр.
ризпа ; Сохранить все регистры.
хог ебх,ебх ; 0 для команд ризй 0.
оу — е$1, мр_И\ па ; Для команд ‘ризй ПВМпа.
тоу вах, мр_иМз9
; Обработать пришедшее сообщение.
стр, еах, ИМ_СВЕАТЕ
3е №_мт_сгеате
стр еах, ИМ_517Е
де № мм_$12е
стр еах,ИМ_ОЕЗТВОУ
]е й_мт_Чезтгоу
стр еах, ММ СОММАМО
де п_мт_соттапа
стр еах, ММ_АСТТУАТЕ
де |_мт_аст1уате
стр еах, ММ_С105Е
Зе ‚ В.мт_с10$е
Графические. приложения
ЧеЁ_ргос:
рора . . .
1еауе а ‚. Если это ненужное сообщение,
Зар бе пдомРгос. ^^ - ; оставить его обработчику по умолчанию.

: Обработчик ИМ СГОЗЕ.
‚; Если нужно, спрашивает, сохранить ли. файл;
|_мт_с]05е:
са11 заме_соптеп{$
тр зпог{ деГг_ргос
; Обработчик ММ_СВЕАТЕ.
В_ми_сгеае:
; Здесь также можно создать +0016аг и зфатизВаг.
; Создать окно. редактора’.
ризВ еБх . | | ,
ризи мс.НТазтапсе ; Идентификатор основной программы.
ризй ЕТО
рызй е$1 ‚ П\пд
ризВ еБх ° : 0
‚ ризй ебх ; 0
ризв ебх | | :0
ру$П ебх : 2:0
риузй М5 УТЗТВЕЕ ог №$_СНТЬО ог ЕЗ_ЦЕЕТ ог ЕЗ_МУАСТИТМЕ ог\
ЕЗ_АИТОНУСНОЕ: ог Еб_АЦТОМЗСВОЕН
ризй еБх ;: 0
ризй ОТЕзет е01{_с1аз$ .
рип ебх : ; 0
са11 Сгеатем1 пдомЕх
поу |_е911и1п9дом, еах
‚ Передать ему фокус.
ризп еах
са11 ЗетРосиз
стр ад. ип {1е9, 1
]е соп{1пие_сгеате ,
са]11 зК1р_детореп ; Открыть файл, указанный. в командной строке.
соп1пие_сгеате:
са] зет_11е
тр епд_мт_спеск

; Обработчик ММ_СОММАЮО.

В_мт_соттапа:
том еах, ир_мРагат |
сжде $ Младшее слово содержит: ТОМ_.*.
ЫИ: еах, 1008
| 5 дег_ргос
; Обработать сообщения от пунктов. меню.
са11 Чиог@ руг мепи_папд1егз[еах»4]
Этр епд_мт_спеск
А

1! Программирование для Мио 95 мт


мепи_Папд1ег$
99 оРЁзет П_19т_пем, о7Рзет Н_19т_ореп, оЕРзеф п_19т_зауе
99 ОЕЁРзет |_19т_зауеаз, оРРзет в_19т_ех1{, оРРзет п_19т_арои*
93 ответ Н_19т_ипдо, ответ Н_19_сиф, оТРзет п_19т_сору
99. оРЕзет П_19т_разфе, оРЁзеф №_1дт_с]еаг, оТРзег п_1дт_зет$е1
: Сообщения от пунктов меню должны быть описаны в и1п95рад.гс именно в таком
; порядке - от ТОМ_МЕМ 1008 до ТОМ_СЕЕАВ 10АВ.

|_19т_5е15е1:
ризВ -1 ‚ -1
ризй ебх ; 0
ризй ЕМ_ЗЕТЗЕЕ ‚ Выделить весь текст.
рузп п_е91
{м1 п90м
са11 ЗепдМеззаде
гет

; Обработчики сообщений из меню ЕБТ:


п_1ат_стеаг:
оу еах, ММ_СТЕАЯ
дир логе зепа_То_ед1ог
В_19т_разте:
. ОУ „ еах, ИМ_РАЗТЕ
Зир ЗПогт зепд_То_еа1Тог
№_19_сору:
поу еах, ММ_СОРУ
< р ЗПогт зепа_то_ед1Тог
п_19_сиЕ:
моу еах,
ИМ СИТ
- Эр ` ЗПогЕ зепд_То_е@1
ог
п_19т. ипдо:
поу еах, ЕМ_0№00
зепа_1о_едтог:
риузН ебх :
ризй ебх
ризй еах
ризв В_е911и1пдом
са11 ЗепаМеззаде
ге

; Обработчик ТОМ_ МЕМ.


В_19т_пем:
са11 зауе_соптепез ‚ Записать файл, если нужно.
в Буте рфг 11ад_ипт11еа, 1
са11 зет_1111е ; Отметить, что файл не назван.°.
ризй ебх
ризй ебх
ризН ММ ЗЕТТЕХТ
ризй В_е91
м1 пдом
са11 Зеп4Меззаде ; Послать пустой ИМ_ЗЕТТЕХТ редактору. '
гет.
/
\

Графические-приложения
; Обработчик ТОМ_АВОМТ: у . И
|_19т_абоц*: .
ризй ебх ;0
ризв — оЁРзеф абоит_ргос ‚
ризв 251. ; Мпа
ризп 10 АВОЦТ
ризй мс. АТпзтапсе
са]1 01а1098охРагат
- те ,

; Обработчик ТОМ_ЗАМЕАЗ и `ТОМ_АУЕ. `


Н_1дт_зауе: |
стр 1]а9_ип{1е9,1 ; Если файл’ назван,
пе $К1р_детзауе ; пропустить вызов бетбауеР11еМаме.
п_19т_зауеаз: . | р
‚ Узнать имя файла.
оу ` огл. Е1а0$, ОРМ_ЕХРЕОАЕЯ ог ОРМ_ОМЕВМАТТЕРАОМРТ
ризй оРГзет оп . `
са11 бетбамеР11еМате _
- е5т еах, еах
3: {11е_зауе_Ёа11е4
эК1р_детзауе:
; Создать его.
ри ебх .
ризн ЕТЬЕ_АТТАТВУТЕ_АВСНТУЕ
ризй СНЕАТЕ_АЕМАУЗ
ризв ебх
рип ЕЛЕЕ_ЗНАВЕ АЕАО ог ЕТЬЕ ЗНАВЕ_ МАТТЕ
рии бЕМЕВТС_ВЕАО ог СЕМЕВТС МВТТЕ
‚ ризп — оРРзет БиРРег
са] СгеатеЕ1]е
тоу е91, еах
‚ Выделить ‘память.
ризВ МЕМЗТ7Е
ризй ‚ ВСМЕМ_МОМЕАВЕЕ ог СМЕМ_7ЕВОТМТТ
са11 6305а1А110с
ризй еах ; ИМетогу для С1оба1Егее.
ризн еах -. ; ВМетогу для б1оБаоск.
са 1 б1оБа1 (оск
мо\ ез1, еах ; Адрес буфера в ЕЗТ.
; Забрать текст из редактора. °
ризй е$1
ризп. МЕМЗТ2Е-1
ризн ИМ_СЕТТЕХТ
ризв В_е61 м1 пдом
са11 ЗепаМеззаде
; Записать в файл. о `
ы ризН е51 _ _; рМетогу
са11 15{г1еп
ризн ебх
| Программирование для МИпЧо\му;
‘95 /МТ й
ризй оТГзет $12еВеадиг
Ме
ризй еах ; Размер буфера.
ризй е51 ‚ Адрес буфера.
ризй е91 ° ; Идентификатор файла.
са]1 - Иг1 Те 1] е
ризв ез1. ; рМетогу
са11 610Ба1/п1оск ”
са11 61оБа]Егее ‚ ИМетогу уже в стеке.
ризй е01 ; Идентификатор файла.
са] 1 С1озеНапа1е
; Сбросить флаг модификации в редакторе.
ризН еъх
ризв ебх
ризв ЕМ_ЗЕТМООТЕУ
изн п_е 911 дом
са11 ЗепдМеззаде
мом буфе рфг 11а9_ип{11еа, 0
са11 зет_1111е
1] е_зауе_а11е9: у
ризй в_ед1 ит пом
са11 ЗетРоси$
гет *

‚ Обработчик ТОМ_ОРЕМ,
й_19_ореп:
са11 зауе_соптепт$
‚ Вызвать стандартный диалог выбора имени файла. ;
ОУ оп.
Е]адз, ОРМ_РТТЕМУЗТЕХТ$Т ог ОЕРМ_РАТНМОЗТЕХТЬТ ог\,
ОЕМ_ЕХРЕОВЕВ
ризв оЁРзет оп
‚ са11 бет0репЕ11еМате
тет еах, еах
1]2 {11 е_ореп_Ра1]е9
$КТр. детореп:
; Открыть выбранный файл.
ризп ебх
ризп . ЕТЬЕ АТТАТВИТЕ_АНСНТУЕ
ри$Н ОРЕМ_ЕХТЗЬТТК@
'риузв ебх .
ризй ЕТЕ ЗНАВЕ_ВЕАО ог ЕТЬЕ _ЗНАЯЕ_МВТТЕ
ризй СЕМЕНТС_ВЕАО ог СЕМЕАТС_МВТТЕ
ризй ОЕЕзее БиРЕег |
са11 Сгеафе[11е _,
поу е91, еах ; Идентификатор для НеадЕ11е.
; Выделить память.
ризп. МЕМЗТЕ `
ризв СМЕМ_МОМЕАВЕЕ ог СМЕМ_2ЕВОТМТТ
с811 6106а1А1106
# . ризп еах ‚ НМетогу для б?оБа1Ёгее.
ризй еах ; ИМетогу для’ б1оБа1Щоск.
Графические приложения ..::
са} 6] оба1Ёоск ; Получить адрес выделенной памяти.
ризв еах ; рМетогу для б1обаТИп1оск.
ризв еах ‚ рМетогу для ЗепаМеззаде.
: Прочитать файл. |
о ризв еъх
ризН от5ет 512ейеадие1те
ризй МЕМЗТ2Е-1 . `
рип вах ; рМетогу для ВеадЕ11е.
ризН ед1
са] ВеадЕ1е Г
; Послать окну редактора сообщение мт_зеех{ о том,
; что нужно забрать текст из буфера. _ у
рузп е5х ; рМетогу уже в стеке.
ризв ИМ_ЗЕТТЕХТ '
ризй В_е94 {ма пом
са11 ЗепаМеззаде
; А теперь можно закрыть файл и освободить память.
са]11 61оБа1/п1оск ; рМетогу уже в стеке.
са] 1 61оБа1Егее ; НМетогу уже в стеке.
ризв е41 ИЕ,
са11 С1озеНап1е В
моу Буте ртг Г1ад_ипт1{1ед,0
са11 зет_1141е
Е е_ореп_Га1]ед:
ризй В_ ©9111 пом
са11 ЗетРосиз ^
гет

; Обработчик ТОМ_ЕЖТ. | `
п_19т_ех{:
са]] заме_соптепт$
ризн е31 ; ВМпа
са1} Безтгоуй1паом ; Уничтожить наше окно.
гет

‚ Обработчик ММ_$12Е.
| мм_$17е:
; Здесь Также надо послать ММ_$1ГЕ окнам Тоо]баг и зтафизБат, изменить размер окна
; редактора так, чтобы оно по-прежнему было максимального размера.
ризп оЁРзет гес
ризй ез1 > Мпа
са11 бетС11ептВесе
ризй 1 ‚ Тгие
ризй гес. Боттом = ; петовт.
ризй ‚гес. г1аНт ‚ м1аВ
ризй ех . ‚У
ризН еБх 5х
ризН Б_е91{1 пдом
са11 › Момемтдом
тр пог епб_мт_сНеск.
Ш! Программирование для МЛидоми 95/МТ
; Обработчик ИМ_АСТТМАТЕ. |

№_мт_аст1уате:
ризй П_е91 {1 п90м
са11 ЗетРосиуз
тр ЗПогф епд_мт_спеск

; Обработчик ММ_БЕЗТВОУ.

А_мт_дезтгоу:
‘рузй ебх
са]1 РозЕ0и1{Меззаде ; Послать ИМ_ОИТТ основной программе.

‚ Конец процедуры м1пдом_ргос.


епа_мт_сНеск:
.рора
хог еах,еах . . ‚ Вернуть 0.
‚]еаме
гех 16
; Процедура зе {1 1е.
‚ Устанавливает новый заголовок для основного окна.
Зет. 1111е:
ризй $51
риз! ед !
тмоу е91, оРЕзефт м1пдом_1141е
стр Буте руг Еа9_ипт111е9,1 ; Если у файла нет. имени,
. фе 011 еа ; использовать Цпт11ед.
том . е31, оРп. 1рзтгЕ1е ; [Е$ЗТ] - имя файла с путем.
то\2х еах, отп. ПР 1е01Рэех ; ЕАХ - начало имени файла.
а99 е$1, еах —
сору_Е11епате: |
10956 ‚ Скопировать файл побайтово в название окна,
те51 а1, а] -
32 ад4_ргодпате , пока не встретится ноль,
То36 |
Эр эпогт сору_РИЛепате `
а99_ргодпате:
А Фиога ртг [е91],’ - ' ; Приписать минус
ада е91,3
то е$1, оРЁзее с_м папе
оу есх, 9 ; и название программы. ^
гер моУзЬ |
рор е91
рор е51
ризй ОЁРзет м1пдом_11е
ризй е$1. . _; Идентификатор окна.
са11 Зети1пдомТехт. |
ге

111 1е9:
по\ Чиога рег [е4911, '1%п0" ; Дописать “Упт1“\,
Графические приложения _ __ ПЬЕСЕ
оу Чиогд рег [е91+41, '9е11' ; Дописать “{1е4". с:
‚294 241,8 г. -
Эр зВогЕ ада. ргодламе_

; Процедура заме_соптепгз,
; ЕВХ. =.0, ЕЗТ = ВИЧ
зауе_соптептз: ..
; Спросить редактор, изменялся-ли текст.
ризй ебх
ризв ебх .
рузв ЕМ_СЕТМООТРУ ба
раз № едиитаом.
‚ са11 . ЗепдбМеззаде
Тез еах, еах к
ру пот_то9111ед
; Спросить пользователя, сохранять ли его.
ризВ МВ УЕЗМО + МВ_ТСОММААМТМС
ризв оТРзет с_м_пате
рип ОЁРзет свапдез_тз9
ризй е31 ` 1
са11 МеззацеВох А -
стр еах, ТОУЕЗ
ле пот п0911е9
‚ Сохранить его.
са11 в_19т_зауе
пос_тпо911е9:
‚ ге

м1п_ргос ‘епдр

абоиф ргос ргос пеаг,


; Параметры {с учетом ризп ебр).
ар_#019 еди дмогд рег [ебр+081]
ар_иМ$9 еди бмога рег [е5р+0СВ]
ар_мРагам еди диога рег [ебр+108]
ар_1Рагат еду Фиог@ руг [ебр+148]
ризй еБр ,
оу ебр, езр | ; Создать стековый кадр.
стр ар_иМ$9, ИМ_СОММАКО
пе Чоп{_ргосеед
стр ар_мРагат, ТООК
пе доп{_ргосеед
ризв 1
ризВ ар_109
са11 Еп901а109 !
доп{_ргосеед: 2. ,
хог вах, еах и ; Не обрабатывается.
1еауе . . 5х
гет 16 |
абои{_ргос епар

епд _$Тагт
ШИ Программирование для МИпдоми$ 95 /МТ Е
Размер этой программы- 6,5 Кб (скомпилированной ш|/НоК), и даже версия, |
в которую добавлено все, что есть в Мобера4 (вывод файла на печать и поиск по }
тексту), получилась меньше поёера4.ехе почти в четыре раза. Чем значительнее .?
\УМпдо\з-приложение создается, тем сильнее сказывается выигрыш в размерах _
при использовании ассемблера, даже несмотря на то, что мы лишь вызываем сис-
темные функции, практически не занимаясь программированием.
Прежде чем можно будет скомпилировать \Лпра@95.азт, следует внести необ-
ходимые дополнения в наши включаемые файлы.
Добавления в файл 4е!32.1щс:
; Из м1лизег.п.
ИМ СВЕАТЕ _ еду `1
ИМ_АСТТУАТЕ' еди. 6’
ММ _ЗЕТТЕХТ еди осв
\М бЕТТЕХТ еди 008
УМ СИТ еди оон
\М_СОРУ еди Зо1н
ММ_РАЗТЕ еди 3028 |
ММ СТЕАН еду 3038
ИМ 0900 еди З04и
ММ ТЕ . еди 5
М$_УТЗТВЕЕ = еди 100000001
М$_СНТЕО еаи 400000008
\$_ЕХ_СЕТЕМТЕОбЕ еди 2001
ЕЁ ТЕРТ | еди 0
ЕЗ_МОЕТТЕТМЕ ` еди 4
ЕЗ_АЦТОНУСВОГ Е еди вон
Е$_АИТОУЬСВОн. еди 401
ЕМ СЕТНАМОТЕ . еди оВОв
ЕМ бЕТМООТРУ еач ОВ8В
ЕМ_ЗЕТМООТРУ еди ОВУВ
ЕМ_0№00 еач ОСН
ЕМ_ЗЕТЗЕЕ еаи ОВлН
МВ_УЕЗМО : еду 4
МВ_ТСОМИАВМТМС еду зол
ток - еду 1
` ТОУЕЗ еди 6

; Из и1ппт.в. -
СЕМЕАЯТС_ВЕАБ ° еб 800000008
СЕМЕНТС_МВТТЕ еду 400000008
ЕТЬЕ_ЗНАВЕ_ВЕАВ еду 1
ЕЛЕ _$НАВЕ_МАТТЕ еду 2
ЕТЬЕ АТТАТВОТЕ_АВСНТУЕ еди 20Н
; Из сотта19.п.
ОЕМ.РАТНМУЗТЕХТЬТ _ га 8001
` ОРМ_ЕТЕЕМУЗТЕХТЬТ еду 10008
ОЕМ_ЕХР\.ОВЕВ еди 800001
Графические приложения — __ _ ИМЕЕТ
ОЕМ_ОМЕВИВТТЕРВОМРТ еду 2
‘ОРЕМЕЦ-ЕМАМЕ згис
${гис{$17е 99 ?
ВипдОмпег | 94 ?
_ВТпзТапсе 99 ?
ТретгЕГ Мег , 94 ?
< Тресгбизфойг
тег 49 ?
пМахСиз Е тег . 04. ?
пЕ1 ]егТпдех . 94 ?
]1регЕПе | 99 ?
. пМахЕ11е ` | 94 2
1рэтгЕ11еТ111е 99 ?
пМахЕ11ет1+]е 04 2
ТрегштинанН1г 94 ?
1р$1гТ1118 43 ?
Е1адз . 34 ?
` пРЗео[Евет ` @м 2
пЕ 1 еЕх{епз1оп м ?
1ретгОеГЕХ+ 99 2
1Сиз{бата . 94 ?
]ТрЕпНоок 94 ?
1рТетр]1афемате 94 ?
ОРЕМЕТЕЕМАМЕ епд$

$ Из итпаег.п,
ВЕСТ ЗТгис .
1е 99 ?
Тор 93 ?
гаи 94 ?
. Боттом 94 ?
ВЕСТ епдз у

‚ Из м1пбазе.В.
СМЕМ_МОМЕАВЕЕ . еди 2
СМЕМ_СЕВОТМТТ еди 408
ОРЕМ_ЕХТЗТТМб еди 3
СВЕАТЕ_А1МАУ$У еду 2

Добавления в файл Кегпе!32тс между НЧеЁ! _ТАЗМ_ и е1зе:


ехфгп 131г1еп: пеаг
ехфгп бе{Соттапа[ 1пеА:пеаг
ех{ гп `С1озеНап41е: пеаг
ехЕгп 61оба1А]10ос:пеаг
ехтгп б1ора1(оск:пеаг
ехЕ гп: 61оБа1Егее :пеаг
ехтгп СгеатеЕ11еА:пеаг
ехфгп НеаЧЕ11е:пеаг
ехЕгп Мг! те=11е:пеаг
бе{Соттапа{ {пе еди бе{Соттапа 1пеА
СгеафеР11е еди СгеатеЕ11еА

15 Зак. 459.
\\ Программирование для МИпдому$ 95 /МТ ]
и между е1зе и епа!:
ех&гп __Нр__1$1г1еп6@4
:дмога
ехфгп :_1тр__ветСоттапа
Е1пеА@0 :диога
ехтгп __{тр__С10озеНапа1е@4
‚дога
ехтгп __Нтр__6105а1А110с@8
: диогд
ехтгп _.1тр__бТоба11оск@4 ; дмога
ехтгп __4тр__61оба1Егее6@4 : диогд
ехфгп __Нар__Сгеате[11еА@28 : дога
ехф гп __тр__ВеадЕ11е620: дмогд
ехЁгп __1р__ Мг {еЕ11е620 : дмога
151г]еп еду __фтр__151г1еп@4
бетСоттала 1 пе еди - __ир__бетСоттапа 1пеА@0
С1озеНапа1е еди __1тр__С1озеНапа1е64
6106а1А110с еду _ __р__61оба1А110с@8
б1оБа1 0ск еду __1тр__61оБа 1оск@4
6] оба1Егее еда __Нр__61оБа1Егее@4
Сгеате[11е еди __Нир__Сгеате[11е4А@28
ВеадЕ1]е . еду __1р__ВеадЕ11е@20
иг теР1]е еди -_ 4тр_ Мг ее е@20

Добавления в файл изег


32 пс:
ехегп |садАссе1егатогзА:пеаг .
ехфгп Тгапз1а{еАссе]егатог: пеаг
ехфгп ЗепаМеззадеА :пеаг
ехфгп Зети1пдомТехтА: пеаг
ехЕгп . Моуе\1пдом : пеаг
ехтгп бетС11ептНест :пеаг
ехтгп 6] оба1\/п10ск: пеаг
1 оадАссе1егатог$ еди 1 оадАссе]егатогзА
Зеп9Меззаде еди белдМеззадеА
Зеи1паомТехе еду ‚ Зеи1паомТеххА
и между е15е и еп
ехЕгл ‘’ __Ир_ ТоадАссе1егатог$А@8': дмога
ехфгп __1ир__Тгапз1атедссе]егатог@12 :диога
ехЕгп __1тр__ЗепаМеззадеА@16:
дмога
ехфгп о __Чр__беМ1пдемТехтА@8 : ЧиогЧ
ехтгп __ иир__Моме\1пдом@24
: диот9
ехтги . __фтр__ ве{С11ептВесте8
: дмогд
ехтгп | | __1тр__61о6а19п10ск@4
; ога
{ оааАссе1егатогз - еци __1тр__КоадАссе1егатогзА@8
Тгапз1атедссе1егатог еды р __1ир__Тгапз1атедссе]егатог@12
ЗепаМеззаде ‚ еду __4тр__ЗепдМеззадед@16 °
Зем паомТехте еду __1тр__Зе М1 пдомТехтА@в
Момем1паом ° `_ ебу | __1тр__Моуе\1пдом@24
бет 1лептАест вач 7. р. _бетс11ептАест@8:
боба /и1оск еди Сол 1 __р__@1оБа1/п1юск@4
.
Динамические: библиотеки
Кроме того, нам потребуется новый включаемый файл, сот #32.тс, который
описывает функции, связанные с вызовами стандартных диалогов (выбор имени
файла, печать документа, выбор шрифта и т. д.):
; с0191932. 1пс
; Включаемый файл ‘с функциями из ‘0191932. 911.

14ег _ТАЗМ_ . в
11с]и9е116 1трог{32.
116
ехЕгп . бетОрепРЛеМатед:
пеаг
ехфгп бе{Зауе[11еМамед:
пеаг
бетОрепР11еНате е4и бе{ОрепЕ1 1еМатеА
бе{бауе[11еМате еди бе{зауе[1 ]еМатеА
е1зе
. 1пс1иде115 сот 032.116
; Истинные имена используемых функций.
ехтгп __1тр__бетОрепЕ1 1еМатеА@4 : диогв
ехфгп - __ р бе+бауе[! 1еМатед@4 : диога
; Присваивания для удобства. использования.
бе{ОрепЕ1 1еМате еди __Шир__бетОреп[11еМатед@4
бе{Заме[1]еМате ед0’ __1тр__бе{бауеР 11еМатед@4
епаз Е в” о

Конечно, эту программу можно еще очень долго совершенствовать — добавить


фооФаг и збабазЪаг, написать документацию или сделать так, чтобы выделялось не
фиксированное небольшое количество памяти для переноса файла в редактор, ‹
а равное его длине. Разрешается также применять функции отображения час-
ти файла в память (Сгеа{еР!еМарратя, ОрепЕИеМаррше, Мар\У1е\ОЁЕИе,
ОптарУМе\ОЙ:е), что позволит работать с файлами больших размеров. В \Ип32
АР! так много функций, что можно очень долго заниматься лишь их изучением.

7.4. Динамические библиотеки


Кроме обычных приложений в УЛп4о\$ появился специальный тип файла —
динамические библиотеки (ОТТ.). ОШ. - это файл, содержащий процедуры и дан-.
ные, которые доступны программам, обращающимся к нему. Например, все сис-
темные функции УЙп4о\5, которыми мы пользовались, на самом деле были про-
цедурами, входящими в состав таких библиотек, — ‘Кегпе!32.4 изег3З2.АП,
сот ]#32.А1 и т. д. Динамические библиотеки позволяют уменьшить использова-
ние памяти и размер исполняемых файлов в тех случаях, когда несколько про-
грамм (или даже копий одной программы) используют одну и ту же процедуру.
Можно считать, что ОТ. - это аналог пассивной резидентной программы, с тем
лишь отличием, что его нет в памяти, если ни одна программа, работающая с ним,
не загружена.
С точки зрения программирования на ассемблере ОГ. - это самый обычный
исполняемый файл формата РЕ, отличающийся только тем, что при входе в него
в стеке передается три параметра (идентификатор ОТ.Т.-модуля, причина вызова
ГЕРШИШИШШИИ | Программирование для ММпдому$95/МТ
процедуры и зарезервированный параметр), которые надо удалить, например ко-
мандой ге 12. Помимо этой процедуры в О. входят и другие, часть которых 1
можно вызывать из разных программ. Список экспортируемых процедур должен з
быть задан во время компиляции О, и поэтому команды для создания нашего:
следующего примера будут отличаться от обычных.
Компиляция МАЗМ:
1. /с /со!Р /Ср /О_МАЗМ_ 91]гиз. ат
1пКк 91]гиз.06] @911гиз. пк
Содержимое файла ЧИгиз Лок:
04 .’
/ептгу: зфагт
/зирзузтет:м1п90м$
/{ехрогт: Ко12м1п_азт
/ехрогт: Ко12м1 п
/ехрогт: Ко12м1п1$_азт \
/ехрогт:Ко12м115
Компиляция ТАЗМ:
Тазм /м /х /м1 /0 ТАЗМ_ 91]гиз. ат
{11 пк32 -Тра -с 911гуз.05],,,,911тги$.
дет
Содержимое файла. АПгиаз.деЁ
ЕХРОВТЗ Ко12м1п_азт Ко12м1п Ко12м1п$ Ко12м1пз_азэт
Компиляция У\А$М:
мазт 911гиз. азт
_ мк @911гиз.
917
Содержимое Чгиз. Аи:
Ее 91175.06]
Фогм м1п90м$ пФ ОЕ
ехр Ко1 21 п_азт, Ко12м1 п, Ко12м1п5_азт,
Ко12\11$

; 911ги$. азт
; ОЕ для м1п32 - перекодировщик из `'Ко18 в ср1251.

.386
.109е1
Р1ат
; Функции, определяемые в ВЦ-файле.
1Р4еЕ _МАЗМ_ .
риб11с _Ко12и1п_а$т@0 ; Ко12м1п_азт - перекодирует символ в А.
руб11с _Ко12м1164 ; СНАВ МТМАРТ Ко12м1п(СНАВ зутбо1).
ру611с _Ко12м11$_азт@0 ; К012м1пз_азт - перекодирует строку в [ЕАХ].
руб11с _Ко12\1п5@4 ; \ОТО ИТМАРТ Ко1т2м1и(СНАВ* $1Г1п9).
е]зе
руб]11с Ко12\1п_азт ‚ Те же функции для ТАЗМ и МАЗИ.
руб11с Ко12м1п
ру611с Ко12и1пз_аят
ру611с Ко12\1п$
епа1Р

‚ СОПЗТ
Динамические ‘библиотеки
; Таблица для ‘перевода ‘символа из кодировки КОТ8-г (ВЕС1489)
‚ в кодировку \1п90м8 (ср12513; таблица только для символов 800 -.ЕЕВ .
; (то есть надо будет вычесть 801 из символа, преобразовать его командой х1ат
; и снова добавить 801).
Кам {6} ЧБ 16 9ир(0) ; Символы, не существующие в ср1251,
96 16 дир(0) ; Перекодируются в 801.
Ч6 00в, 00, 00, 388, ООН, 008, ООН, ООН
Ге) 00, 00, 00н, 00%, 008, 00%, 00и, ООН
[2] 001, ООН, 001, 28, 001, 00н, ООН, 008
ЧБ. 00и, ООН, 008, ООН, ООН, 008, 00н, 008
[6] ТЕР, 601, 6б1н, 7бн, 648, 651, 74Нн, 638
6 _ 751, 68н, 69№, 6Ан, 68н, 6Сп, 60и, бЕп
96 6Еп, УРА, ТОН, 71И, 721, 731, 661, 628
[е 7СВ, УВВ, тн, 78н, 7ОН, 79В, 77Н, 7АН
Ге) °БЕВ, 408, 41н, 561, 441, 456, 541, 438
[6] 551, 481, 49., 4АВ, 48ВВ, 4С1,. 401, 4ЕВ
6 4Е!, 5ЕВ, 508, 518, 521, 531, 461, 428
96 5Сн, 5ВВ, 47н, 581, 501, 591, 57и, 5АВ.

. соде
; Процедура ОБЕЕптгу. Получает три параметра - ‘идентификатор, причину вызова
‚; И зарезервированный параметр. Нам не нужен ни один из них.
_$8таг{@12:
моу а], 1 ; Надо вернуть ненулевое число в ЕАХ.
гет 12

; Процедура ВУТЕ МТМАРТ `Ко12м1п (ВУТЕ зутьоТ) - точка входа для вызова из С.
114ее _МАЗМ_ .
_Ко1 21184 ргос
е15е ‘
Кот ргос
епо1Е
рор есх. ; Обратный адрес в ЕСХ.
рор еах
; Параметр в ЕСХ (теперь стек очищен
; от параметров!).
ризН есх ; Обратный адрес вернуть`в стек для ВЕТ.
‚; Здесь нет команды ВЕТ - управление передается следующей процедуре.
1Р9ер _МАЗМ_
_Ко12м1п@4 епар
е15е
Ко121п епар
ета
; Процедура Ко12\1п_азт.
; Точка входа для вызова из ассемблерных программ:
‚ ввод: АЁБ - код символа в КОТ,
‚ вывод: АЁ - код этого же символа в ИМ.
1Р4еР _МАЗМ_
_Ко12м1п_а31@0 — ргос
е15е
Ко12м1п_азт ргос
епа1Е
ШИ! Программирование для МИпдоми; 95 /МТ. |
тезт а1, 808 ; ‚Если. символ ‘меньше 80Н (старший бит 0),
32 аопт_десоде ; ‘не перекодировать, |
ризй е5х | ; иначе -
моу ебх, оРЕзет К2м_151 -
зиБ а1, 808 ‚ вычесть 801,
х1а{ ‚ перекодировать
а34 а], 801. ; и прибавить 801.
рор ебх
доп{_Чесоде: .
ге ` , ; Выйти.
1РдеРг _МАЗМ_
_Ко12м1п_азт@0 — епар
е]зе
Ко1 21 п_азт епар
епа1{

; №010 Кко12матз(ВУТЕ»Ко1$1г1п9) - : }
; Точка входа для вызова из С. . Е
11 деЁ. _МАЗМ_
_Ко12м1п3@4 ргос
е15е
Ко12м115 „ргос
епа1те
`рор есх И ; Адрес возврата из стека.
‚ рор еах ; Параметр в ЕАХ.
ризн ° ‘есх ; ‘Адрес возврата в стек.
174еЕ _МАЗМ.-
_Ко1 211564 : епар
е15е |
Ко12м11$ епар
епа1Р
; Точка входа для вызова из ассемблера:
; ввод: ЕАХ - адрес строки, которую надо преобразовать из КОТ в ИТМ.

1Е4ет _МАЗМ_
_Ко12\11$_а$1@0 ргос 3
е1е Е
Ко12\1пз_азм ргос
епотЕ
рузй -е31 ; Сохранить регистры, которые
; нельзя изменять,
ризй е91
рызп ебх
оу е$1, еах ; Приемник строк
ОУ е41 , еах ; и источник совпадают.
оу еъх, оРзет Кк2и_1Ь1
десоде_з1г1пд: .
' 10936 | ; Прочитать байт,
тезт а1, 80И ‚ если старший бит 0,
Динамические‘ библиотеки <.
ру доп{_десоде2 ; не перекодировать, ` ‘.
зиБ а], 801 ; иначе - вычесть 801,
„ хат ; перекодировать
ааа а1, 80В ; и добавить 801.
допт_десоде2:
УТо5Б ; Вернуть байт. на место,
те51 а], а1 ; если байт - не ноль,
12 десоде_51г110 —^; продолжить. -
рор ебх
рор е01
-. рор е$1
ге
1Е4еР _МАЗМ_°
_Ко12м11$_а$т@80 епар
е1зе
Ко12\1пз_азт епдр
епа1Р |
епд _$1аг{@12
Как видно из примера, нам пришлось назвать все процедуры по-разному для
различных ассемблеров. В случае МАЗМ понятно, что все функции должны иметь
имена типа _5аг6@12, а иначе программам, использующим их, придется обращать-
ся кфункциям с именами типа _ _пар_эатв, то есть такой ОГ1.-файл нельзя будет
загружать из программы, написанной на Мтсгозой С. В случае ТАЗМ и \МАЗМ
процедуры могут иметь неискаженные имена (и более того, \/1пК.ехе не позволяет
экспортировать имя переменной, содержащее символ @), так как их компиляторы
берут имена процедур не из библиотечного файла, а прямо из ОТТ. посредством
соответствующей программы -— нарЦЬ или \/ПЪ.
Итак, чтобы воспользоваться полученным ЮЫ.-файлом, напишем простую
программу, которая перекодирует одну строку из КО]-8г в УЛп4о\з ср1251.
; 9119ето. азт
; Графическое приложение для \1п32, демонстрирующее работу с 911гиз. 911,
; выводит строку в КОТ8 и затем в ср1251, перекодированную функцией Ко12м1п5.

‚ Компиляция:
; -МАЗМ
; №] /с /с01Р /Ср /О_МАЗМ_ 911дето. азт
; Илк 9119ето.05] /зибзузтем:
м1пдом$
‚ (должен присутствовать файл 411гиз.116, созданный при компиляции 911гиз. 911)

; ТАЗМ
; Тазт /т /м] /0_ ТАЗМ_ 911дето.
азм
; Шир 911ги$.116 911ги$, 911
; 1111К32 /Тре /аа /х /с 9114ето.
06)

‚ МАЗМ
‚ мазм 9114ето.азт
ЕВВИШШИШИНИИИИИ Программировани
дляМиомиз
е 95/МТ'
; №116 911гуз. МБ 91]ги$. 911
‚ мыпк 11]е 91]дет0.06] Рог м1пд0м$ пе
,

11с]и9е 9де{32. 1пс


1пс1и4е изег32. 1п6
1тс иде Кегпе132. 1пс

1пс1и9е116 91]гиз. 116


17пдеЁ _МАЗМ_
ехтгп Ко12м1п_азт: пеаг ‚ Определения для функций
‚из ОЕ для
ехёгп Ко12\1 п: пеаг ; ТАЗМ и МАЗМ
ехтгп Ко12\1п$_азт: пеаг ; (хотя для МАЗМ было бы
у ; эффективнее
ех{гп Ко12и1п$ : пеаг ‚ использовать __1тр__Ко12мп
выделив
е1зе . ‚ его в условный блок),
ехтгп __ир__Ко12м1п_а3т@0:
диога ; А это. для МАЗМ.
ех{гп __р__Ко12\1164 :дмога
ехфгп __1пр__Ко12м1п$_азт@0 : днога
., ехёгп __1тр__Ко12м1п364 : диога
Ко12м1п_азт. - еду __ир__Ко12м1п_аз1@0
Ко12м1п еци __Нир__Ко12м1п@4
Ко1 21 пз_азт еаи __1ир__Ко12м1пз_аз1@0
Ко12м1п3 еди __1ир__Ко12м1136@4 : *
епо1г '

.386
.тоде1 Раф
‚ сопзт
1111е_$1г1191 ЧБ “ко12м1п Чето: $4г1пд 1п КО18”,0
11 1е_$1г1192 6 “Ко12м1п ето: ${г1пд 1п ср1251”,0
‚ Чата а
о
м

Ко1_31г1п9 95 ОЕЗВ, 0041, 002н, ОСЕП, ОСВН, ОСЛН, 201, ОСЕП, ОСЛН
6 20Н, ОЕВИ, ОЕРВ, ОЕЭН, 208, 288, 0
. соде
_зТагт:
риэН МВ_ОК :
ризй. ОЁРзеф 11{1е_3{г1п91 ‚; Заголовок окна МеззадеВох.
ризй ОЕРЁзеф ко1_$1г1п9 ‚ Строка на КОТ.
ризй оо
са]11 МеззадевВох
пом еах, оРРзеф Ко1 317119
рузй еах:
са11 Ко12\1п$
ризп МВ_ОК .
рузй оЁР5ет т1{1е_$1г1п92
ризН оРРзеф Ко1_$1г1п9
рузп 0
са11 МеззадеВох
Драйверы устройство = — т: 557
.

ризи 0 у ; Код `выхода.


са11 Ех1ЕРгосез$ ; Конец программы.
еп@ ^ этаге | ы
`

Этот небольшой ОТ.Т.-файл может оказаться очень полезным для расшифров-


ки текстов, взятых из [бегпеё или других систем, где применяется кодировка
КО1В. Воспользовавшись таблицами из приложения 1, вы можете расширить на-
бор функций ЧЙгиз.АП, вплоть до перекодировкив какой угодно вариант.

7.5. Драйверы устройств


В УЛпдо\з, так же как и в ОО$, существует еще один вид исполняемых фай-
лов — драйверы устройств. УЛпдо\з 3.хх и УЛп4о\з 95 используют одну модель
драйверов, \Мп4о\/з МТ - другую, а УЛо4о\з 98 — уже третью, хотя и во многом
близкую к модели УЛадо\з МТ. В УЙпдо\з 3.хх/95 применяются два типа драйве-
ров устройств — виртуальные драйверы (УхО), выполняющиеся с уровнем приви-
легий 0 (обычно имеют раситирение .386 для \УЛпаозуз 3.хх и УХО для УЛтЧо\ 95),
и непривилегированные драйверы, исполняющиеся, как и обычные программы,
с уровнем привилегий 3 (как правило, они имеют расширение ОКУ). УЛп4о\$
МТ использует несовместимую модель драйверов, так называемую Кегпе!-то4де
(режим ядра). На основе модели Кегпе!-тофе с добавлением поддержки техноло-
гии РМР и понятия потоков данных в 1996 году была создана модель УОМ
(\1п32 амуег то4е), которая теперь используется в \Лпдозуз 98/МТ и, по-види-
мому, будет играть главную роль в. дальнейшем.
Как и следовало ожидать, основным средством создания драйверов является
ассемблер, и хотя использование С здесь возможно (в отличие от драйверов
205), но сделать это сложнее: функции, к которым обращается драйвер, могут
передавать параметры в регистрах; сегменты, из которых состоит драйвер, долж-
ны называться определенным образом и т. д. При создании драйверов часто
пользуются одновременно С и ассемблером или С и специальным пакетом, кото-
рый включает в себя все необходимые для инициализации средства.
Чтобы самостоятельно создавать драйверы для любой версии УЙп4о\з, необ-
ходим комплект программ, документации, включаемых файлов и библиотек, рас-
пространяемый МекгозоЁ, который называется РОК - Опуегз Оеуеортепе Ки.
(ООК для Упдо\з №МТ/98 распространяются бесплатно.)
Мы не будем рассматривать программирование драйверов для Уадочв в де-
талях, так как этой теме посвящено много литературы, не говоря уже о докумен-
тации, прилагающейся к ООК. Чтобы создать драйвер, в любом случае лучше
всего начать с одного из прилагающихся примеров и изменять/добавлять проце-
дуры инициализации, обработчики сообщений, прерываний и исключений, обра-
ботчики для АРТ, предоставляемого драйвером, и т. д. Рассмотрим, как выглядит
ИСХОДНЫЙ текст драйвера, потому что он несколько отличается от привычных нам
ассемблерных программ.
Любой драйвер начинается с директивы шс!а4е уши. пс, которая включает
файл, содержащий определения используемых сегментов и макроопределений.
ЕБТЕНИШЕНИИИИНИНИИ!! Программирование для МЛпдомиз 95/МТ 1
Макроопределения вида УХО ТОСКЕОР_СОРЕ_$ЕС/УХО ТОСКЕО_СОРЕ_
ЕМО$ соответствуют директивам начала и конца сегментов (в данном случае сег-
мента _ТТЕХТ). Другие важные макроопределения - Песаге_Уй{иа!_Пеусе 3
и УММСа /ЛУОМСа1. Первое - просто определение, получающее в качестве па- 4
раметров идентификатор драйвера, название, версию, порядок загрузки и адреса #
основных процедур драйвера, из которых строится его заголовок. Второе - заме- 4
на команды са], получающая в качестве параметра имя функции УММ или:
УУ/ОМ, к которой надо обратиться. Например, элемент кода драйвера ВГОЗХЕАТ,
перехватывающий прерывание 101, выглядит следующим образом:
\Ух0_1С00Е_$Еб ; Начало сегмента _ТТЕХТ (сегмент кода
; инициализации, исполняющийся |
; в защищенном режиме, который удаляется‘.
; из памяти после сообщения Тп1`Сотр1ете).
Вед1пРгос ВТОЗХ1ат_Зуз_Сг11са1
Тиле ; Процедура, вызываемая для обработчика
‚ сообщения $у$_Сг11са1 Ти: - первого
‚ сообщения, которое получает драйвер.
‚ Обычно. обработчики сообщений должны .
; сохранять регистры ЕВХ, ЕОТ, ЕЗТ и ЕВР,
; хотя в данном ‚случае этого можно
конь: * о," у Не делать,
оу ° е51, ОРЕЗЕТЗ2 ВтоЗхТае 1пе1о ; Адрес обработчика ТМТ 101
; В регистр ЕЗТ. Важно использовать
; макроопределение ОРЕЗЕТЗ2 всюду
; вместо отРзет.
моу едх, 101 ; Любое число, которое будет
; помещатьсяв ЕБХ при вызове
` ; регистрируемого обработчика.
УММСа1]
А1]осафе_РМ_Са11_Васк ; Зарегистрировать точку входа,
; обращаясь к которой, программы
; из защищенного режима в УМ будут передавать ‘управление процедуре в драйвере (но не
; м1132-программа) - они должны использовать беу1сеТОСоптго] для работы с драйверами.
71° ВХЕ$СТ_М№рРМ ‚ Если СЕ = 1 - произошла ошибка:
хсп9 ех, еах ; Точку входа - в ЕОХ, число 101 - в ЕАХ
; (теперь это номер перехватываемого прерывания для Зет_РМ_ТпЕ_\естог).
оу есх, едх
г есх, 101 ; Селектор точки входа.
моу7х еах, дх: ; Смещение точки входа.
УММСа11 5ет_РМ_Тпт_Местог ‚ Установить обработчик прерывания ТМТ 101.
'
; Если эта функция вызвана до $уз_УМ_Тп1+, установленный обработчик
; становится звеном цепочки обработчиков для всех виртуальных машин.
; После того как прерывание проходит по цепочке обработчиков
; в защищенном режиме, оно отображается в \86 точно так же, как в ОРМТ
[код перехвата других прерываний].
ЕпаРгос ВТОЗХ1ат_$уз_Ст1{1са1_Тп1т ; Конец процедуры.
Ух0_Т1С00Е_ЕМО$ ; Конец сегмента инициализации.
Драйверы устройств’
Соответственно, чтобы эта процедура была вызвана для сообщения 5уз_СиЯ-
са|_Тпк, в сегменте фиксированного кода _ЕРЕХТ должна быть следующая за-
ПИСЬ:; | :
Ух0_10СКЕВ_С00Е_ЗЕб ; Начало Сегнента_ _КТЕХТ.
Вед1пРгос В10$Х1ат_Сопего1: ^ ; Начало процедуры.
| Соптго1_01зрафсй $уз: Сг11са1_Тп1+, ВТОЗХЛае Зуз_Сг11са1_ пи
.; При помощи еще одного макроопределения.-из ‘та. 1пс зарегистрировать процедуру.
° В105Х1ат_5у$_ Сге1са1_ Тп1{ как обработчик ‘сообщения: Зуз_Сг111са1 Лт.
616 . ; Процедура-обработчик управляющих
. | ‚ сообщений должна возвращать СЕ=
гет
ЕпаРгос ВТ0ЗХ1 ас_СопЕго] ; Конец процедуры.
\хб_1ЕОСКЕО_С00Е_ЕНО$ ; Конец сегмента _1ТЕХТ.

И наконец, процедура ВТОЗХ]а&_Сопёго| регистрируется в заголовке драйве-


ра как процедура, получающая управляющие сообщения:
; Первая строка’ побле .386р`и 1пс1и4е утт. 1пс:
Оес1аге_\№М1гтиа]1 _Веу1се ВТОЗХ1ат, 1, 0, ВТОЗХ1ат_Соптго1; ВТОЗХ1ае_Пеу1се_Т0,
: ВТО$Х1
а Ти {_Огаег .

Это не слишком сложно и, пользуясь примерами и документацией из РОК,


а также отладчиком Зо СЕ, можно справиться практически с любой задачей, для
которой есть смысл создавать драйвер.
Глава 8. Ассемблер
и языки высокого уровня
В предыдущей главе, занимаясь программированием для УЛп4о\з, мы уже обра-
щались к процедурам, написанным на языке высокого уровня из программ на ас-
семблере, а также создавали процедуры на ассемблере, к которым можно обра-
щаться из языков высокого уровня. Для этого нужно было соблюдать
определенные договоренности о передаче параметров — параметры помещались
в стек справа налево, результат возвращался в ЕАХ, стек освобождался от пере-
данных параметров самой процедурой. Данная договоренность, известная как
$ТОСАШ,, конечно, не единственная, и разные языки высокого уровня использу-
ют различные способы передачи параметров.

8.1. Передача параметров


Болынинство языков высокого уровня передают параметры вызываемой про-
цедурев стеке и ожидают возвращения параметров в регистре АХ (ЕАХ). Иногда
используется ОХ:АХ (ЕОХ:ЕАХ), если результат не умещается в одном регистре,
и 5Г(0), если результат — число с плавающей запятой.

8.1.1. Конвенция Разса!


Самый очевидный способ выражения вызова процедуры или функции языка
высокого уровня, после того как решено, что параметры передаются в стеке и воз-
вращаются в регистре АХ/ЕАХ, - это способ, принятый в-языке РАЗСАТ. (а так-
жев ВАЗ!С, ЕОКТКАМ, АРА, ОВЕКОМ, МОРОГА2?), - просто поместить пара-
метры в стек в естественном порядке:
запись
зоте_ргос(а,
Б, с,9,е)

превращается в:
ризй
ризй
ризН
ризй е
ризй Фсзсозсь

са11 зоте_ргос

Это значит, что процедура зоте_ргос, во-первых, должна очистить стек по О


|
окончании работы (например, завершившись командой геё 10)‘и, во-вторых, па- ]
раметры, переданные ей, находятся в стеке в обратном порядке:

ве
а н
Передача параметров. р НОО
зоте_ргос ргос
ризй Бр
тои `° Бр, зр ; Создать стековый кадр.
а | еди [6р+12] : Определения для простого. доступа: к параметрам.
ь еду [6р+10] | |
с еди [6р+8]
| еду [6р+6]
е еди (6р+4]

[текст процедуры, использующей параметры а, 6, с, 9, е]

рор р
. гет 10
зоте_ргос _ епдр

Этот код в точности ‘соответствует усложненной , форме директивы ргос, кото-


рую поддерживают все современные ассемблеры:
зоте_ргос ргос РАЗСА! , а:мога, В: мога, с: нога, 9:мога, е:мога

[текст процедуры, с параметрами а, Ь, с,.0, е.. Так как ВР применяется в ка-


честве указателя стекового кадра, его использовать нельзя! ] |

ге ; Эта команда ВЕТ будет заменена на ВЕТ 10.


зоте_ргос епдр

Главный недостаток этого подхода заключается в сложности создания функ-


ции с изменяемым числом параметров, аналогичных рип — функции языка С.
Чтобы определить число параметров, переданных рн, процедура должна сна-
чала прочитать нервый параметр, но она не знает его расположения в стеке. Эту
проблему решает подход, используемый в С, где параметры передаются в обрат-
ном порядке. | |

8.1.2. Конвенция С |
Данный способ передачи параметров используется в первую очередь в языках
СиС++, а также в РКОГОС и др. Параметры помещаются в стек в обратном по-
рядке, а удаление параметров из стека (в противоположность РАЗСАТ--конвен-
ции) выполняет вызывающая процедура:
запись
зоте_ргос(а,
6,с,4,е)

превращается в:
ризп
ризп
ризй
ризй
рузй:. оософо
о

са11 зоте_ргос.
‚ ада эр, 10 ‚ Освободить стек.
И Ассемблер и языки высокого уровня]
Вызванная процедура может инициализироваться следующим образом:
зоте_ргос ргос
'^ ризв Бр С!
поу Бр, зр ‚ Создать ‘стековый кадр. р
а еду ` [6р+41 }; Определения для простого доступа к параметрам.
Ь : вау [5р+6]
| еду’ [6р+8]
9. ` еач [6р+10]
е еац [6р+12]

[текст процедуры, использующей параметры а, В, с, 9, е]

рор р
гет |
зоте_ргос епдр
:

Ассемблеры поддерживают и такой формат вызова посредством усложненной-


формы директивы ргос с указанием языка С: `
зоте_ргос ргос С, а:мога, 6: мога, с:мога, д: ога, е:мога

[текст процедуры с параметрами. а, Ь, с. 9. е. Так как ВР ‘применяется как ука-.


затель стекового кадра, его’ ‘использовать нельзя! ]
г.
зоте_ргос епар

До сих пор этими формами записи процедур в ассемблере мы не пользовались 3


потому, что они скрывают от нас следующий факт: регистр ВР служит для хране- 3
ния параметров и его ни в коем случае нельзя изменять, а в случае РАЗСАТ ко- }
манда гей на самом деле -— геё М. :.
’ Преимущество по сравнению с РАЗСАТ.-конвенцией заключается в том, что}
освобождение стека от параметров в С возлагается на вызывающую процедуру, |
а это позволяет лучше оптимизировать код программы. Например, если мы долж- |
ны вызвать несколько функций, принимающих одни` и те же параметры подряд,
можно не заполнять стек каждый раз заново: ]
ризв рагам2
ризв рагая1
са11 ргос1
са11 ргос2
Е зр,4 °

эквивалентно

ргос1(рагат1 , рагат2};
ргос2 (рагам1, рагат2);

вот почему компиляторы с языка С создают более компактный и быстрый код не-
жели компиляторы с других языков.
Искажениеимен _ .. ам ия

8.1.3. Смешанные конвенции . о


Вглаве 7 мы познакомились с договоренностью о передаче параметров ЗТОСАЦ,
отличавшейся и от С, и от РАЗСАТ--конвенций, которая применяется для всех си-
стемных функций \1132 АР. Здесь параметры помещаются в стёк в обратном по-
рядке, как в С, но процедуры должны очищать стек сами, как в РАЗСАГ.
Еще одно интересное отклонение от С-конвенции можно наблюдать в У/асот
С. Этот компилятор активно использует регистры для ускорения работы програм-
мы, и параметры в функции также передаются по возможности через регистры.
Например, при вызове функции с шестью параметрами
зоме-ргос(а,
6,с,9,е,{);

первые четыре передаются соответственно в (Е)АХ, (Е)ОХ, (Е)ВХ, (Е)СХ, ас пя-


того параметры помещаются в стек в обычном обратном порядке: —
е_ еду [6р+4]
+ - еду [6р+6]

8.2. Искажение имен


Компиляторы Мегозой С (а также многие компиляторы в МХ, как мы узна-
ем далее) изменяют названия процедур, чтобы отразить используемый способ пе-
редачи параметров. Так, к названиям всех процедур, применяющих С-конвенцию,
добавляется символ подчеркивания. То есть, если в С-программе записано
зоте_ргос();
то реально компилятор пишет
са1] _зоте_ргос

и это означает: если процедура написана на ассемблере, она должна называться


именно _зоте_ргос (или использовать сложную форму записи директивы ргос).
Названия процедур, использующих $ТОСАШМ, как можно было видеть из при-
мера ОГ1.-программыв разделе 7.4, искажаются еще более сложным образом: спе-
реди к названию процедуры добавляется символ подчеркивания, а сзади = сим-
вол @ и размер области стека в байтах, которую занимают параметры (то есть
число, стоящее после команды гей в конце процедуры). | |
зоте_ргос(а: многа);

превращается в
‘ризй а.
са1} _зоте_ргос@4

8.3. Встроенный ассемблер


Если требуется выполнить совсем небольшую операцию на ассемблере, напри-
мер вызвать какое-то прерывание или преобразовать сложную битовую структу-
ру, порой нерационально создавать отдельный файл ради` нескольких строк на !
Ш! — Ассемблер и языки высокого уровня
ассемблере. Во избежание этого многие языки высокого уровня поддерживают
возможность вставки ассемблерного кода непосредственно в программу. Напри-
мер, напишем процедуру, возвращающую слово, находящееся по адресу
00408:006СЪ, в ВТО$ - счетчик сигналов системного таймера, который удобно
использовать для инициализации генераторов случайных чисел.

‚ 8.3.1. Ассемблер, встроенный в Разса!


Фипс{10оп дет_зеед: 1019111
уаг
зеед: 1019111
Бед1п | ‚
аз‘
ризй е$
оу ах, 00401
оу ез, ах
У ах, ез: [006С8]
поу зеед,ах
рор ез
епа;
дет_зеед
: =зее 9;
епд;

8.3.2. Ассемблер, встроенный в С


111 дет зее9()
111 зеечд;
{
_азм {
| ризй ез
тому ах, 00404
поу е5,ах
„Том ах, ез: [00601]
ОУ зеед;ах
` рор ез
у;
гетигп
( зеед);
};
В данных ситуациях ассемблерная программа может свободно пользоваться
переменными из языка высокого уровня, так как они автоматически преобразу-
ются в соответствующие выражения типа \ог4 рёг [Бр + 4].
Глава 9. Оптимизация
Наиболее популярным применением ассемблера обычно считается именно оптими-
зация программ, то есть уменьшение времени выполнения программ по сравнению
с языками высокого уровня. Но если просто переписать текст, например с языка С
на ассемблер, перёводя каждую команду наиболее очевидным способом, окажет-
ся, что С-процедура выполнялась быстрее. Вообще говоря, ассемблер, как и лю-
бой другой язык, сам по себе не является панацеей от неэффективного програм-
мирования — чтобы действительно оптимизировать программу, требуется знать не
только команды процессора, но и алгоритмы, оптимальные способы их реализа-
ции и владеть подробной информацей об архитектуре процессора.
Проблему оптимизации принято делить на три основных уровня:
1. Выбор самого оптимального алгоритма — высокоуровневая оптимизация.
2. Наиболее оптимальная реализация алгоритма — оптимизация на среднем
уровне.
3. Подсчет тактов, тратящихся на выполнение каждой команды, и оптимизация
`их порядка для конкретного процессора - низкоуровневая оптимизация.

9.1. Высокоуровневая оптимизация


Выбор оптимального алгоритма для решения задачи всегда приводит к луч
шим результатам, чем любой другой вид оптимизации. Действительно, при заме-
не пузырьковой сортировки, время выполнения которой пропорционально №, на
быструю сортировку, выполняющуюся как № Х 108 (№), всегда найдется такое чис-
ло сортируемых элементов М, что вторая программа будет выполняться быстрее,
как бы она ни была реализована. Поиск лучшего алгоритма — универсальная ста-
дия, и она относится не только к ассемблеру, но и к любому языку программиро-
вания, поэтому будем считать, что оптимальный алгоритм уже выбран.

9.2. Оптимизация на среднем уровне


са-
Реализация алгоритма на данном конкретном языке программирования—
мая ответственная стадия оптимизации. Именно здесь можно получить выигрыш
в скорости в десятки раз или сделать программу в десятки раз медленнее при се-
рьезных ошибках в реализации. Многие элементы, из которых складывается оп
тимизация, уже упоминались — хранение переменных, с которыми выполняется
активная работа, в регистрах, использование таблиц переходов вместо длинных
последовательностей проверок и условных переходов и т. п. Тем не менее даже
плохо реализованные операции не вносят заметных замедлений в программу, если
ы
они не повторяются в цикле. Можно говорить, что практически все проблем
СТИ ВИН стоя _ (Оптимизация:
оптимизации на среднем уровне так или иначе связаны с циклами, и именно поэто-
му мы рассмотрим основные правила, которые стоит иметь в виду при реализа- |
ции любого алгоритма, содержащего циклы.

9.2.1, Вычисление констант вне цикла


Самым очевидным и самым важным правилом при создании цикла на любом
языке программирования является вынос всех переменных, которые не изменя-
ются на протяжении цикла, за его пределы. Программируя на ассемблере, имеет
смысл также по возможности разместить все переменные, которые будут исполь-
зоваться внутри цикла, в регистры, а старые значения нужных после цикла реги-
‚ стров сохранить в стеке.
9.2.2, Перенос проверки условия в конец цикла
Циклы типа \УНШЕ или ЕОК, которые так часто применяются в языках вы-
сокого уровня, оказываются менее эффективными по сравнению с циклами типа
ОМТИ. из-за того, что в них требуется лишняя команда перехода:
го Цикл типа ИНТЕЕ.
МОУ 31, соиптег ‚ Число повторов.
оу _ . Ох, Фаге_1 , | ‚ Начальное значение.
1оор_зтагт: . ,
стр Чх, $1 | ,‹ Пока 9х < $1 - выполнять.
`‘ ть ех1{_1оор
[тело цикла]
1пс 9х
Эр Тоор_зфаг{
; Почти такой же цикл типа УМТТЕ.
по $1, соиптег
ь том. Чх, таг _1
1юор_зтагт: . ‚ 3 ВЫПОЛНЯТЬ.
[тело цикла] :
пс 9“
стр Чх, 91 ‚ Пока 9х < 81.
3} 1оор_зтагт

Естественно, цикл тина ОМТИ., в отличие от цикла типа \УНЕ, выполнится


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

9.2.3. Выполнение цикла задом наперед


Циклы, в которых значение счетчика растет от единицы или нуля до некото-
рой константы, можно реализовать вообще без операции сравнения, выполняя
цикл в обратном направлении (и мы пользовались этим приемом неоднократно
в наших примерах). Дело в том, что команда ЕС соит\ег устанавливает флаги
почти так же, а команда ЗОВ соцщег,1 — абсолютно так же, каки команда СМР
Оптимизация на среднем уровне
‚ сомпфег,1, то есть следующая команда условного перехода будет обрабатывать ре-
зультат сравнения счетчика с единицей: у
Цикл от 10 до 1.
моу дх,10
1оор_зтагт: о
| [тело цикла] (7: ..
де ах 7). з Уменьшить ОХ, .
312. "Поор_ таг . 1 сли ОХ. не стал.нулем - продолжить цикл.

‚ Цикл от 10 до 0.
МОУ _ 9х, 10. о |
1оор_зтагт: .
[тело цикла] ,
дес ах р Уменьшить
0х, -
313... Дооргвтаге ; если ЭХ не отрицательный - продолжить. цикл.

Конечно, не все циклы можно заставить выполняться в обратном направлении


сразу. Например, иногда приходится изменять формат хранения массива данных
также на обратный или вносить другие изменения, но в целом, если это возмож-
но, всегда следует стремиться к циклам, выполняющимся задом наперед. Кроме
того, если цикл построен по этому образцу, выполняется до значения счетчика,
равного нулю, и регистр СХ можно освободить для выполнения роли счетчика,
есть вариант воспользоваться командой ЕООР хотя в некоторых случаях в низ-
коуровневой оптимизации команды РЕС/ЙМ2 оказываются более эффектив-
ными.
9.2.4. Разворачивание циклов
Для небольших циклов время выполнения проверки условия и перехода на на-
чало цикла может оказаться значительным по сравнению с временем выполнения
самого тела цикла. Более того, Репёит Рго/Репит П всегда тратят по крайней
мере один такт процессора на цикл, хотя его тело может выполняться даже быст-
рее одного такта. С этим легко справиться, вообще не создавая цикл, а просто по-
вторив его тело нужное число раз (разумеется, только в случае; если нам заранее
известно это число!). Для очень коротких циклов можно, например, удваивать
или утраивать тело цикла при условии, что Число повторений кратно двум или
трем. Кроме того, бывает удобно часть работы сделать в цикле, а часть развернуть,
например продолжая цепочку циклов из предыдущего примера:
Цикл от 10 до. -1.
оу Чх;10
1оор_ 5фагт:
В [тело цикла] й
дес 9х: ; Уменьшить 0Х.
]т$ ‚ Тоор. «тат ‚ Если ОХ не отрицательный -
= ВИ „ ‹ продолжить. цикл.
[тело. цикла]
468 (|1 7”. ’ Оптимизация
Совершенно естественно, что эти простые методики не. перечисляют все воз-
можности оптимизации среднего уровня, более того, они не описывают и десятой
доли всех ее возможностей. Умение оптимизировать программы нельзя сформу-
лировать в виде набора простых алгоритмов — слишком много таких ситуаций,
когда любой алгоритм оказывается неоптимальным. При решении задачи оптими-
зации приходится постоянно что-то изменять. Именно потому, что оптимизация
всегда занимает очень много времени, рекомендуется приступать к ней только
после написания программы. Как и во многих других случаях, на любой стадии
‚ создания программы с оптимизацией нельзя торопиться, но и нельзя совсем за-
бывать о ней.

9.3. Низкоуровневая оптимизация


9.3.1. Общие принципы низкоуровневой оптимизации
Так как процессоры Пе] используют весьма сложный набор команд, большин-
ство операций можно выполнить на низком уровне различными способами. При.
этом иногда оказывается, что наиболее очевидный способ’ не самый быстрый
или короткий. Часто простыми перестановками команд, зная механизм их реали-
зации на современных процессорах, можно заставить ту же процедуру выполнять-
ся на 50-200% быстрее. Разумеется, переходить к этому уровню. оптимизации
разрешается только после того, как текст программы окончательно написан и макси-
мально оптимизирован на среднем уровне.
Перечислим основные рекомендации, которым нужно следовать при опти-
мальном программировании для процессоров ие! Репиит, РепНит ММХ,
Репиит Рго и Рерииа П.
Основные рекомендации
Используйте регистр ЕАХ всюду, где возможно. Команды с непосредственным
операндом, с операндом-— абсолютным адресом переменной и команды ХСНС с ре-
гистрами на байт меньше, если другой операнд - регистр ЕАХ.
Применяйте регистр 0$ всюду, где возможно. Префиксы переопределения сег-
мента увеличивают размер программы на 1 байт и время на 1 такт.
Если к переменной в памяти, адресуемой со смещением, выполняется несколь-
ко обращений - загрузите ее в регистр.
Не используйте сложные команды (ЕМТЕК, ГЕАХЕ, ГООР, строковые коман-
ды), если аналогичное действие можно выполнить небольшой последовательнос-
тью простых команд.
Не используйте команду МОУ7Х для чтения байта -— это требует четыре так-
та. Заменой может служить следующая пара команд:
хог еах, еах
оу а1, зоигсе

Применяйте ТЕЗТ для сравнения с нулем:


Тезт. еах, еах
32 1Е 7тего ; Переход, если ЕАХ =
Низкоуровневая оптимизация 559]
- Применяйте команду ХОВ; чтобы обнулять регистр (конечно, если текущее со-
стояние флагов больше не потребуется); она; официально ‘поддерживается Гобе
как команда. обнуления регистра:
`хог . вах, вах г БАХ = 0

Не используйте умножение или деление на константу — его можно заменить .


другими командами, например:
; ЕАХ = ЕАХ * 10 | :
$1] еах, 1 : ; Умножение на 2.
1еа еах, [еах+еах»4] ; Умножение на 5.
; ЕАХ = ВАХ * 7
поу ебх, еах о. ве.
381 еах, 3 _._ _; Умножение на 8
зи - еах, ебх ;. И вычитание сохраненного ЕАХ.
; АХ = АХ/10 |
мо\ 9х, 6554 . ; ОХ= 65 536/10.
_ мы] 9х (т; 0Х = АХ/10 (умножение выполняется.
, ; ‘быстрее деления).
; ЕАХ.= ЕАХ тов 64 (остаток от’ деления на степень. двойки).
апд еах, ЗЕ

Используйте короткую форму команды тр, где возможно (пр зВогё метка).
Как можно реже загружайте сегментные регистры.
Как можно меньше переключайте задачи -— это очень медленная процедура. Ча-
сто, если сохранение состояния процесса не требует больших затрат, например для
реализации нитей, переключение быстрее организовать с помощью программы.
Команда {ЕА
ТЕА можно использовать (кроме прямого назначения — вычисления адреса
сложно адресуемой переменной) для следующих двух ситуаций:
О быстрое умножение
]еа вах, [вах»2] .; ЕАХ = ЕАХх 2 (3181 .еах,1 лучше).
]еа вах, [еах+еах*2] _; ЕАХ = ЕАХ х 3.
1еа еах, [еах*4] ; ЕАХ = ЕАХХ 4 (571 вах, 2 лучше).
]еа еах, [еах+еах»4] ; ЕАХ = ЕАХХ 57
1еа вах, [еах+еахя8] ; ЕАХ = ЕАХх 9.

Отрехоперандное сложение о р|
1еа есх, [еах+еьх] °. ; ЕСХ = ВАХ + ЕВХ.

Единственный недостаток ГЕА`-— увеличивается вероятность АСТ с предылу-


щей командой (см. ниже).
Выравнивание
8-байтные данные должны быть выравнены по .8-байтным границам (то есть
три младших бита адреса должны быть равны нулю).
4-байтные данные должны быть выравнены но границе двойного слова (то есть
два младших бита адреса должны быть равны нулю).
4701 ||| ||] | ‚ о. Оптимизация
2-байтные данные должны полностью содержаться в выравненном двойном
слове (то есть два младших бита ‘адреса не должны быть равны единице).
80-битные данные.должны быть выравнены по 16-байтным границам.
Когда нарушается выравнивание при доступе к данным, находящимся в кэше,
теряются 3 такта на каждое невыравненное ‘обращение на Репиат и 9-12 тактов —
на Репиит Рго/Репиит П. .
Так как линейка кэша кода составляет 32 байта, метки для переходов; особенно
метки, отмечающие начало цикла, должны быть выравнены по 16-байтным грани-
цам, а массивы данных, равные или большие 32 байт, должны начинаться с адреса,
кратного 32. ”
Генерация адреса
АСТ - это ситуация, при которой регистр, используемый командой для генера-
ции адреса как базовый или индексный, являлся приемником предыдущей коман-
ды. В таком случае процессор тратит один дополнительный такт.
Последовательность команд
ада еах,4
тмо\ ез1, [еах) |

выполняется с АСТ на любом процессоре. —_ -#


Последовательность команд в
а94 е31,4 . ;. -конвейер - 1 такт (на Репт1ит). -
‚ рор `е5х ‚ У-конвейер - 1 такт.
1пс ебх : М-конвейер - 1 такт
поу еа1, [е$1] ‚ в У-конвейер - «АСТ», затем 1 такт.

зыйтолняется с АС] на Репиит за три такта процессора.


Кроме того, АСТ может происходить неявно, например при изменении регист-
ра Е$Р и обращении к стеку:
зи езр, 24 .
ризп еБх ор *АВТ
ИЛИ
то\ езр, ебр
рор ебр ; «АБТ»

но изменение Е$ЗР, производимое командами РОЗН и РОР не приводит к АСТ,


если следующая команда тоже обращается к стеку.
Процессоры Репиит Рго и Репёит П не подвержены АСТ.
Обращение к частичному регистру
Если команда обращается к 32-битному регистру, например ЕАХ, сразу после
команды, выполнявшей запись в соответствующий частичный регистр (АХ, АГ,
АН), происходит пауза минимум в семь тактов на Репиит Рго и Репичга.П ив один
такт на 80486, но не на Репиит:
тмоу ах, 8
_ ада есх, еах ; Пауза.
„Низкоуровневая оптимизация
„На Репёнит Рго и-Репиит П эта пауза не появляется, если сразу перед коман-
дой записи в: АХ была командаа ХОК ЕАХ,ЕАХ или 5ОВ ЕАХ,ЕАХ.
Префиксы
`Префиксы ГОСК, переопределения сегмента и изменения адреса операнда уве-
личивают время выполнения команды на 1 такт.
9. 3.2. Особенности архитектуры процессоров Репит
‚и Репйит ММХ. >

Выполнение команд_
Процессор Репёит содержит два конвейера исполнения целочисленных ко-
манд (ЦЧи\У) и один конвейер для команд ЕРУ. Он может выполнять две цело-
команды одновременно, и поддерживает механизм предсказания пере-
численные
ходов, значительно сокращающий частоту сброса очереди предвыборки из-за.
передачи управления по другому адресу. |
На стадии загрузки команды процессор анализирует сразу две следующие ко-
манды, находящиеся в очереди, и, если возможно, выполняет одну из них в О-кон-
вейере, а другую в У. Если это невозможно, первая команда загружается в О-кон-
вейер, а \У-конвейер пустует.
\У-конвейер имеет определенные ограничения на виды команд, которые. могут
в нем исполняться. Приложение 2 содержит для каждой команды информацию
о том, может ли она выполняться одновременно с другими командами и в каком
конвейере. Кроме того, две команды не будут запущены одновременно, если:
О команды подвержены одной из следующих регистровых зависимостей:
— первая команда пишет в регистр, а вторая читает из него;
— обе команды пишут в один и тот же регистр (кроме записи в ЕРГАС$).
Исключения из этих правил— пары РОЗН/РО$Н, РУЗН/РОР
и РО$Н/САЦ,, осуществляющие запись в регистр ЕЗР;
О одна из команд не находится в кэше команд (кроме случая, если первая ко-
манда — однобайтная);
О одна из команд длиннее семи байт (для РепЧит);
Оодна команда длиннее восьми байт, а другая — семи (для Реинит ММХ).
Помните, что простыми перестановками: команд можно выиграть до.200% ско-
рости в критических ситуациях.
Кэш-память
Процессор Репимт. состоит из двух 8-килобайтных блоков кэш-памяти, один
`° для кода и один для данных с длиной линейки 32 байта. Кэш данных состоит из
_ восьми банков, причем он доступен из ‚обоих конвейеров одновременно, только
‘если обращения происходят к разным банкам. Когда данные или код находятся
‘в не кэше, минимальная дополнительная задержка составляет 4 такта.
Если происходит два кэш-промаха одновременно при записи в память из обо-
`их конвейеров и обе записи попадают в одно учетверенное слово (например, при
записи двух слов в последовательные адреса), процессор затрачивает столько же
времени, сколько и на один кэш-промах. .
[472 ГОТ | ‚ _ Оптимизация
Очередь предвыборки ,
Перед тем как команды распределяются по конвейерам, они загружаются из
памяти в одну из четырех 32-байтных очередей предвыборки. Если загружается
команда перехода и блок предсказания переходов подтверждает, что переход про-
изойдет, начинает работать следующая очередь предвыборки. Это сделано для
того, чтобы, если предсказание было неверным, первая очередь продолжила вы-
борку команд после невыполненной команды перехода. ы
Если условный переход не был предугадан, затрачивается 3 такта, когда коман-
да перехода находилась в О-конвейере, и 4 такта, когда в \.
Если безусловный переход или вызов процедуры не был предугадан, затрачи-
вается 3 такта в любом случае.
Конвейер ЕРИ
Конвейер исполнения команд ЕРО состоит из трех участков, на каждом из\ко-
торых команда тратит по крайней мере один такт. Многие команды, однако, пост-
роены таким образом, что позволяют другим командам выполняться на ранних
участках конвейера, пока данные команды выполняются на более поздних. Кроме
того, параллельно с длинными командами ЕРО, например ЕР, могут выпол-
няться команды в целочисленных конвейерах.
Команда ЕХСН может выполняться одновременно почти с любой командой
ЕРГ. что позволяет использовать ЗТ(в) как неупорядоченный набор регистров
практически без потерь в производительности.
Конвейер ММХ
Команды ММХ, так же как команды ЕРУ, используют дополнительный кон-
вейер, содержащий два блока целочисленной арифметики (и логики), один блок
умножения, блок сдвигов, блок доступа к памяти и блок доступа к целочислен-
ным регистрам. Все блоки, кроме умножителя, выполняют свои стадии команды
за один такт, умножение требует трех тактов, но имеет собственный буфер, поз-
воляющий принимать по одной команде каждый такт. Так как блоков арифмети-
ки два, соответствующие операции могут выполняться одновременно в - или
У-конвейере. Команды, использующие блок сдвигов или умножитель, способны
осуществляться в любом конвейере, но не одновременно с другими командами,
применяющими тот же самый блок. А команды, обращающиеся к памяти или
обычным регистрам, в состоянии выполняться только в О-конвейере и только
одновременно с ММХ-командами.
Если перед командой, копирующей ММХ-регистр в память или в обычный ре-
гистр, происходила запись в ММХ-регистр, затрачивается один лишний такт.
9.3.3. Особенности архитектуры процессоров Репйит Рго
и РепНит ПИ
Процессоры Репиит Рго и Репиит П включают в себя целый набор средств
для ускорения выполнения программ, В них происходит выполнение команд не
по порядку, предсказание команд и переходов, аппаратное переименование ре-
гистров.
Низкоуровнёвая оптимизация М
АИ ОИНИИНЕ Е
Выполнение команд | .
За каждый такт процессора. из очереди предвыборки может быть прочитано
и декодировано на микрооперации до трех команд. В этот момент работают три.
декодера, первый из которых декодирует команды, содержащие до четырех мик-
роопераций, а другие два — только команды из одной микрооперации. Если в ас-
семблерной программе команды упорядочены в соответствии с этим правилом
(4-1-1), то на каждый такт будет происходить декодирование трех команд. Напри-
мер: если в последовательности команд
ад еах, [е5х} - ср 2% - в декодер 0. на ‚первом такте:
моу есх, [еах] ; 2 - пауза 1 такт, пока декодер 0
; не освободится. |
` 299 едх, 8 ; 1м - декодер 1 на втором такте. `

переставить вторую и третью команды, то ад едх,8 будет декодирована в тот же


такт, что и первая команда. | | о
Число микроопераций для каждой команды приведено В приложении 2, но
можно сказать, что команды, работающие только с регистрами, как правило, вы-
полняются за одну микрооперацию, команды чтения из памяти — тоже за одну,
команды записи в память — за две, а команды, выполняющие чтение-изменение-
запись, - за четыре. Сложные команды содержат больше четырех микроопераций
и требуют несколько тактов для декодирования. Кроме того, команды длиннее
_ семи байт не могут быть декодированы за один такт. В среднем время ожидания
в этом буфере составляет около трех тактов.
Затем микрооперации поступают в.буфер накопления, где они ждут, пока все
необходимые им данные не будут доступны. Далее они посылаются в ядро систе-
мы неупорядоченного исполнения, состоящей из пяти конвейеров, каждый из ко-
‚торых обслуживает несколько блоков исполнения. Если все данные для микро-
операции готовы и в ядре есть свободный элемент, исполняющий конкретную
микрооперацию, в буфере накопления не будет потрачено ни одного лишнего так-
та, После выполнения микрооперации скапливаются в буфере завершения, где ре-
зультаты их записываются, операции записи в память упорядочиваются и микро-
операции завершаются (три за один такт). |
Время выполнения команд в пяти конвейерах исполнения приведено в табл. 21.
Указанное в таблице время требуется для выполнения микрооперации, а ско-
рость демонстрирует, с какой частотой элемент может принимать микрооперации
в. собственный конвейер (1 — каждый такт, 2 — каждый второй такт). То есть, на-
пример, одиночная команда ЕАЮШ выполняется затри такта, а‚три последователь-
ные команды ЕАОШ- тоже за три-такта. _
Микрооперации чтения и записи, обращающиеся к одному и тому же адресу
в памяти, выполняются за один такт.
Существует особая группа синхронизирующих команд, любая из которых на-
чинает выполняться только после того, как`завершаться все микрооперации, на-
ходящиеся в процессе выполнения. К таким командам относятся привилегиро-
ванные команды \УВМ$В, ПЧУО, ПМУГРС, У/ВТМУО, ГСОТ, ЕГОТ, ГОТ, СТВ,
[7 ТО _ © Оптимизация
Таблица 21. Конвейеры процессора Репйит Рго/Репйит Ио тт

Конвейер 0
Блок целочисленной арифметики
Блок команд ЁЕА
Блок команд сдвига

Блок команд РАБО


Блок команд ЕМИЕ : ,
17 для 32-битных
Блок команд РОМ . 36 для 64-битных
56 для 80-битных

| ‚ Конвейер. 1

Блок чтения

Блок записи адреса.

Блок ‘записи данных не меньше" 1

К$М и МОУ в управляющие и отладочные регистры, а также две непривилегиро-


ванные команды — ВЕТ и СРОТО. Когда, например, измеряют скорость испол- '
нения процедуры при помощи команды КОТЗС (см. раздел 10.2), полезно выпол-.
нить одну из синхронизирующих команд, чтобы убедиться в том, что. все
измеряемые команды полностью завершились.
Кэш-память
Процессоры РепНит Рго включают в себя 8-килобайтный кэш 1.1 для данных
и 8-килобайтный кэш [.1 для кода, а процессоры Репёит П соответственно по 16 Кб,
но не все кэш-промахи приводят к чтению из памяти: существует кэш второго уров-
ня — 1.2, который маскирует промахи 1-1. Минимальная задержка при промахе в оба
кэша составляет 10-14 тактов в зависимости от состояния цикла обновления памяти.
Микрооперации чтения и записи могут произойти одновременно, если они
обращаются к разным банкам кэша 1.1. `
Очередь предвыборки
Очередь предвыборки считывает прямую линию кода 16-байтными выровнен-
ными блоками. Это значит, что следует организовывать условные переходы так,

:
Е.
‚оптимизация МЕН
‚ чтобы наиболее частым исходом было бы отсутствие перехода, и что полезно вы-
равнивать команды на границы слова. Кроме того, желательно располагать редко
используемый код в конце процедуры, чтобы он не считывался в очередь предвы-
борки впустую.
Предсказание переходов '
Процессор поддерживает 512- байтный буфер выполненных переходов и их це-
лей. Система предсказания может обнаруживать последовательность до. четырех
повторяющихся переходов, то есть четыре вложенных цикла будут иметь процент
предсказания близкий к 100. Кроме того, дополнительный буфер адресов возврата
позволяет правильно предсказывать циклы, из которых вызываются подпрограммы.
На неправильно предсказанный переход затрачивается как минимум девять
тактов (в среднем от 10 до 15). На правильно предсказанный невыполняющийся
‚переход не затрачивается никаких дополнительных тактов вообще. На правильно
предсказанный выполняющийся переход затрачивается один дополнительный
такт. Именно поэтому минимальное время исполнения цикла на Репцит Рго или
Репиит П — два такта и, если цикл может выполняться быстрее, он должен быть
развернут.
с
Если команда перехода не находится в буфере, система предсказания делает
следующие предположения: — | |
О безусловный переход предсказывается как происходящий, и на его выполне-
ние затрачивается 5-6 тактов;
О условный переход назад предсказывается как происходящий, и на его выпол-
нение также затрачивается 5—6 тактов; -
О условный переход вперед предсказывается как непроисходящий. При этом.
команды, следующие за ним, предварительно загружаются и начинают ис-.
полняться, вот почему не размещайте данные сразу после команды перехода.
Глава 10. Процессоры ие!
в защищенном режиме
Мы уже неоднократно сталкивались с защищенным режимом и даже програм-
мировали приложения, которые ‘работали в нем (см. главы 6 и 7), при этом
пользовались только средствами, которые предоставляла операционная система,
и до сих пор не рассматривали, как процессор переходит и функционирует в за-
щищенном режиме, то есть как работают современные операционные системы.
Дело вот в чем: управление защищенным режимом в современных процессорах
Табе] — это самый сложный. раздел программирования и самая сложная глава
в этой книге. Но материал можно легко освоить, если рассматривать этот раздел
шаг за шагом — отдельные механизмы работы процессора достаточно мало пере-
крываются друг с другом. „Прежде чем рассматривать собственно программиро-
вание, познакомимся с регистрами и командами процессора, которые пока’ были
от нас скрыты.

10.1. Регистры
Рассматривая регистры процессора в разделе 2.1, мы специально ничего не рас-
сказали-о регистрах, которые не используются в обычном программировании,
в основном'Именно потому; что они управляют защищенным режимом.

_ 10.11. Системные флаги.


Регистр флагов ЕЕГАС$ - это 32-битный регистр, в то время как в разделе
2.1.4 рассмотрена только часть из младших 16 бит. Теперь мы можем обсудить все:
биты 31-22: нули
бит 21; флаг идентификации (ТО)
бит 20: флаг, ожидания виртуального прерывания (\У1[Р)
бит 19: флаг виртуального прерывания (У1Е)
бит 18: флаг контроля за выравниванием (АС)
бит 17: флаг режима \У86 (УМ)
бит 16: флаг продолжения задачи (ВЕ).
бит 15:0
бит 14: флаг вложенной задачи (мт)
биты 13-12: уровень привилегий ввода-вывода (ТОРГ)
бит 11: флаг переполнения (ОЕ)
бит 10: флаг направления (ОБ).
бит 9: флаг разрешения прерываний (ТЕ)
Регистры ‘^^ МИ
бит 8: флаг трассировки-(ТЕ)
биты 7-0: флаги состояния (5Е РЕ АЕ РЕ СР) были рассмотрены подробно
раньше
Флаг ТЕ. если он равен 1,перед выполнением каждой команды генерируется |
‘исключение #0В (ТМТ 1). |
Флаг [Е: — если он равен 0, процессор не реагирует ни на какие маскируемые
аппаратные нрерывания.
Флаг ОЕ; если он равен 1, регистры ЕРИЕЗ при выполнении команд ‘строко-
вой обработки. уменьшаются, иначе — увеличиваются.
Поле ТОРГ: уровень привилегий ввода-вывода, с которым выполняется текущая
программа или задача. Чтобы программа могла обратиться к порту
ввода-вывода, ее текущий ‘уровень привилегий (СРГ.) должен быть
меньше или равен ТОРГ. Это поле можно модифицировать, только
имея нулевой уровень привилегий.
Флаг МТ: равен 1, если текущая задача является вложенной по отношению к ка-
кой-то другой— в обработчиках прерываний и исключений и вызван-
ных командой са| задачах. Флаг влияет на работу команды ТЕТ.
Флаг ВЕ когда этот флаг равен 1, отладочные исключения временно запреще-
_ ны. Он устанавливается командой 1ВЕТО из обработчика. отладоч-
ного прерывания, чтобы #ОВ не произошло перед выполнением ко-
манды, которая его вызвала, еще раз. На флаг не влияют команды
РОРЕ РОЗНЕ и ВЕТ.
Флаг УМ: установка этого флага переводит процессор в режим \86 (виртуаль-
ный 8086).
Флаг АС: если установить этот флаг и ‘флаг АМ в регистре СВО, каждое обра-
щение к памяти из программ, выполняющихся с СРГ= 3, не вырав-
ненное на границу слова для слов и на границу двойного слова для
двойных слов, будет вызывать исключение #АС.
Флаг УТЕ: это виртуальный образ флага.ТЕ (только для Репбит и выше).
Флаг У[Р; этот флаг указывает процессору, что произошло аппаратное преры-
вание. Флаги УТЕ и У[ГР используются в многозадачных средах для
того, чтобы каждая задача имела собственный виртуальный образ
флага [Е (только для Репёит и выше - см. раздел 10.9.1).
Флаг Ш: если программа может изменить значение этого флага — процессор
поддерживает команду СРИТО (только для Репииш и выше).

10.1.2. Регистры управления памятью


Перечисленные ниже четыре регистра используются для указания положения
структур данных, ответственных за сегментацию в защищенном режиме.
СОТВ: 6-байтный регистр, в котором содержатся 32-битный линейный адрес
начала таблицы глобальных дескрипторов (СОТ) и ее 16-битный раз-
мер (минус 1). Каждый раз, когда происходит обращение к памяти, по
СУЕЗИМИИИ
ШИ ИИ Процессоры це! в защищенном режиме‘
‘селектору, находящемуся в сегментном регистре, определяется дескрип-
тор из таблицы СОТ или ГРОТ, в котором записан адрес начала сегмен-
та и другая информация (см. раздел 6.1).
ШОТЕ: 6-байтный регистр, в котором содержатся 32- битный линейный адрес
начала таблицы глобальных дескрипторов обработчиков прерываний
(ТОТ) и ее 16-битный размер. (минус 1). Каждый раз, когда происхо-
дит прерывание`или исключение, процессор передает управление на
обработчик, описываемый дескриптором из ШТ с соответствующим
номером.
ГОТК: 10-байтный регистр, в котором содержатся 16- битный.‘селектор для
СОТ и весь 8-байтный дескриптор из СОТ, описывающий текущую
таблицу локальных дескрипторов (ГОТ).
ТВ: 10-байтный регистр, в котором содержатся 16-битный селектор для
СОТ и весь 8-байтный дескриптор из СОТ, описывающий Т$$ текущей
задачи.

10.1.3. Регистры управления процессором _


Пять 32-битных регистров СВО- ‚СВА управляют функинонированием про-
цессора и работой отдельных его внутренних блоков. .

СВ0: флаги управления системой.


бит 31: РС - включает и выключает режим страничной адресации
бит 30: СО - запрещает заполнение кэша. При этом чтение из кэша все равно
будет происходить
‚бит 29: ММ — запрещает сквозную запись во внутренний кэш — данные, запи-
сываемые в кэш, не появляются на внешних выводах процессора
бит 18; АМ- разрешает флагу АС включать режим, в котором невыровненные
обращения к памяти на уровне привилегий 3 вызывают исключение
#АС
бит 16: \!Р - запрещает запись в страницы, помеченные как «только для чте-
ния» на всех уровнях привилегий (если \!Р= 0, защита распространя-
ется лишь на уровень 3). Этот бит прёдназначен для реализации мето-
да копирования процесса, популярного в ОМИХ, в котором вся память
нового процесса сначала полностью совпадает со старым, а затем, при
а8щ
ы
попытке записи, создается копия страницы, к которой происходит
обращение
бит 5: МЕ - включает режим, в котором ошибки ЕРО вызывают исключение
#МЕане [К О13 |
бит 4: ЕТ- использовался только на 80386 0Х`‘и указывал, что ЕРО присут-
ствует
бит 3: Т$- устанавливается процессором ‘после переключения задачи. Если
затем выполнить любую команду ЕРУ, произойдет исключение #ММ,
обработчик которого может сохранить/восстановить состояние ЕРУ,
очистить этот бит командой СГТ$ и продолжить ‘программу
бит 2: ЕМ. - эмуляция сопроцессора. Каждая команда ЕРО вызывает исклю-
‚ чение #ММ
бит 1: МР - управляет тем, как исполняется команда У/АТТ. Должен быть
установлен для совместимости с программами, написанными для 80286
и 80386 и использующими эту команду
бит 0: РЕ- если он равен 1, процессор находится в защищенном режиме
(остальные биты зарезервированы, и программы не Должны +изменять их зна-
чения)
СВ: зарезервирован
СК2: регистр адреса ошибки страницы
Когда происходит исключение #РЕ из этого регистра можно прочитать линей-
НЫЙ адрес, обращение к которому вызвало исключение.

СВЗ (РОВК): регистр основной таблицы страниц


биты 31-11: 20 старших бит физического адреса начала каталога страниц,
если бит РАЕ в СКА равен нулю, или
биты 31-5: — 27 старших бит физического адреса ‘таблицы указателей на ка-
талоги страниц, если бит РАЕ = 1
бит 4 (80486+): бит РСР (запрещение кэширования страниц)— этот бит зап-
рещает загрузку текущей страницы в кэш-память (например,
если произошло прерывание и система не хочет, чтобы обра-
ботчик прерывания вытеснил основную программу из кэша)
‘бит3 (80486+): бит РУУТ (бит сквозной записи страниц) - управляет методом
записи страниц во внешний кэн!
СКА: этот регистр (появился только в процессорах Репнит) управляет новы-
ми возможностями процессоров. Все эти возможности необязательно присут-
ствуют, и их надо сначала проверять с помощью команды СРОИШ
бит 9: Е$К- разрешает команды быстрого сохранения/восстановления состо-
яния ЕРО/ММХ ЕХЗАУЕ и ЕХЕЗТОВ (Репиит П) |
бит 8: РМС- разрешает выполнение команды ВОРМС для программ на всех
уровнях привилегий (при РМС - 0 - только на уровне 0) - Репиит Рго
и выше | о
бит 7: РСЕ- разрешает глобальные страницы (бит 8 атрибута страницы),
которые не удаляются из ТЕВ при переключении задач и записи в СВЗ
(Репйит Рго и выше) |
бит 6: МСЕ - разрешает исключение #МС
бит 5: РАЕ - включает 36-битное физическое адресное пространство -—
Репбит Рго ивыше ,
бит 4: РЗЕ- включает режим адресации с 4-мегабайтными страницами.
бит 3: РЕ- запрещает отладочные прерывания по обращению к портам
бит 2: Т$Р- запрещает выполнение команды ВОТ$С для всех программ, кро-
ме программ, выполняющихся на уровне привилегий 0
{ Процессоры ние! в защищенном режиме
бит 1: РУГ - разрешает работу флага УТЕ в защищенном режиме, что может
позволить некоторым программам, написанным для уровня привилегий
0, работать на более низких: уровнях
бит 0: УМЕ - включает расширения режима У86 — разрешает работу флага
УТЕ для У86-приложений

| 10.1.4. Отладочные регистры |


Эти восемь 32-битных регистров (ОВ0- ОВ7) позволяют программам, выпол-
няющимся на уровне привилегий 0, определять точки останова, не модифицируя
код программ, например для отладки ПЗУ или программ, применяющих слож-`
ные схемы защиты от трассировки. Пример отладчика, использующего эти реги-
стры, — ЗоЁТСЕ.
ОК7 (ОСБ)- регистр управления отладкой
биты 31-30: поле ГЕМ для точки останова 3 (размер точки останова)
° 00-1 байт
01 — 2 байта
00 - не определен (например, для останова при выполнении) 11-4 байта
биты 29—28: поле В/\ для точки останова 3 (тип точки останова)
00 — при выполнении команды |
01 - при записи
10 — при обращении к порту (если бит РЕ в регистре СКА -= 1)
11 - при чтении или записи
биты 27—26; поле Г.ЕМ для точки останова 2
биты 25-24: поле В/У для точки останова 2
биты 23—22: поле ГЕМ для точки останова 1
биты 21-20: поле В/У для точки останова 1
биты 19-18: поле ГЕМ для точки останова 0
биты 17-16: поле К/\М для точки останова 0
биты 15-14: 00 р
бит 13: бит СО - включает режим, в котором любое обращение к отладочному .
| регистру, даже из кольца защиты 0, вызывает исключение #П0В (этот
бит автоматически сбрасывается внутри обработчика исключения)
биты 12-10: 001
бит 9: бит СЕ - если этот бит 0, точка останова по обращению к данным мо-
жет не сработать или сработать на несколько команд позже, так что его
лучше всегда сохранять равным 1
бит 7: бит СЗ - точка останова 3 включена
бит 5: бит С2 -— точка останова 2 включена
бит 3: бит СЕ - точка останова 1 включена
бит 2: бит С0 -— точка останова 0 включена
биты 8, 6, 4, 2, 0: биты Г.Е, 1.3, 1.2, ГЛ, 1.0 - действуют так же, как СЕ - С0, но
обнуляются при переключении задачи! (локальные точки
останова)
РЕ 058)- регистр. состояния отладки: содержит информацию`о причине
отдадочного останова для обработчика исключения #О0В
биты 31-16: единицы
бит 15: ВТ - причина прерывания:- тладочный бит. в Т5$: задачи, в которую
только что произошло. переключение
бит:14: В$ — причина прерывания— флаг трассировки ТЁ из регистра Е1.АС$
бит 13: ВО - причина прерывания — следующая команда собирается писать
или читать отладочный регистр, и бит СО в 0Е7 установлен в 1.
бит 12: 0
биты 11-4: единицы
бит 3: ВЗ — выполнился останов в точке 3
бит 2: В2 — выполнился останов в точке 2
бит1: В1 — выполнился останов в точке 1
бит 0: ВО - выполнился останов в точке 0
Процессор не очищает биты причин прерывания в данном регистре, так что об-
работчику исключения #ПВ следует делать это самостоятельно. Кроме того, од-
новременно может произойти прерывание по нескольким причинам, тогда более
одного бита будет установлено.
ОВА - 085 зарезервированы. На процессорах до Репиит или в случае, если
бит ОЕ регистра СКА равен нулю, обращение к этим регистрам приводит
к обращению к ОВб и ОВ7 соответственно. Если бит РЕ = 1, происходит
исключение #00.
ОВО- ОВЗ содержат 32-битные линейные адреса четырех возможных точек
останова по доступу к памяти
Если условия для отладочного останова выполняются, процессор вызывает
исключение #ОВ.

10.1.5. Машинно-специфичные регистры


Это большая группа регистров (более ста), назначение которых отличается
в моделях процессоров Ге! и даже иногда в процессорах одной модели, но раз-
ных версий. Например, регистры Репиит Рго МТКВ (30 регистров) описывают,
какой механизм страничной адресации используют различные области памяти —
не кэшируются, защищены от записи, кэшируются прозрачно и т. д. Регистры
Репиии Рго МСС/МСГ (23 регистра) используются для автоматического обна-
ружения и обработки аппаратных ошибок, регистры Репииют ТВ (12 регистров) —
для тестирования кэша и т. п. При описании соответствующих команд мы рас-
смотрим только регистр Репёиш Т$С - счетчик тактов процессора и группу из
четырех регистров Репйит Рго, необходимую ‘для подсчета различных событий
(число обращений к кэшу, умножений, команд ММХ ит. п.). Эти регистры оказа-
лись настолько полезными, что для работы с ними были введены дополнитель-
ные команды —- ВОТ$С и КОРМС.

16 Зак. 459
ЕТ ШИНИИИ | Процессоры ще! в защищенном режиме |
10.2. Системные и привилегированные команды.
Команда Назначение ' | Процессор
ЕСОТ источник | Загрузить регистр СОТВ 80286

Команда загружает значение источника (6-байтная переменная в памяти) в ре-


гистр СОТВ. Если текущая разрядность операндов 32 бита, в качестве размера 3
таблицы глобальных дескрипторов используются младшие два байта операнда,
а в качестве ее линейного адреса — следующие четыре. Если текущая разрядность 4
операндов - 16 бит, для линейного адреса используются только байты 3, 4, 5 из 4
операнда, а в самый старший байт адреса записываются нули.
Команда выполняется исключительно в реальном режиме или при.СРЕ. = 0.

Команда. ° Назначение Процессор


СОТ приемник Прочитать регистр СОТВ 80286

Помещает содержимое регистра СОТКЬ в приемник (6-байтная переменная в па-


мяти). Если текущая разрядность операндов - 16 бит, самый старший байт этой *
переменной заполняется нулями (начиная с 80386, а 286 заполнял его единицами). |

_ Команда - Назначение Процессор ,

НОТ источник Загрузить регистр ШОТА 80286


—щ—Щ—ыЫы—ыыы=—=ы=ыы——=ы—ы—ы—ы—ЫЩы——ЩШы——_———Ы—————————Щ—=мы—ы—ы——ыыыЫыы—ыЫы=ыы"—ы—ы—ы———

Загружает регистр 1.ОТЕ, основываясь на селекторе, находящемся в источни-


ке (16-битном регистре или переменной). Если источник - 0, все команды, кроме {
ГАВ, 1.5Т., УЕКК и УЕКУ,, обращающиеся к’дескрипторам из ГОТ, будут вызы- }
вать исключение #СР. |
Команда выполняется только в защищенном режиме с СР. = 0.

Команда | Назначение Процессор


. ЗЬОТ приемник . Прочитать регистр СОТА 80286

Помещает селектор, находящийся в регистре Г.ОТЕ, в приемник (16- или 32-


битный регистр или переменная). Этот селектор указывает на дескриптор в СОТ
текущей ГОТ. Если приемник 32-битный, старшие 16 бит обнуляются на РепНит
Рго и не определены на предыдущих процессорах. ^
Команда‘ выполняется только в защищенном режиме.
Команда Назначение Процессор
ЕТЯ источник . Загрузить регистр ТВ — . 80286

Загружает регистр задачи ТК, основываясь на селекторе, находящемся в ис-


точнике (16-битном регистре или переменной), который указывает на сегмент со-
стояния задачи (Т3$). Эта команда обычно используется для загрузки первой `
задачи при инициализации. многозадачной системы.
Команда выполняется только в защищенном режиме с СР = 0.
Системные команды

Команда г. со Назначение . . Процессор


ТВ приемник . - - Прочитать регистр ТВ . 80286

Помещает селектор, находящийся в регистре ТВ, в приемник (16- или 32-бит-


ный регистр или переменная). Этот селектор указывает на дескриптор в СОТ,
описывающий Т$$ текущей задачи. Если приемник 32-битный, старшие 16 бит
обнуляются на Репиит Рго и не определены на предыдущих процессорах.
Команда выполняется только в защищенном режиме.
Команда -. ^ Назначение . Процессор
НОТ источник Загрузить регистр ОТВ | 80286

_ Загружает значение источника (6-_байтная переменная в памяти) в регистр


ГШТЕ. Если текущая разрядность онерандов — 32 бита, в качестве размера табли-
цы глобальных дескрипторов используются младшие два байта операнда, а в ка-
честве ее линейного адреса — следующие четыре. Если текущая разрядность опе-
рандов — 16 бит, для линейного адреса используются только байты 3, 4, 5 из
операнда, а самый старший байт адреса устанавливается нулевым.
_ Команда выполняется исключительно в реальном режиме или при СРГ.= 0.

Команда Назначение Процессор


З!ОТ приемник Прочитать регистр ОТВ | 80286
1 .

‚ Помещает содержимое регистра СОТЕ в приемник (6-байтная переменная в па-


мяти). Если текущая разрядность операндов - 16 бит, самый старший байт этой пе-
ременной заполняется нулями (начиная с 80386, а 286 заполнял его единицами).

Команда ` Назначение . : Процессор


МОУ приемник, источник Пересылка данных в/из управляющие/их 80386
и отладочные/ых регистры/ов

Приемником или источником команды МОУ могут быть регистры СВО —С ВА


и РВ - ОКУ. В этом случае другой операнд команды обязательно должен быть
32-битным регистром общего назначения. При записи в регистр СВЗ сбрасыва-
ются все записи в ТГВ, кроме глобальных страницв Репиит Рго. Во время моди-
фикации бит РЕ или РС в СВО и РСЕ, РЗЕ или РАЕ в СВА сбрасываются все
записи в ТГВ без исключения.
Команды выполняются только в реальном режиме или с СР. - 0.
Команда `` ° Назначение Процессор
ЕМ$М/ источник Загрузить слово состояния процессора 80286

‚ Копирует младшие четыре бита источника. (16-битный регистр или перемен-


ная) в регистр СКО, изменяя биты РЕ, МР ЕМ и Т$. Кроме того, если бит РЕ = 1,
этой командой ето нельзя обнулить, то есть нельзя выйти из защищенного режима.
в
484 1 | „1 ПрПроцессоры
р нее! в защищенном р ежиме }
Команда .М$\ существует только для совместимости, с. процессором 80286,
и вместо нее всегда удобнее использовать тоу сг0,еах
Команда выполняется только. в реальном режиме или с СР, = 0,
Команда Назначение Процессор
$М$М/ приемник Прочитать слово состояния процессора 80286

Копирует младшие 16 бит регистра СКО в приемник (16- или 32-битный регистр
или 16-битная переменная). Если приемник 32-битный, значения его старших би-
тов не определены. Команда $М$\У нужна для совместимости. В процессором
80286, и вместо нее удобнее использовать тоу еах,сгО. >

Команда | Назначение Процессор


ал$ Сбросить флаг Т$ в СКО | 80286

Команда сбрасывает в 0 бит Т$ регистра СВО, который устанавливается про-


цессором в 1 после каждого переключения задач. СГТ$ предназначена для син-
хронизации сохранения/восстановления состояния ЕР в многозадачных опера-
ционных системах: первая же команда ЕРО’в новой задаче при Т$ = 1 вызовет
исключение #ММ, обработчик которого сохранит состояние 'ЕРУ для старой за:
дачи и восстановит сохраненное ранее для новой, после чего выполнит команду
СГТЗ и вернет управление.
Команда выполняется только в реальном режиме или с СР, = 0.
——————аа—А==——А—А—А—3А—АЧААС—————А—————————Ан/и—/—/АС//—Аннааи/АЧ/,/——
Команда | Назначение В Процессор.
АЯРЕ приемник, источник Коррекция поля ВРЕ селектора 80286

Команда сравнивает поля КРТ, двух сегментных селекторов. Приемник (16-бит-


ный регистр или переменная) содержит первый, а источник (16-битный регистр) —
второй. Если КРЕ приемника меньше, чем КРТ. источника, устанавливается флаг
2Е, и ВРГ. приемника становится равным КРГ. источника.В противном случае
2Е = 0 и никаких изменений не происходит. Обычно эта команда используется _
операционной системой, чтобы увеличить КР1. селектора, переданного ей прило-
жением, с целью удостовериться, что он соответствует уровню привилегий при-
ложения (который система может взять из ВРГ. сегмента кода приложения, нахо-
дящегося в стеке).
° Команда выполняется только в защищенном режиме (с любым СРГ.).
—————————А—СаАА,,/Ч/С/С/С//С/А/С/С/АС/СЧ/СЧС/СА/С/СЧС/А/А/А/ЗА——„„’ЧЗЗ
Команда : р Назначение | 2} Процессор
ГАВ приемник, источник | ‘Прочитать права доступа сегмента 80286
|

Копирует байты, отвечающие за права доступа из дескриптора, описываемого


селектором, который находится в источнике (регистр или переменная), в источник
(регистр) и устанавливает флаг 2Е Если используются 16-битные операнды, копи-
руется только байт 5 дескриптора в байт 1 (биты 8-15) приемника. Для 32-битных
Системные команды `` М рис
операндов дополнительно копируются старшие четыре бита `(для‘сегментов кода
и данных) или весь шестой байт дескринтора (для системных сегментов) в байт 2
приемника. Остальные биты приемника обнуляются. Если СРЬ > ОРЁ или КРГ. >
ОРЕ, — ‘для неподчиненных сегментов кода, если селектор или дескриптор оши-
бочны или в других ситуациях, когда программа не сможет пользоваться этим се-
лектором, команда Г.АВ возвращает 2 = 0. —.
Команда выполняется только в защищенном режиме.
ии ии ооарииаиииориион жити ити живи вито

Команда в Назначение. "` Процессор

1$ приемник, источник . _ Прочитать лимит сегмента | 80286

Копирует лимит сегмента (размер минус 1) из дескриптора, селектор для ко-


торого находится в источнике (регистр или переменная), в приемник (регистр)
и устанавливает флаг 2Р в 1. Если бит гранулярности в дескрипторе установлен
и лимит хранится в единицах по 4096 байт, команда Т.5Т. переведет его значение
в байты. Если используются 16-битные операнды и лимит не умещается в при-
емнике, егостаршие биты теряются. Как и в случае с Г.АК, эта команда проверя-
ет доступность сегмента из текущей программы: если сегмент недоступен, в при-
емник ничего не загружается и флаг7Е сбрасываетсяв 0... _ В
Команда выполняется только в защищенном режиме.
до
——А——
—_ А
————дд———д ———————дд—__
Команда Назначение : Процессор
—ы—
——— д д—д——д—д—д___—дд—цдцд—д—д—д—д—д—о_цкд—дВХДХХ

УЕВЯ источник Проверить права на чтение \ 80286

УЕВМ/ источник Проверить права на запись 80286

Команды проверяют, доступен ли сегмент кода или данных, селектор которого


находится в источнике (16-битный регистр или переменная), для чтения (УЕВЕ)
или записи (УЕВУ/) с текущего уровня привилегий. Если сегмент доступен, то
команды возвращают 7Е = 1, иначе — 2Е = 0. | |
Команды выполняются только в защищенном режиме.

Команда | `Назначение р ‚ ^ Процессор


имУО Сбросить кэш-памятъ 80486
МВИМУО - [Записать и обросить кэш-память 80486.

__ Эти команды объявляют все содержимое внутренней кэш-памяти процессора


недействительным и подают сигнал для сброса внешнего кэша, так что после этого .
все.обращения к памяти приводят к заполнению кэша заново. Команда \У/ВТМУО
кэша в память, команда ПУУЛ приводит к по-
предварительно сохраняет содержимое
тере всей информации, которая попала в кэш, но еще не была перенесена в память.
Команды выполняются только в реальном режиме или‚с СРИ. = 0.

Команда .. ООВ Назначение . Процессор

МУЕРС источник .. Аннулировать страницу 80486 .


ЕТ: ИОШНИИНИНИЙ Процессоры те! в защищенном режиме
Аннулирует (объявляет недействительным) элемент буфера ТТ.В, описываю-
щий страницу памяти, которая содержит источник (адрес в памяти).
Команда выполняется только в реальном режиме или с СР, = 0.

Команда Назначение Процессор

т `Остановить процессор 8086

Переводит процессор в состояние останова, из которого его может вывести \


только аппаратное прерывание или перезагрузка. Если причиной было прерыва-
ние, то адрес возврата, помещаемый в стек для обработчика прерывания, указы-
вает на следующую после НЕТ команду. |
Команда выполняется только в реальном режиме или с СР1. = 0.

Команда ` Назначение Процессор

3 УМ Выйти из режима ММ Р5

Применяется для вывода процессора из режима $ММ, использующегося для


сохранения состояния системы в критических ситуациях (например, при выклю-
чении электроэнергии). При входе в ЗММ (происходит во время поступления со-
ответствующего сигнала на процессор от материнской платы) все регистры, вклю-
чая системные, й другая информация сохраняются в специальном блоке памяти —
ЗМКАМ, а при выходе (который и осуществляется командой В$М) все восста-
навливается. | |
Команда выполняется только в режиме $ММ.

Команда | ` Назначение Процессор


ВОМ$В Чтение из М$А-регистра Р5,
\МАМ$Я Запись в МЗЯ-регистр Р5

Помещает содержимое машинно-специфичного регистра с номером, указанным


в ЕСХ, в пару регистров ЕОХ:ЕАХ (старшие 32 бита в ЕОХ и младшие в ЕАХ)
(ВОМ$К) или содержимое регистров ЕОХ:ЕАХ - в машинно-специфичный ре-
гистр с номером в ЕСХ. Попытка чтения/записи зарезервированного или отсут-
ствующего в данной модели МК приводит к исключению #СР(0).
Команда выполняется Только в реальном режиме или с СРИ. = 0.
Команда ‚ Назначение Процессор

` ВОТ$С | Чтение ‘из счетчика тактов процессора Р5

Помещает в регистровую пару ЕРХ:ЕАХ текущее значение счетчика тактов —


‚ 64-битного машинно-специфичного регистра Т$С, значение которого увеличива-
ется на 1 каждый такт процессора с момента его последней перезагрузки. Этот
машинно-специфичный регистр доступен для чтения и записи с помощью. команд
ВОМ5В/МУЕМ5К как регистр номер 10, причем на Репйит Рго при записи в него
старшие 32 бита всегда обнуляются. Так как машинно-специфичные регистры
Системные команды ‘ ПИ ||| 13379
могут отсутствовать на отдельных моделях процессоров, их наличие всегда сле-.
дует определять посредством СРИТО (бит 4 в ЕОХ - наличие Т$С).
Команда выполняется на любом уровне привилегий, если бит ТЗР в регистре ,
СКО равен нулю; и только в реальном режиме или с СРГ,= 0, если бит Т$О = 1.
ий тиви иво
о отильииитодоиианивитиивлжнодотиолжчотчитонижиисн
р
отоиииииьваноьиаивнитьводитивв
Процессо
пиши

Команда Назначение—оцо5ок5к5—дккдкд_д_докккодкдкдкдцддддкд ДХДя>


щШшиЙЙ——
——_—д—д—ддд—_—_—оаа——ы—и————Аыи_

АОРМС у Чтение из счетчика событий ` `Рб

Помещает значение одного из двух программируемых счетчиков событий (40-


битные машинно-специфичные регистры СЛВ и С2Ь для Репцит Рго и Репиити 11)
в регистровую пару ЕОХ:ЕАХ. Выбор читаемого регистра определяется числом 0
или 1 в ЕСХ. Аналогичные регистры есть и на Рени (и Супх 6х86МХ), но они
имеют номера 11В и 12, и к ним можно обращаться только при помощи команд
ВОМ$В/\ЕМ$Е. `
Способ выбора типа подсчитываемых событий тоже различается в Рейт
и Репнит Рго — для РепНит надо выполнить запись в 64-битный регистр МК
0118, разные двойные слова которого управляют выбором режима каждого из
счетчиков и типа событий, а для Репнит Рго/Репиит П надо выполнить запись
в регистр 187 для счетчика 0 и 188Вдля счетчика 1. Соответственно и наборы со-
бытий между этими процессорами сильно различаются: 38 событий на Репита,
83 — на Репнита Рго и 96 - на Репйит П.
` \

Команда Назначение | Процессор


ди
боманае
ЗУЗЕМТЕВ Быстрый системный вызов РИ

ЗУЗЕХТ | Быстрый возврат из системного вызова = РИ

Команда $УЗЕМТЕЕВ загружает в регистр С$ число из регистра М$В #174В,


в регистр ЕГР - число из регистра М$В. #176, в регистр 5$ -- число, равное С +
8 (селектор на следующий дескриптор), и в регистр ЕЗР - число из МУК #1755.
Эта команда предназначена для передачи управления операционной системе - ее
можно вызывать с любым СР. а вызываемый код должен находиться в бессег-
ментной памяти с СРТ, = 0. На самом деле ЗУЗЕМТЕК модифицирует дескрипторы
используемых сегментов -- сегмент кода будет иметь ОРГ = 0, базу 0, лимит 4 Гб,
станет доступным для чтения и 32-битным, а.сегмент стека также получит базу 0,
лимит 4 Гб, ОРТ. = 0, 32-битный режим, доступ для чтения/записи и установлен-
ный бит доступа. Кроме того, селекторы С$ и $$ получают КРЬ = 0.
Команда ЗУЗЕХ!Т загружает в регистр С$ число, равное содержимому регист-
‚ ра М$В #1746 плюс 16, в ЕТР - число из ЕОХ, в 55 - число, равное содержимому
регистра М$К #1748 плюс 24, ив ЕЗР - число из ЕСХ. Эта команда предназначена
для передачи управления в бессегментную модель памяти с СРЬ= 3 и тоже моди-
фицирует дескрипТоры. Сегмент кода получает ПРЕ. - 3, базу 0, лимит 4 Гб, доступ
для чтения, перестает быть подчиненным и становится 32-битным. Сегмент стека
также получает базу 0, лимит 4 Гб, доступ для чтения/записи и 32-битную разряд-
ность. Поля ВРЕ. в С$ и $$ устанавливаются в 3.
_ ЕН! Процессоры те] в защищенном режиме
Поддержку команд ЗУЗЕМТЕК/ЗУЗЕХИТ всегда следует проверять
при помо-
щи команды СРОТО (бит 11). Кроме того, надо убедиться, что номер
модели про-.:
цессора не меньше трех, так как Репйит Рго (тип процессора 6,
модель 1) не име-
ет команд ЗУЗЕМТЕВ/ЗУЗЕХИТ, но бит в СРОШ возвращается
равным [. 3
ЗУЗЕМТЕК выполняется лишь в защищенном режиме, а ЗУЗЕХ
Т -— только-3
с СРИ. = 0.

10.3. Вход и выход из защищенного режима


Итак, чтобы перейти в защищенный режим, достаточно установ
ить бит РЕ — |
нулевой бит в управляющем регистре СКО, и процессор немедл
енно окажется
в защищенном режиме. Единственное дополнительное требова
ние, которое -з
предъявляет Пице|, - в этот момент все прерывания, включая немаски
руемое, долж- |
ны быть отключены.
; рмо. азт
; Программа, выполняющая переход в защищенный режим и
немедленный возврат.
‚; Работает в реальном режиме 00$ и в 005-окне №1па0из
95 (\1п40и$ перехватывает
‚ исключения, возникающие при попытке перехода в защищенный режим из \86,
‚ И Позволяет нам работать, но только на минимальном уровне привилегий).

; Компиляция: °
; ТАМ:
; Тазт /п ртО.азт
; СИшк /х. ИЕ ро. 063
; МАЗ: .
; 1 /с ро. азт
; Илк рт0.05},,МА.,,
‚; @хе2Ь1п рто.ехе рт. сом
; МАЗМ: :
; мазт рт. азт.
; упак Ре ртб.об] Рогт 00$ СОМ

.109е1 пу
„.соде
.386р ; Все наши примеры рассчитаны ‘на 80386.
огд 1001 ; Это СОМ-программа. |
зтагт. *
; Подготовить сегментные регистры.
ризп [е-
рор 93 | ; 0$ - сегмент данных (и кода) нашей программы.
рузА 088008
, рор ез ° °, Е - сегмент видеопамяти.
; Проверить, находимся ли мы уже в’ защищенном ‘режиме:
Мом вах, сго — ; Прочитать регистр СВО.
‚ Тезт а], 1 ; Проверить бит РЕ, ,
32 по_\У86 ‚ если он ноль - мы можем продолжать
‚ Иначе - сообщить об ошибке и ‘выйти.
оу ав, 9 ; Функция 00$ 09н.
Входи выход из защищенного режима ПЕТЯ
моу вх, от Тзет У86_мз9; 05:0Х’- адрес. строки.
1 21 р . 5 Вывод на экран..
гет ; Конец СОМ-программы,
; (поскольку это защищенный режим, в котором работает нава 00$-програма,
‚ То это должен быть \86).
\86_тз0 [6 “Процессор в рехиме \86 - нельзя переключиться в РМ$”

‚ Сюда передается управление, если мы запущены в реальном режиме.


по_\86: . ` й
‚. Запретить прерывания. .
с11 `
‚ Запретить немаскируемое прерывание.
п а1, 708 ‚ Индексный порт СМ05.
ог 81,808 .— ; Установка бита 7 в нем запрещает МТ.
и 701,а]
; Перейти в защищенный режим.
оу еах, сго ; Прочитать регистр СНО.
ог 21,1 ‚ ‘; Установить бит РЕ, |
оу сгО, еах ; с этого момента. мы в защищенном режиме.
; Вывод на экран. `
хог 91, 91 ; ЕЗ:0Т - начало видеопамяти.
му $1, оТ{зет теззаде; 05:$Г - выводимый. текст.
мо\ сх, теззаде_1 7
гер тпоузЬ ; Вывод текста.
тоу ах, 07201” .; Пробел с атрибутом 07п.
оу сх, гезЕ_$сг ; Заполнить этим символом остаток экрана.
гер $105
; Переключиться в реальный режим.
тоу еах, сго ‚Прочитать С80,
апа а], ОРЕВ ; Сбросить бит РЕ.
[Те сг0, еах ; С этого момента- процессор работает в реальном режиме.
; Разрешить немаскируемое прерывание.
п а], 70 | ; Индексный порт СМ0$.
апа а1, О7ЕН ; Сброс бита 7 отменяет блокирование ММТ.
о 70, а1
; Разрешить прерывания.
$11 |
; Подождать нажатия любой клавиши.
А ап, 0
11 161
; Выйтииз СОМ-программы.
ге
; Текст сообщения с атрибутом после каждого символа для прямого вывода на экран.
пеззаде фе "Н’,7, 'е’,7, *1',7,'1',7,
0’, 7, о’, И’, Я, °3',7
95 Г.Г, РТ,М’, 7
; Его длина в байтах.
пеззаде_1 = $-теззаде
Длина оставшейся части экрана в словах.
гезт_зсг = (80*25)-(2*теззаде_1)
епд эта
ЕСТИИНШИ
ШИ ШИИИ И Процессоры пе! в защищенном режиме |
В разделе 6.1 при рассмотрении адресации в защищенном режиме говорилось
о том, что процессор, обращаясь к памяти, должен определить адрес начала сег-
мента из дескриптора в таблице дескрипторов, находящейся в памяти, используя
селектор, находящийся в сегментном регистре, в качестве индекса. Одновремен- 2
но при этом мы обращаемся к памяти из защищенного режима, вообще не описав
никаких дескрипторов, и в сегментных регистрах у нас находятся те же числа, что
и в реальном режиме.
Дело в том, что, начиная с процессора 80286, размер каждого сегментного ре-
гистра — С5, 55, 05, Е$, Е5 и С$- не два байта, а десять, восемь из которых нелдо-
ступны для программ, точно так же, как описанные выше регистры Г.ОТВ и ТВ.
В защищенном режиме при записи селектора в сегментный регистр процессор ко-
пирует весь определяемый этим селектором дескриптор в скрытую часть сегмен-
тного регистра и больше не пользуется этим селектором вообще. Таблицу деск-
рипторов можно уничтожить, а обращения к памяти все равно будут выполняться,
как и раньше. В реальном режиме при записи числа в сегментный регистр процес-
сор сам воздает соответствующий дескриптор в его скрытой части. Он описывает
16-битный сегмент, начинающийся по указанному адресу с границей 64 Кб. Когда,
мы переключились в защищенный режим в программе риз0.азт, эти Дескрипторы |
остались на месте и мы могли обращаться к памяти, не принимая во внимание, ,. |
|
что у нас написано в сегментном регистре. Разумеется, В такой ситуации любая :
` попытка записать в сегментный регистр число привела бы к немедленной ошибке
(исключение #СР с кодом ошибки, равным загружаемому значению).

10.4. Сегментная адресация


10.4.1. Модель памяти в защищенном режиме }
Мы уже неоднократно описывали сегментную адресацию, рассказывая о. на-
значении сегментных регистров в реальном режиме или о программировании для
расширителей РО$ в защищенном режиме, но каждый раз для немедленных нужд
требовалась только часть всей этой сложной модели. Теперь самое время рассмот-
реть ее полностью.
Для любого обращения к памятив процессорах [пе] используется логический
адрес, состоящий из 16-битного селектора, который определяет сегмент, и 32- или
16-битного смещения- адреса внутри сегмента. Отдельный сегмент памяти — это
независимое защищенное адресное пространство. Для него указаны размер, раз-
решенные способы доступа (чтение/запись/исполнение кода) и уровень приви-
легий (см. раздел 10.7). Если доступ к памяти удовлетворяет всем условиям за-
щиты, процессор преобразует логический адрес в 32- или 36-битный (на Р6) ли-
нейный. Линейный адрес — это адрес в несегментированном непрерывном
адресном пространстве, совпадающий с физическим ‘адресом в памяти, если от-
ключен режим страничной адресации (см. раздел 10.6). Чтобы получить линей-
ный адрес из логического, процессор добавляет к смещению линейный адрес на-
чала сегмента, который хранится в поле базы в сегментном дескрипторе. Сегмен-
тный дескриптор - это 8-байтная структура данных, расположенная в таблице
Сегментная адресации _ М ЕСИ
СОТ. или ГОТ. адрес таблицы находится в регистре СОТВ или ГОТВ, а номер
дескриптора в таблице определяется по значению селектора.
Дескриптор для селектора, находящегося в сегментном регистре, не считывает-
ся из памяти при каждом обращении, а хранитая в скрытой части сегментного ре-
гистра и загружается только при выполнении команд МОУ (в сегментный регистр),
РОР (в сегментный регистр), 1.05, 1.Е$, 155, 165, [.Е$ и дальних команд перехода.

10.4.2. Селектор
Селектор - это 16-битное число следующего формата:
биты 16-3: номер. дескриптора в таблице (от 0 до 8191)
бит 2: 1 - использовать ГОТ, 0 - использовать СОТ
биты 1-0: запрашиваемый уровень привилегий при обращении к сегменту
`’и текущий уровень привилегий для селектора, загруженного в С$
Селектор, содержащий нулевые биты 16-3, называется нулевым и требуется
для загрузки в неиспользуемые сегментные регистры. Любое обращение в сег-
мент; адресуемый нулевым селектором, приводит к исключению #СР(0), в то
время как загрузка в сегментный регистр ошибочного селектора вызывает исклю-
чение #СР(селектор). Попытка загрузки нулевого селектора в 55 или С$ также
вызывает #СР(0), поскольку эти селекторы используются всегда.

10.4.3. Дескрипторы
Дескриптор - это 64-битная (восьмибайтная) структура данных, которая мо-
жет встречаться в таблицах СОТ`и ГОТ. Он способен описывать сегмент кода, сег-
мент данных, сегмент состояния задачи; быть шлюзом вызова, ловушки, прерыва-
ния или задачи. В СОТ также может находиться дескриптор ГОТ.
Дескриптор сегмента данных или кода (подробно рассмотрен в разделе 6.1)
байт 7: биты 31-24 базы сегмента.
байт 6: бит 7: бит гранулярности (0 — лимит в байтах, 1 - лимит в 4-килобайт-
ных единицах)
бит 6: бит разрядности 0 — 16- битный, 1 - 32-битный сегмент)
бит 5: 0
бит 4: зарезервировано для операционной с системы
биты 3-0: биты 19 - 16 лимита
байт 5: (байт доступа)
бит 7: бит присутствия сегмента
биты 6-5: уровень привилегий дескриптора (ОРГ.)
бит 4: 1 (тип дескриптора — несистемный)
бит 3: тип сегмента (0 — данных, 1 — кода)
бит 2: бит подчиненности для кода, бит расширения вниз для данных
бит 1; бит разрешения чтения для кода, бит разрешения записи для данных
бит 0: бит доступа (1 - к сегменту было обращение)
байт 4: биты 23—16 базы сегмента
байты 3-2: биты 15-0 базы
байты 1-0: биты 15-0 лимита
ЕЕУНИИШИИВИИ |Процессоры н\е! в защищенном режиме: |
Таблица 22. Типы системных дескрипторов

З3арезервированный тип Зарезервированный тип [1


| ди 16-битный Т$$ Свободный 32-битный 15$
|_2 | Дескриптор таблицы ГОТ Зарезервированный тип
Занятый 16-битный Т$$ Занятый 32-битный Т$$
16-битный шлюз вызова 32-битный шлюз вызова
Шлюз задачи ' Зарезервированный тил
16-битный шлюз прерывания 32-битный шлюз прерывания `
.| 7 | 16-битный шлюз ловушки 32-битный шлюз ловушки

Если в дескрипторе бит 4 байта доступа равен 0, дескриптор называется сис-. |


темным. В этом случае биты 0-3 байта доступа определяют один из 16 возмож- 1
ных типов дескриптора (см. табл. 22). |
Дескрипторы шлюзов
Дальние САМ. или ] МР на адрес слюбым смещением и с селектором, указываю-
щим на дескриптор шлюза вызова, приводят к передаче управления по адресу, кото-
рый есть в дескрипторе. Обычно такие дескрипторы используются для передачи уп-
равления между`сегментами с различными уровнями привилегий (см. раздел 10.7).
СА. или ] МР на адрес с селектором, указывающим на шлюз задачи, приво-
дят к переключению задач (см. раздел 10.8).
Шлюзы прерываний и ловушек используются для вызова обработчиков пре-
рываний и исключений типа ловушки (см. раздел 10.5).
байты 7-6: биты 31 - 16 смещения (0 для 16-битных шлюзов и шлюза задачи)
байт 5: (байт доступа)
бит 7 — бит присутствия сегмента
‚биты 6-5: ОРТ, - уровень привилегий дескриптора
бит 4: 0
‘биты 3-0: тип шлюза (4, 5, 6, 7, С, Е, Е)
байт 4: биты 7-5: 000
биты 4-0: 00000 или (для шлюза вызова) число двойных слов, которые
будут скопированы из стека вызывающей задачи в стек вы-
зываемой
байты 3-2: селектор сегмента
байты 1—0: биты 15-0 смещения (0 для шлюза задачи)
Дескрипторы Т55 и ГОТ х
‚Эти два типа дескрипторов применяются в многозадачном режиме, о котором
рассказано далее. Т5$ — сегмент состояния задачи, используемый для хранения
всей необходимой информации о каждой задаче в многозадачном ‘режиме. ГОТ —
таблица локальных дескрипторов, своя для каждой задачи. |
Форматы дескрипторов совпадают с форматом дескриптора для сегмента кода
или данных, но при этом бит разрядности всегда равен нулю и, естественно,
Сегментная адресация 42
номер типа сег”
системный бит равен нулю, а биты 3-0 байта доступа содержат
] МР и САМ. на адрес с селекто ром, соответствую-
мента (1, 2, 3, 9, В). Команды
щим Т$$ незанятой задачи, приводя т к перекл ючению задач.

10.4.4. Пример программы


сти, а для.
Мы будем пользоваться различными дескрипторами по мере надобно
Нах, где все.сегмен-
начала выполним переключениев 32-битную модель памяти
один для кода
ты имеют базу 0 и лимит 4 Гб. Нам потребуются два дескриптора -
ых дескрип тора с лимита ми 64 Кб, чтобы заг-
и один для данных - и два 16-битн
рузить их в С$ и 0$ перед возвратом в реальн ый режим. - |
выполнять
В комментариях к примеру ри 0.азт мы заметили, что его можно
ется уже в защище нном режиме.
в 2О5-окне УЛпдо\з 95, хотя программа запуска
т обраще ния к контро льным
Это происходит потому, что УЛпдо\з 95 перехватывае
нный режим, но толька с ми-
регистрам и позволяет программе перейти в защище
наши пример ы в этом разделе
нимальным уровнем привилегий. Все следующие
у добавим
будут рассчитаны на работу с максимальными привилегиями, поэтом
16006 прерывания
в программу проверку на запуск из-под УЛпдо\з (функция
т И
мультиплексора ПМТ 2ЕЪ).
ючении
Еще одно дополнительное действие, которое мы выполним при перекл
запуска компью тера для
в защищенный режим, — управление линией А20. После
ют адресные
совместимости с 8086 используются 20-разрядные адреса (работа
линейн ому адресу 100000
линии 'А0 - А19), так что попытка записать что-то по
тся установ кой бита 2
приведет к записи по адресу 00001. Этот режим отменяе
в 0. (Сущес твуют и дру-
в порту 92Ь и снова включается сбрасыванием этого бита
на материн-
гие способы, зависящие от набора микросхем, которые используются
ся максим ально возмож-
ской плате, но они необходимы в том случае, если требует
ная скорость переключения.) В |

; рт. азт
режиме.
‚ Программа, демонстрирующая работу с сегментами в защищенном
возвращается в 00$.
; Переключается в ‘модель Г1а{, выполняет вывод на экран и

‚ Компиляция:
; ТАЗМ:
; Тазт /ш рт!.азм
; Ик Их /3 ре]. 06)
; МАЗМ: | й
; № /с ри. аз *-.
; Ш1К рм1.063,,МИЕ,,,
; МАЗИ;
‚ ‘мазт рт. авт ^

5 мик Ее рт1.05) Рогм 00$


; 32"битный защищенный режим появился в 80386.
. 386р.

; 16-битный сегмент,в котором находится. код для. входа


; и выхода из защищенного режима. .
ИИ Процессоры Ме! в защищенном режиме
АН _$е9 зедтепт рага риБ]1с “соде” изе16
аззите С$:ВМ_зед,55:АМ_зтаск
ЗТагт:
; Подготовить сегментные регистры.
рузй `с3
рор 9$
‚ Проверить, не находимся ли мы уже в РМ.
оу еах, сго
тезт а1,1
| 32 по_\/86
‚ Сообщить и выйти.
моу 9х, ответ \86_тз9
егг_ех1{: у
° МОУ ан,9°
11 218 |
мм ап, 4Сп р
11 218 .
. У86_т$9 - 906‘. “Процессор в режиме У86 - нельзя переключиться в РМ$”
м1 п_ 50 [ее "Программа запущена под И\1п9омз - нельзя перейти в кольцо 0$”

; Может быть, это И1паом$ 95 делает вид, что РЕ=


по_\86: ы :
оу ах, 16001 ; Функция 16008
101 ЕВ ‚ прерывания мультиплексора.
тет а],а] ° ; Если АЁ =
ру. по_м1190\$ ; \№1п90м$ не запущена.
; Сообщить и выйти, если мы под \1паомз.
мо\ 9х, оРРзет м1п_тз9
фир ЗВогЕ ‘егг_ех1+
; Итак, ‘мы точно находимся в ‘реальном режиме.
по_м1п400\$:
‚ Если мы собираемся работать с 32-битной ‘памятью, стоит открыть А20.
11 а1, 928 °
ог ‚а1,2
ош 928,а1
‹ Вычислить линейный адрес метки РМ_ептгу.
хог ° вах, еах :
МОУ ах, РМ_5е9 ‚ АХ - сегментный адрес РМ_3е9.
$11 вах, 4 ; ЕАХ - линейный адрес _РМ_эе9.
ада еах, отРзет РМ_епфгу ; ЕАХ`- линейный адрес РМ_ептгу.
тоу мог рфг рт_ептгу_оТР,
еах ; Сохранить его.
; Вычислить базу для б0Т_1651405 и 60Т_166110$.
хог —,„ еах, еах
тому ах, с$ ; АХ - сегментный адрес ВМ_$е9.
911 еах, 4 ‚ ЕАХ - линейный адрес ВМ_$е0.
ризй еах
оу мог рег 60Т_165116$+2,ах ; Биты 15-0
Сегментная адресация `
МОУ мога- рег 60Т_1661105+2;ах
`зйг вах, 16 | |
ОУ Буте рег 60Т_1663 16$+4,а1 ; и биты 23-16,
пом Буде рег 60Т_1661409+4,а?
: Вычислить абсолютный адрес метки бот.
`рор еах | . ЕАХ - линейный адрес ВМ_зе9.
`ада ах, отРзет бот ‹ ЕАХ - линейный адрес 60Т.
ЮУ фмога рег 941г+2, еах : Записать его для СОТА.
: Загрузит ь таблицу глобальн ых дескрипт оров,
- 19% Тмог@ ртг 99г
‚ Запретить прерывания,
611
|
; Запретить немаскируемое прерывание.
{п а1, 70П -
ог. а], 80В
оц 70,а]
‚ Преключиться в защищенный режим.
МОУ еах, сго
ог а1,1
по сго, еах
в регистр 6$. .
; Загрузить новый селектор
6 ; Префикс изменения. разрядности операнда.
6
[6 ОЕАВ ; Код команды дальнего тр.
рт_епегу_о ТР 99 ? ‚ 32-битное смещение.
ди ЗЕЁ_#}а10$ ; Селектор.

передается управление при выходе из защищенного режима.


АМ_ гетигп: ; Сюда
; Переключиться в реальный режим.
ОУ еах, сго
апа а1, ОРЕВ
том сго, еах .
предвыборки и загрузить.С$ реальным сегментным адресом.
: Сбросить очередь
| Ге] ОЕАВ : Код дальнего тр.
и о $4 - . Адрес следующей команды,
м ВМ. $е9 ; Сегментный адрес АМ_$ед,
‚ Разрешить НМТ.
1п а}, 70Н
апд а1, 07ЕН
от 70,а1
; Разрешить другие прерывания.
$11
:; Подождать нажатия любой клавиши.
оу ап,0
1% 161
‚ Выйти из программы. .

ЮУ ай, 4Св
17 218
№1! Процессоры Не! в защищенном режиме
; Текст сообщения с атрибутами, который мы будем выводить на экран.
меззаде [е]) "Н’,7, 'е’,7, "1,7, "17,7, 0’, 7,’ ',Т, И’, "3,7, ",7
95 '3:,7,' 7, '6’,7,'и’,
2’,7,'-7, т’, 7,'Н',7, О’,
', 7, Г’, 7
|) '0’,7,’ ',7, 'Р’,7, М’
теззаде_1 = $-теззаде ; Длина в байтах.
гезт_$сг = (80*25*2-теззаде_1)/4 ; Длина оставшейся части экрана-в двойных словах.
‚ Таблица глобальных дескрипторов. °
вот ]абе1 руте
; Нулевой дескриптор (обязательно должен быть на первом месте).
| ЧБ 8 44р(0)
‚ 4-гигабайтный код, ОРЁ= 00:
бОТ_Е]а{0$ ЧБ ОЕЕА, Ор, 0,0, ООО, МОЧЬ, О
;\4-Гигабайтные данные, ОРЁ=
вОТ_Е1а105 95 ОЕЕН, о, 0,0, 0, 100100106, 11001111, 0
; 64-килобайтный код, ОРЁ = 00:
С0Т_1651%05 ЧБ ОЕЕИ, ОРРА,0,0,0, 100110106, 0,0
; 64-килобайтные данные, ОРЁ = 00: |
СОТ_1661105 ЧБ ОЕЕи, ОРЕИ, 0,0,0, 100100106,0,0
б0Т_1 = $-60Т ; Размер 60Т.
99г М 60Т_1-1 ; 16-битный лимит 60Т. и.
| 99 ? ; Здесь будет 32-битный линейный адрес вот.
‚ Названия для сёлекторов (все селекторы для 60Т, с ВРЕ= 00).
ЗЕЁ_Е1а105 еди 000010006 ^
УЕЁ_11а105 еди 000100005
$ЕЕ_16140$ еаи 000110006
$Е_ 1661105 еду 001000006

ЯМ_зе9 епд5

; 32-битный сегмент; содержащий код, ‘который будет исполняться в защищенном режиме.


РМ_зед зедтепт рага риб11с “С00Е” изеЗ2.
‚ аззите . сз:РМ_$е9
РМ_ептгу:
; Загрузить сегментные регистры (кроме $$).
[1 ах, ЗЕЁ_1651105
моу 9$,ах
моу ах, ЗЕЁ_Е1а{0$
то ез, ах
; Вывод на экран. . .
моу е$1, оРзеЁ меззаде ; 0$:Е$Т - сообщение:
тоу е91, 0880008 ‚ Е5:ЕОТ - видеопамять.
поу есх, теззаде_1 ; ЕСХ - длина.
гер моу$Ь ; Вывод на экран.
моу еах, 072007208. ; Два символа 20Н с атрибутами 07.
моу есх, гезт_$сг у ‚ Остаток экрана /2.
гер 31084 ; Очистить остаток экрана.
; Загрузить-в 06$ селектор 16-битного. сегмента ВМ_зе9.
4: ОЕАВ 7, ; Код дальнего пр.
94 ‚ ОЕЁзеф ВМ гефтигп ; 32-битное смещение.

а
а
а
дАь
ы
аа
р
р
Сегментная адресация. › осу
[и $Е1...1661%С$: ; Селектор.
РМ_5е9 еп.

; Сегмент стека - используется как. в 16-битном; так и. в 32-битном режимах;


_; поскольку мы ме трогали. $5, он’все время оставался. 16-битным. |
ВМ_зтаск зедтелт рага зТаск “ЗТАСК” изе16
[() 1008 9ир{?) .
ВМ_зтаск еп4$ ` |
ета ЗТаге

10.4.5. Нереальный режим


Как мы уже знаем, при изменении режима скрытые части сегментных регист-
ров сохраняют содержимое своих дескрипторов и их разрешено применять. Мы
воспользовались этой возможностью в нашем первом примере, когда значения, за-
несенные в сегментные регистры в реальном режиме, загружались в защищенном.
Возникает вопрос - а если поступить наоборот: в защищенном режиме загрузить
сегментные регистры дескрипторами 4-гигабайтных сегментов с базой 0 и перей-
ти в реальный режим? Оказывается, это прекрасно срабатывает, и мы попадаем
в особый режим, который называется нереальным режимом (ипгеа| то4е), боль-
шим реальным режимом (ВЕМ) или реальным Яаб--режимом (ВЕМ). Чтобы пе-
рейти в нереальный режим, перед переходом в реальный режим надо загрузить
в С$ дескриптор 16-битного сегмента кода с базой 0 и лимитом 4 Гб и в осталь-
ные сегментные регистры- точно такие же дескрипторы сегментов данных.
Теперь весь дальнейший код программы, написанный для реального режима,
больше не ограничен рамками 64-килобайтных сегментов и способен работать
с любыми массивами. Можно подумать, что первый же обработчик прерывания
от таймера загрузит в С$ обычное значение и все нормализуется, однако при со-
здании дескриптора в скрытой части сегментного регистра в реальном режиме
процессор не трогает поле лимита, а только ‘изменяет базу: что бы мы ни записали
в сегментный регистр, сегмент будет иметь размер 4 Гб. Если попробовать вер-
нуться в ОО$ — она по-прежнему будет работать. Можно запускать программы
такого рода:
‚в0де1 1ту
. соде
ог 100и.
Зфаг{: ° хог ах, ах
оу 4$, ах ; 8$ =0 у
‹ Вывести символ в видеопамять:
моу _мога ртг 43:[0880001), 8403
ге
епб ЗТагте

и они тоже будут работать. Единственное, что отключает этот режим, — програм-
‘мы, переходящие в защищенный режим и обратно, которые устанавливают гра-
ницы сегментов в 64 Кб, например любые программы, использующие расширите-
ли РОЗ.
ШИ! Процессоры т*е! в защищенном режиме
Нереальный режим -— идеальный вариант для программ, которым необходима
32-битная адресация и свободное обращение ко всем прерываниям В10$ и РО$
(традиционный способ состоял бы в работе в защищенном режиме с переключе-
нием в \У86 для вызова ВО$ или РО5, как это делается в случае с ОРМТ).
‚ Для перехода в этот режим можно воспользоваться, например, такой процедурой:
; Область данных:
бОТ ]аБе} Буе :
[6] 8 9ир(0) ; Нулевой дескриптор.
; 16-битный 4 Гб сегмент: . |
у Ч6 ОРЕВ, ОРРА, 0, 0.0, 1001001Ь, 110011115,0
даег 9м 16 ; Размер 60Т.
99 Базе — 94 ? ; Линейный адрес ОТ.
; Код программы.
; Определить линейный адрес ©0Т.
хог еах, вах
моу ах, сз
ЗВ]. еах,4
а99 ах, оГРзет вот
; Загрузить @0Т из одного дескриптора (не считая нулевого).
йоу 64 Базе, еах
1941 Рмога рег датг
; Перейти в защищенный режим.
с11
. У вах, сго .
ог а1,1
мо\ сго, вах |
тр зтагт_РМ ; Сбросить очередь предвыборки.
; 1п1е1 рекомендует
$ТагЕ_РМ: ; Делать )тр после каждой смены режима.
; Загрузить все сегментные регистры дескриптором с лимитом 4 Гб.
: оу ‚ ‘ах,8 ; 8 - селектор нашего дескриптора.
моу 9$,ах
пу = е$,ах
- том 3,ах
поу 93, ах сх
; Перейти в реальный режим.
моу еах,сго ,
ап а1,ОРЕВ '
оу сгО, еах
Этр ех4{_РМ
ех1т_РМ: |
; Записать что-нибудь в каждый сегментный регистр.
хог ах, ах
оу 33,ах
моу ез, ах
оу 73, ах `
моу 9$, ах
.

Обработка прерываний и исключений _


зы На С. о
вом ‚ах,63
оу ..` 9$,ах:
‚; И все - теперь процессор находится. в реальном режиме с неограниченными сегментами.

10.5. Обработка прерываний и исключений


До сих пор все наши программы работали в защищенном режиме с полностью
отключенными прерываниями - ‘ими нельзя было управлять с клавиатуры, они
не могли работать с дисками и вообще не делали ничего, кроме чтения или запи-
си в те или иные области памяти. Разумеется, ни одна программа не может вы-
полнить что-то серьезное в таком режиме — нам рано или поздно придется обра-
батывать прерывания.
В. реальном режиме адрес обработчика прерывания
п считывался процессором
из таблицы, находящейся по адресу 0 в памяти. В защищенном режиме эта табли-
ца, называемая 1ЮТ - таблицей дескрипторов прерываний, может находиться где
угодно. Достаточно того, чтобы ее адрес и размер были загружены в регистр ШТК.
Содержимое ШТ - не просто адреса обработчиков, как это было в реальном ре-
жиме, а дескрипторы трех типов: шлюз прерывания, шлюз ловушки и шлюз зада-
чи (форматы данных дескрипторов рассматривались в предыдущем разделе).
Шлюзы прерываний и ловушек указывают точку входа обработчика, а также
его разрядность и уровень привилегий. При передаче управления обработчику
процессор помещает в стек флаги и адрес возврата, так же как и в реальном режи-
ме, но после этого для некоторых исключений в стек помещается дополнитель-
ный код ошибки, следовательно, не все обработчики можно завершать простой
командой 1ВЕТО (или {ВЕТ для 16-битного варианта). Единственнбе различие
между шлюзом. прерывания и ловушки состоит в том, что при передаче управле-
ния через шлюз.прерывания. автоматически запрещаются далёнейшие прерыва-
ния, пока обработчик не выполнит ТКЕТО. Этот механизм считается предпочти-
тельным для обработчиков аппаратных прерываний, а шлюз ловушки, который
не запрещает прерывания на время исполнения обработчика, лучше использовать
для обработки программных прерываний (которые фактически и являются ис-
ключениями типа ловушки). Кроме того, в защищенном режиме при вызове об-
работчика прерывания сбрасывается флаг трассировки ТЕ.
Сначала рассмотрим пример программы, обрабатывающей только аппаратное
прерывание клавиатуры с помощью шлюза прерываний. Для этого надо составить
ТОТ, загрузить ее адрес командой ГОТ и не забыть загрузить то, что содержится
в регистре ОТВ в реальном режиме, — адрес 0 и размер 4Х256, соответствующие
таблице векторов прерываний реального режима.
; рт2.азт
; Программа, демонстрирующая обработку аппаратных прерываний в: защищенном режиме.
; Переключается в 32-битный защищенный режим и позволяет набирать. текст при помощи
’ клавиш от 1 до +. Нажатие Васкзрасе стирает предыдущий символ,
; нажатие Езс - выход из программы.
ВЗУМЕШИИШИИ! Процессоры т{е! в защищенном режиме

‚; Компиляция ТАЗМ;
; Тазш /т /0_ТАЗМ_ рм2.азт
; (или, для версий 3.х, достаточно Тазм /т рм2. аз)
; 1 1тКк Их /З рм2.05]
; Компиляция МАМ:
; мазт /0_рм2.азт
; м11пКкК 111е рт2.06] Рогт 00$

‚ Варианты того, как разные ассемблеры записывают смещение из 32-битного


‚ сегмента в 16-битную переменную:
1Р9еЕ _ТАЗМ_
80 . еду эта11 ответ ‚ ТАЗМ 4.х
е1зе |
$0 еду оЕРзет ; МАЗМ
епа1 Е
; Для МАЗМ, по-видимому, придется добавлять лишний код, который преобразует
‚ смещения, используемые в ТОТ.

. 386р
ВМ ед зедтепф рага риуб11с "СО0Е" изе16
аззите с$:ВМ_5е9, 93:РМ_5е0, $$; зтаск_зед
эТагт:
; ‘Очистить экран.
ОУ ах,3
111 108
‚ Подготовить сегментные регистры.
ризв РМ_5е9
рор 9$
; Проверить, не находимся ли мы уже в РМ:
` МОУ еах, сг0
тез+ а1,1
37 по_\86
;’ Сообщить и выйти.
моу 4х,30 \86_т59
егг_ех1т:
, поу ай, 9
10 218
оу ап, 4СВ
11 211 |
; Может быть, это И1пд0мз 95 делает вид, что РЕ =
по_\86:
ЮУ ах, 16001
177 2ЕВ
теэ+ а1,а1
32 по_м1100м$
; Сообщить и выйти,
оу 9х,30 и1п_1$0
Этр ЗНогЕ егг_ех1+
\

Обработка прерываний и исключений. |


; Итак, мы точно находимся в реальном режиме.
по_м1п0б0м$:
; Вычислить базы для всех используемых дескрипторов сегментов.
хог еах, еах . .
оу ах, ВМ_3е9
$11 еах, 4 |
пу мога рег бОТ_16511С5+2,ах ; Базой 1661105 будет ВМ-$е9.
< Аг еах, 16
„МОУ Буте руг б0Т_1661169+4, а1
оу ах, РМ_зе9
_ $11 вах,4
по мог руг 60Т_32611С5+2,ах ; Базой всех 32614» будет
поу мога руг 60Т_32611$$+2,ах ; РМ_зе9.
МОУ мога рфг бОТ_3251405+2,ах
ИГ еах, 16
пом Буте рёг 60Т_3261465+4,а1
оу Буе руг б0Т_32611$5+4,а1 у
пу Буе рфг 60Т__326110$+4,а1
; Вычислить линейный адрес б0Т.
‘хог еах, еах
му ах, РМ_зе9
31] еах,4
ризи еах
а99 еах, оЕЕзе{ в0Т
° по Фиога руг 99%г+2, еах
; Загрузить 60Т.
194% Риогд рег 99г
; Вычислить линейный адрес ТОТ.
рор еах я
а99 еах,
о Рзет ТОТ |
оу @мог4 рег 14%г+2, еах.
; Загрузить ШТ.
Пат Риога ртг 16г ,
; Если мы собираемся работать с 32-битной памятью, стоит открыть А20.
11 а1, 921
ог а1,2
ош 921,а1
; Отключить прерывания,
11 . <
; включая МТ. '
1п а1, 701
ог а}, 808
оц 701,а1
; Перейти в РМ.
- тоу еах, сго |
ог а],1`
ОУ сго, еах
ЕСУЗИМИИШИШИВИИИ! |Процессоры име! в защищенном режиме
; Загрузить ЗЕЁ_326116$ в 0$.
ЧБ 66п
6 ОЕАВ
93 ” оРЕзет РМ_ептгу
Ом ЗЕЁ_326116$

ВМ_гетигп:
; Перейти в ВМ,
пом еах, сго
апё а], ОРЕЯ
оу сго, еах
; Сбросить очередь и .загрузить 65 реальным числом.
95 ОЕАВ
бм $+4
Чи АМ_зе9
; Установить регистры для работы в реальном режиме.
тому ах, РМ_зе9 |
оу 9$,ах
оу е$, ах
мо ах, зфаск_$е9
моу Ьх, этаск_1
мо $5, ах

оу эр,5х
‚ Загрузить ТОТВ для реального режима.
моу ах, РМ_5е9
тому 9$,ах
1191 Рыога руг 19тг_геа1
; Разрешить ММТ.
п а1, 701
апа а», О7ЕН
ош ТОВ, а1
; Разрешить прерывания
31
5 И выйти.
оу ан, 4СН
171 218
АМ _эе0 епаз

‚ 32-битный сегмент.
РМ_зед’ зедтеп{ ‘рага руБ11с “СО0Е” изез2
аззите с$:РМ_ед
; Таблицы @ОТ и ТОТ должны быть выравнены, так что будем их размещать
‚ в начале сегмента. г
вот Дабе] Буте
ЧЬ 8 9ир(0)
; .32-битный 4-гигабайтный сегмент с базой = 0.
в0Т_+11а{0$ 95 ОЕРВ, ОЕРВ, 0,0,0, 10010010, 110011116,0
‚ 16-битный 64-килобайтный сегмент кода. с’ базой ВМ. зе9.
СОТ. 1651165 96 . ОЕЕВ, ОРЕН, 0,0, 0,10011010,
0,0
Обработка прерыванийи исключений [ММ
; 32-битный 4-гигабайтный сегмент. кода с базой РМ_369.
бОТ_3261160$ 96 ОЕЕВ, ОРЕв,0, 0,0, 100110106, 110011116,0
; 32-битный 4-гигабайтный сегмент данных с базой РМ_эе9.
вОТ_326110$ 96 ОЕ, ОЕЕН, 0, 0,0,100100106, 110011116, 0
:; 32-битный 4-гигабайтный сегмент данных с базой $Таск_5е9.
бОТ_32511$$ ° 95 ОЕЕв;ОРЕВ, 0,0, 0, 100100105, 1100111150
991_512е = $-б0Т
ог м. 941_$12е-1 ; Лимит 60Т.
93 ? ; Линейный адрес 60Т.
; Имена для селекторов.
ЗЕЁ_Е1а{0$ еду 0010006
ЕЁ _166140$ еди 0100005
ЗЕЁ_326146$ еди 0110006 ` -
ЗЕЁ_326410$ еби . . 1000006 `
ЗЕ|_325115$ еди 1010006
: Таблица дескрипторов прерываний ТОТ.
ТОТ ]аБе1 ` Буте
; Все’эти дескрипторы имеют тип ОЕп - 32-битный шлюз прерывания.
; ТМ 00 - 07
[1 8 бир(50 1пт_папаЗег, 5ЕЁ_326146$, ЗЕСОВ, 0)
; МТ 08 (1г90) .
дм з0 1г40_7_папд]ег, $ЕЁ_326116$, 8Е0 ОВ, 0
; М 09 (1191) = |
ди 50 1г41_папд1ег, 5Е1_326116$, 8ЕООП, 0
; Т№Т оАВ - ЕВ (1802 - 1408)
[е\ 6 дир(з0 1г40_7_папа1ег, $Е`_326116$, 8Е0ОВ,.0)
; ЛАТ 10. - 6 .
Чи 97 дир(зо 1п*_ПВапа1ег, ЗЕЁ_32511С$, 8ЕООН, 0)
; ЛАТ 70н - 781 (1408 - 19015)
@и 8 Зир(з0. 1г48_15_ папё1ег, $ЕЁ_32611С$, ВЕ, 0)
‚ ШТ 798 - ЕР
дм 135 дир($0 11 Вапа1 ег, Е _326116$, 8ЕООЛ, 0)
14% 317е = $-ШТ ; Размер ШТ.
г м 191_$12е-1 ; Лимит ТОТ.
94 ? | . Линейный адрес начала 10Т.
; Содержимое регистра ТОТН в реальном режиме.
144 г_геа] Чи ЗЕЕРА, 0,0

; Сообщения об ошибках при старте.


\86_тз9 96 “Процессор в режиме \86 - нельзя переключиться в ` риф
М1 П_М$09 [ее “Программа запущена под \№1п40мз - нельзя перейти в кольцо 0$"

; Таблица для перевода ОЕ скан-кодов в АЗСТТ.


3сап2азс11 аь 0, 1В1,'1',’2’,'3’,'4’,'5’,'6*,'7','8','9’,'0’,'-',’=',8
зсгееп_аддг 39 0 .; Текущая позиция на экране. .

; Точка входа в 32-битный защищенный режим.


РМ_ептгу: : :
;. Установить 32-битный стек и другие регистры:
оу ах, ЗЕЁ_Р]а10$
и

577788
ООООО И Процессоры Не! в защищенном режиме
моу 49$, ах
оу е5, ах
МОУ ах, 3Е1._3261155
Мом ебх, зтаск_1
поу $$, ах
поу езр, еБх
; Разрешить прерывания
$11
; и войти в вечный ‘цикл.
тр эНогт $

; Обработчик. обычного прерывания.


11{_папд1ег:
1гета
‚ Обработчик аппаратного прерывания 1800 - ТНОТ.
- 1г90_7_Пап@]ег:
риузй еах
пом а], 201
сит 201,а]
рор еах
1гета
; Обработчик аппаратного прерывания 1808 - ТВО15.
1га8_15_Папа1ег:
ризй еах
МОУ а], 208
ош ОАЛИ,а1
рор еах
1гета
: Обработчик ТВ@1 - прерывания от клавиатуры.
1га91_папа1ег:
ризй еах ‚ Это аппаратное прерывание - сохранить регистры.
ризй ебх›
ризй ез
рип 0$
11 а], 608 Прочитать скан-код нажатой клавиши. л
о
и
Ш

стр а1, ОЕВ Если он больше, чем


За ЗК1р_Тгапз1ате обслуживаемый нами,- не обрабатывать.
стр а1, 1 Если это ЕЁзс,
3е езс_ргеззед выйти в реальный режим.
том Ьх, 5ЕЁ_325110$ ; Иначе:
моу 9$,6х ; 0$:ЕВХ - таблица для перевода’ скан-кода
тоу ебх, оРЕзет $сапдазс11 в АЗС.
х1ать Преобразовать.
оу Ьх, ЗЕЁ_Р1а{0$
оу е$,Ьх ЕЗ:ЕВХ - адрес текущей
тому ебх, зсгееп_аддг позиции на экране.
стр а1,8 Если не была нажата _ВасКзрасе,
3е Ь$_ргеззед

И
Обработка прерываний и исключений -
МОУ е$:[е5х+0880001] , а1. ‚ ‘послать символ:на экран.
ад Омога руг зсгееп. ад4г,2 ;` Увеличить. адрес позиции на 2.
ар ЗВогт $КГр_Тгапз1ате
Ь$_рге$зед: ; Иначе: _
моу а1,’°’. -. ‚ ; нарисовать пробел
$6 ебх, 2 °^ р; В позиции предыдущего символа
моу е5: [е6х+0880001 ], а] _
ей зсгееп_ад9г, ебх ; и сохранить адрес’ предыдущего символа
зК1р_Егапз1ате: ‚ | . как текущий.
; Разрешить ‘работу клавиатуры. `
1п а1, 611 |
ог а}, 801
оу 611,а]
; Послать ЕОТ контроллеру прерываний. .
оу 21, 208
О 201,а1
‚ Восстановить регистры и выйти..
. рор 45
рор. ез
рор ебх
рор еах
1гетд

; Сюда передается управление из обработчика’ 1801, ‘если нажата Езс.


езс_ргеззед:
; Разрешить работу клавиатуры, послать ЕбТ`и восстановить регистры.
т а1, 61н
ог а1, 801 ,
оит 611, а1 В
оу а], 201 |
о ‚ 20, а1
. рор 9$
рор ез
рор ° еБх
рор вах.
‚; Вернуться в реальный режим.
с11
45 ОЕАЯ
да оРЕзет ЕМ_гетигп
. ди ЗЕЁ_ 1661465
РМ_5е9. епд$ | `

; Сегмент стека. Используется как 16-битный в 16-битной части программы и как


; 32-битный (через селектор 523261135) в 32-битной части.
зтаск_зед зедмепт рага зТаск “ЭТАСК”
зфаск_зтаг* ЧБ 100 9ир(?)_
этаск_} = $-5Таск_зтагт ` ; Длина стека для инициализации ЕЗР.
зтаск_5е9 -епдз . . ,
епд °ЭТагт
Ш! Процессоры и\е! в защищенном режиме
В этом примере обрабатываются только 13 скан-кодов клавиш для сокращения
размеров программы. Полную информацию преобразования скан-кодов в АЗСПИ
можно найти в таблицах приложения 1 (см. рис. 18, табл. 25 и 26). Кроме того,
в этом примере курсор все время остается в нижнем левом углу экрана — для его
перемещения можно воспользоваться регистрами ОЕВ и. оЕЬ контроллера. СВТ
(см. раздел 5.10.4).
Как уже упоминалось в разделе 5.8, кроме прерываний от внешних устройств
процессор может вызывать исключения при различных внутренних ситуациях
(их механизм обслуживания похож на механизм обслуживания аппаратных пре-
рываний). Номера прерываний, на которые отображаются аппаратные прерыва-
ния, вызываемые первым контроллером по умолчанию, совпадают с номерами
отдельных исключений. Конечно, можно из обработчика опрашивать контроллер
прерывание, чтобы определить, выполняется ли аппаратное прерывания или это
исключение, но ие! рекомендует перенастраивать контроллер прерываний (см.
раздел 5.10.10) так, чтобы никакие апнаратные прерывания не попадали на об-
ласть от 0 до 1ЕБ. В нашем примере исключения не обрабатывались, но, если про-
грамма планирует запускать другие программы или задачи, без обработки исклю-
чений обойтись нельзя. |
Часть исключений (исключения типа ошибки) передает в качестве адресатвоз-
врата команду, вызвавшую исключение, а часть—адрес следующей команды. Кро-
ме того, некоторые исключения помещают в стек код ошибки, который нужно
считать, прежде чем выполнять 1ВЕТО. Поэтому пустой обработчик из одной ко-
манды 1ЗЕТО в нашем примере не был корректным и многие исключения приве-
ли бы к немедленному зависанию системы.
Рассмотрим исключения в том виде, в каком они определены для защищен-
ного режима.

Формат кода ошибки:


биты 15-3: биты 15-3 селектора, вызвавшего исключение.
бит 2: Т1 - установлен, если причина исключения-—дескриптор, находящий-
ся в ГОТ, и сброшен, если в СОТ '`
бит 1: ШТ- установлен, если причина исключения - дескриптор, находящий-
сяв ШТ
бит 0: ЕХТ - установлен, если причина исключения — аппаратное прерывание
ГМТ 00 — ошибка #РЕ «Деление на. ноль» :. В
. Вызывается командами ПТУ или ГПУ, если делитель -— ноль или если проис-
ходит переполнение. - т. ;.
,

ТМТ 01 - исключение #О0В «Отладочное прерывание»


Вызывается как ловушка при пошаговой трассировке' (флаг`ТЕ.= 1), при цере-
ключении на задачу с установленным отладочным флагом и при срабатывании .
точки останова во время доступа к.данным, определенной в отладочных регистрах.
Вызывается как ошибка при срабатывании точки останова по выполнению ко-
манды с адресом, определенным в отладочных’'регистрах. р: 5
Обработка прерываний и исключений _
‚ ПМТ 02 - прерывание ММТ
‚ Немаскируемое прерывание.
ЕМТ 03 -— ловушка #ВР «Точка останова» `
Вызывается однобайтной командой ЕУТЗ.
ПМТ 04 - ловушка #ОЕ «Переполнение» |
Вызывается командой П\ТО, если флаг ОЕ = 1.
ПМТ 05- ошибка #ВК «Перенолнение при ВООМО»
Вызывается командой ВОИМО при выходе операнда за допустимые границы.
ПМТ 06 - ошибка #00 «Недопустимая операция»
Вызывается, когда процессор пытается исполнить недопустимую команду или
команду с недопустимыми операндами.

ТМТ 07- ошибка #ММ «Сопроцессор отсутствует»


Вызывается любой командой ЕРО, кроме У/АПТ, если бит ЕМ регистра СКО
установлен в 1, и командой \МАГТ, если МР и Т$ установлены в 1.

`
МТ 08 -— ошибка #П0Е «Двойная ошибка»
Вызывается, если одновременно произошли два исключения, которые не мо-.
гут быть обслужены последовательно. К ним относятся # ПЕ, #Т5, #МР, #55, #СР
и #РЕ
Обработчик этого исключения получает код ошибки, который всегда равен нулю.
Если при вызове обработчика #0Е происходит еще одно исключение, процес-
сор отключается и может быть выведен из этого состояния только сигналом ММ!
или перезагрузкой.
ПМТ 098 — арезервировано
Эта ошибка вызывалась сопроцессором 80387, если происходило исключение
#РЕ или #СР при передаче операнда команды ЕРО.
ТМТ.ОАВ - ошибка #Т$ «Ошибочный Т$$».
Вызывается при попытке переключения на задачу с ошибочным Т$$.
Обработчик этого исключения должен вызываться через шлюз задачи.
Обработчих этого исключения получает код ошибки.
Бит ЕХТ кода ошибки установлен, если переключение пыталось выполнить ап-
паратное прерывание, использующее шлюз задачи. Индекс ошибки равен селектору
Т5$, если Т$5 меньше 671 байт, селектору ГОТ; если ГОТ отсутствует или оши-
бочен, селектору сегмента стека, кода или данных, если ими нельзя пользоваться
(из-за нарушений защиты иди ошибок в селекторе).
ПМТ ОВЬ-— ошибка #МР «Сегмент недоступен»
Вызывается при попытке загрузить в регистр С$, 0$, Е, Е$ или с5 селектор
сегмента, в дескрипторе которого сброшен бит присутствия сегмента (загрузка
в 95 вызывает исключение #55), а также при понытке использовать шлюз, поме-
ченный как отсутствующий, или при загрузке таблицы локальных дескрипторов
командой Т.Л.ЮТ (загрузка при переключении задач приводит к исключению #Т5).
/
ШЕИ! Процессоры те! в защищенном режиме
Если операционная система реализует виртуальную память_на уровне сегмен-
тов, обработчик этого исключения может загрузить отсутствующий сегмент в па-
мять, установить бит присутствия и вернуть управление.
Обработчик этого исключения получает код ошибки.
Бит ЕХТ кода ошибки устанавливается, если причина ошибки - внешнее преры-
вание, бит ОТ устанавливается, если причина ошибки — шлюз из ШТ, помеченный
как отсутствующий. Индекс ошибки равен селектору отсутствующего сегмента.
ГМТ ОСЬ — ошибка #55 «Ошибка стека»
Это исключение вызывается при попытке выхода за пределы сегмента стека.
во время выполнения любой команды, работающей со стеком, — как явно (РОР,
РОЗН, ЕМТЕК, ГЕАУЕ), так и неявно (МОУ АХ, [ВР + 6]), а также при попытке
загрузить в регистр $5 селектор сегмента, помеченного как отсутствующий (не
только во время выполнения команд МОУ, РОР и 155, но и во время переключе-
ния задач, вызова и возврата из процедуры на другом уровне привилегий).
Обработчик этого исключения получает код ошибки.
Код ошибки равен селектору сегмента, вызвавшего ошибку, если она произош-
ла’из-за отсутствия сегмента или при переполнении нового стека в межуровне-
вой команде САМ. Во всех остальных случаях код ошибки- ноль. `

ТМТ ООВ- исключение #СР «Общая ошибка защиты»


Все ошибки и ловушки, не приводящие к другим исключениям, вызывают
#СР - в основном нарушения привилегий. и
° Обработчик этого исключения получает код ошибки.
Если ошибка произошла при загрузке селектора в сегментный регистр, код
ошибки равен этому селектору, во всех остальных случаях код ошибки - ноль.
ПМТ 0ЕБВ -— ошибка #РЕ «Ошибка страничной адресации»
Вызывается, если в режиме страничной адресации программа пытается обра-
титься к странице, которая помечена как отсутствующая или привилегированная.
Обработчик зтого исключения получает код ошибки.
Код ошибки использует формат, отличающийся для других исключений:
бит 0: 1, если причина ошибки — нарушение привилегий;
0, если было обращение к отсутствующей странице;
бит 1: 1, если выполнялась операция записи; 0, если чтения;
бит 2: 1, если операция выполнялась из СРИ,= 3; 0, если СРГ.< 3;
бит 3: 0,если ошибку вызвала попытка установить зарезервированный бит в ка-
° талоге страниц.
Остальные биты зарезервированы. | ,
Кроме кода ошибки обработчик этого исключения может прочитать: из регистра
СВ2 линейный адрес, преобразование которого в физический вызвало исключение.
Исключение #РЕ- основное исключение для создания ‚виртуальной памяти
с использованием механизма страничной адресации.
>
ПМТ ОЕЬ - зарезервировано .
_ [МТ 106 - ошибка #МЕ «Ошибка сопроцессора»
Страничная адресация МЕСТ]
Вызывается, только если бит МЕ в регистре СКО установлен в 1 при выполне-
нии любой команды ЕРО, кроме управляющих команд и \/АТТ/Е\МАТ, при усло-
вии, что в ЕРЧУ произошло одно из исключений ЕРО (см: раздел.2.4.3).
ГМТ ИВ- ошибка #АС «Ошибка выравнивания»
‚ _Вызывается, только если бит АМ в регистре СКО и флаг АС из ЕЕ ТАС уста-
новлены в 1, если СРГ.= 3 и произошло невыравненное обращение к памяти. (Вы-_
равнивание должно быть по границе слова при обращении к слову, к границе
двойного слова, к двойному слову и т. д.)
`Обработчик этого исключения получает код: ошибки равный нулю.
ПМТ 128- останов #МС «Машинно- -зависимая ошибка»
Вызывается (начиная с Репиит) при обнаружении некоторых аппаратных
ошибок с помощью специальных машинно- зависимых регистров МСС_*. Нали-
чие кода ошибки, так же как и способ вызова этого исключения, зависит от моде-
ли процессора. 7,

ТМТ 138 - 1ЕЬ — зарезервировано [| для будущих исключений _


ПМТ 208 - ОЕЕВ - выделены для использования программами
Обычно для отладочных целей многие программы, работающие с защищен-
ным режимом, устанавливают обработчики всех исключений, которые выдают
список регистров процессора и их содержимое, а также иногда участок кода,
вызвавший исключение. В качестве примера обработчика исключения типа
ошибки можно рассматривать программу, обрабатывающую #ВВ (см. раз-
дел 5.8.1).

10.6. Страничная адресация’


Линейный адрес, который формируется процессором из логического адреса,
соответствует адресу из линейного: непрерывного пространства. памяти. В обыч-
ном режиме в это пространство ‘могут попадать области памяти, куда нежелатель-
но разрешать запись, — системные таблицы и процедуры, ПЗУ ВТО$ ит. д. Чтобы
‚ этого избежать, система может позволять программам создавать только неболь-
шие сегменты, но тогда теряется привлекательная идея Яа{-памяти. Сегментация —
не единственный вариант организации памяти, который поддерживают процес-
соры \е|. Существует второй, совершенно независимый механизм — странич-
ная адресация (равштайоп).
При страничной адресации непрерывное пространство линейных адресов па-
мяти разбивается на страницы фиксированного размера (обычно 4 Кб (4096 или
1000Ъ байт), но Репбит Рго может поддерживать и страницы по 4 Мб). При об-
ращении к памяти процессор физически обращается не по линейному адресу, а по
тому физическому адресу, с которого начинается данная страница. Описание каж-
дой страницы из линейного адресного пространства, включающее в себя ее
физический адрес и дополнительные атрибуты, хранится в одной из специальных
ЕЖЕ ШИИШИ И Процессоры че! в защищенном режиме.
системных таблиц, как и в случае сегментации, но при этом страничная адреса-
ция абсолютно невидима для программы.
Страничная адресация включается при‘установке бита РС ргистра СВО, если
бит РЕ зафиксирован в 1 (попытка установить РС, оставаясь в реальном режиме,
приводит к исключению #СР(0)). Кроме того, в регистр СВЗ: предварительно
надо поместить физический адрес начала каталога страниц’ Главной из таблиц,
описывающих страничную адресацию. Каталог страниц имеет размер 4096 байт
(ровно одна страница) и содержит 1024 4-байтных указателя на таблицы страниц.
Каждая таблица. страниц тоже имеет размер 4096 байт.и содержит указатели до
1024 4-килобайтных страниц. Если одна страница описывает 4 Кб, то полностью.
заполненная таблица страниц описывает 4 Мб, а полный каталог полностью за-
полненных таблиц- 4 Гб, то есть все 32-битное линейное адресное пространство.
Когда процессор выполняет обращение к линейному адресу, он сначала исполь-
зует его биты 31—22 как номер таблицы страниц в каталоге, затем биты 21-12 как
номер страницы в выбранной таблице, а затем биты 11-0 как смещение.от физи-
ческого адреса начала страницыв памяти. Поскольку эта ‘процедура занимает:
много времени; в процессоре предусмотрен специальный кэшстраниц — ТГВ (бу-
фер с ассоциативной выборкой); так. что, если к странице обращались не очень
давно, ее физический адрес будет сразу определен: хо
Элементы каталога страниц и ‘таблиц страниц имеют общий формат:
биты 31-12: биты 31-12 физического адреса (таблицы страниц или самой
страницы)
биты 11-9; доступны для использования операционной системой
бит 8: С — «глобальная страница» - страница не удаляется из буфера ттВ при
переключении задач или перезагрузке регистра СКЗ (только на Репёит
Рго, если установлен бит РСЕ|]регистра СВА) |
бит 7: Р5- размер страницы. 1 — для страницы размером 21или 4 Мб, иначе — 0
бит 6: Ш - «грязная страница» — устанавливается в 1 при записи в страницу;
всегда равен нулю для элементов каталога страниц.
бит 5: А - бит доступа (устанавливается в 1 при любом обращении к таблице
_ страниц или отдельной странице) |
бит 4: РСО- бит запрещения кэширования
бит 3: РУТг бит разрешения сквозной записи
бит 2: Ц - страница/таблица доступна для программ С СР. = Е
бит 1: \/ - страница/таблица доступна для.записи —”
. бит0: Р- страница/таблица присутствует. Если этот бит —- 0, остальные биты
элемента система может использовать по своему. усмотрению, напри-
мер, чтобы хранить информацию. о том, где физически находится отсут
‚ствующая страница
_ Процессоры. Решив Рго (и старше) м могут поддерживать расширения стра-
ничной адресации. Если установлен. бит.РАЕ, физический адрес’оказывается не.
32-битным (до 4 Гб); а 36-битным (до:64 Гб). Если установлен'бит'РЗЕ регистра
Страничная адресация и. о НО ЕИИИСК
СКА, включается: поддержка расширенных страниц размером 4 Мб для РАЕ= 0
и 2 Мб для РАЕ- 1. Такие страницы описываются не в таблицах страниц, а в ос-
новном каталоге. Ге! рекомендует помещать.ядро операционной системы и все,
что ему необходимо для работы, на одну 4-мегабайтную страницу, а для приложе-
ний пользоваться 4-килобайтными страницами. Расширенные страницы кэширу-.
ютея в отдельном ТГВ, так что, если определена всего одна расширенная страни-
ца, она будет оставаться в ТТ.В все время.
Для расширенных страниц формат элемента каталога совпадает с форматом
для обычной страницы (кроме того, что бит Р$ = 1), но в качестве адреса исполь-
зуются только биты 31-22— они соответствуют битам 31-22 физического адреса
начала страницы (остальные биты адреса нули).
Для расширенного физического адреса (РАЕ= 1) изменяется формат регистра
СКЗ (см. раздел 10.1.3), размеры всех элементов таблиц становятся равными 8 бай-
там (причем используются только биты 0-3 байта 4), поэтому их число сокраща-
ется до 512 элементов в таблице и вводится новая таблица— таблица указателей
на каталоги страниц. Она состоит из четырех 8-байтных элементов, каждый из ко-
торых может указывать на отдельный каталог страниц. В этом случае биты 31-30
линейного адреса определяют используемый каталог страниц, биты 29—21 —
таблицу, биты 20-12- страницу, а биты 11-0— смещение от начала страницы в фи-
зическом пространстве (следовательно, если биты 29-21 выбрали расширенную
страницу, биты 20-0 соответствуют смещению в ней).
Основная цель страничной адресации— организация виртуальной памяти в ОС.
Система может использовать внешние устройства (обычно диск) для расширения
виртуального размера памяти. При этом, если к какой-то странице долгое время
нет‘обращений, система копирует ее на диск и помечает как отсутствующую
в таблице страниц. Затем, когда программа обращается по адресу в отсутствую-
щей странице, вызывается исключение #РЕ Обработчик исключения читает ад-
рес, приведший к ошибке из СК2, определяет, какой странице он соответствует,
загружает ее с диска, устанавливает бит присутствия, удаляет копию старой стра-
ницы из ТГВ командой ПМУГРС и возвращает управление (не забыв снять со
стека код ошибки). Команда, вызывавшая исключение типа ошибки, выполняет-
ся повторно.
Кроме того, система может ерибдичёски расвать бит доступа и, если он не
установится за достаточно долгое время, копировать страницу на диск и объявлять
ее отсутствующей. Если при этом бит О равен нулю, в страницу не выполнялось
никаких записей (с того момента, как этот бит последний раз обнулили) и ее во-
обще можно не сохранять.
Второе не менее важное применение страничной адресации — безопасная реали-
зация Йаё-модели памяти. Операционная система может разрешить программам
обращаться к любому линейному адресу, но отображение линейного пространства
на физическое не будет взаимно однозначным. Скажем, если система использует
первые 4 Кб памяти, физическим адресом нулевой страницы будет не ноль, а 4096
и пользовательская программа даже. не ‘узнает, что обращается не к нулевому
| Процессоры Н\е! в защищенном режиме ‘
адресу. В этом случае, правда, и сама система не сможет воспользоваться первой - }
физической страницей без изменения таблицы страниц, но эта проблема решает-.
ся при применении механизма многозадачности, о котором рассказано далее.
В следующем примере мы построим каталог и таблицу страниц (для нервых
4 Мб), отображающие линейное пространство в физическое один в один, затем
изменим физический адрес страницы с линейным адресом. 041000}. и попытаем-
ся выполнить обычный цикл закраски экрана в режиме 320х200х256, заполнив
видеопамять байтом с номером цвета, но у нас останется незакрашенным участок,
соответствующий перенесенной странице.
, рт3. азт
, Программа, ‘демонстрирующая страничную адресацию.
Переносит одну из ‘страниц, составляющих видеопамять, и пытается закрасить экран.

Компиляция:
ТАЗМ:
Тазт /т рт3З.азт
1]31К Их /З риЗ. 06]
О МАЗИ:
м1 /с. рм3. азт
Лик ртЗ.05),,МА,,,
МАЗМ: а
мазт ртЗ.азт
' мИпк Ре рт3З.05) Рогт 600$

.386р
АМ_зе9 зедтепф рага руб11с “С00Е” изе16
аззите сз:ЯМ_5е9, 9 :РМ_е9, 35: $таск_зе9
таг:
Подготовить сегментные регистры.
_ризв РМ_5е9
рор 98
; Проверить, не находимся пи мы уже в РМ.
моу еах, сго
те$т а1,1
37° ло_\86
; Сообщить и выйти,
по\ 9х,
от Рзеф у86_тз9
егг_ех1т; | ;
разв сз :
рор 9$
мо ап,9
111 21н
пом ав, 4Сн |
17 218

Убедиться, что мы не под \1паомз.


по_\86:
моу ах, 16001
1 2ЕВ
Сераничная адресация, о”
тезт а],а1
ру по_м1100м5
; Сообщить и выйти.
оу ах, ое ип _ 39
Этр 5ВогЕ егг_ех1+

: Сообщения об ошибках при старте.


\86_т59 46 “Процессор в `режиме У86 - нельзя ‚ переключиться |: РМ$"
- м1п_п$9 95 “Программа запущена под \1пдожз - нельзя перейти в кольцо 0$"

°; Итак, ‚мы точно находимся в реальном режиме. .


по_№1190м$ : .
; Очистить экран и переключиться в нужный видеорежин,
оу ах, 131 : :
ом и _
; Вычислить базы для всех дескрипторов.
< хог еах, еах
оу ах, ВМ_5е9
$11 вах, 4 |
оу мог4 ртг 60Т_1661168+2, ах
ЭГ ‚ вах, 16
моу ’.Буте руг 60Т_1651165+4,а1
моу ах, РМ_3е9
581 еах, 4
тоу мог@ рфг в0Т_3251165+2,ах
эИг вах, 16
моу вузе руг 60Т_325110$+4,а1
; Вычислить линейный адрес 6ОТ.
у хог еах, еах
оу ах, РМ_5е9
$1] еах,4
ризй вах
ад еах, о Рзеф б0Р
оу - Фиог@ рфг 94%тг+2,
вах
; Загрузить ВОТ.
1941 Рмог ртг 991г
; Открыть А20- в этом примере мы будем пользоваться памятью выше 1 М.
моу а},2
оц 92Н,а1
; Отключить прерывания
с11
Би ММГ.
11 а], ТОН
ог а}, 801
ош 708,а}
; Перейти в защищенный режим (пока без страничной адресации).
оу еах, сго
ог а],1
моу сго, еах

7 Зак. 459
ЕЖЕЗИШИШИ
ИИ И Процессоры ие! в защищённом. режимё , |
; Загрузить 65.
96 66н
96 ОЕАН
98 оРРзет РМ_ептгу ,
Чи ЗЕЁ_3251165 .

АМ_гетигп; |
; Переключиться в реальный режим с отключением. страничной адресации.
том еах, сго
апд еах, 7РЕРРЕЕЕВ
оу сгО, еах
; Сбросить очередь и загрузить 6$.
96 ОЕАВ у
дм $+4
Ч АМ_зе9
; Загрузить остальные регистры.
поу ах, РМ_5е9
тоу 9$, ах.
тоу е$, ах
‚ Разрешить ММГ.
п а1, 70Н
ап@ — а1,07ЕН
ош ТОН,а1
‚ Разрешить другие прерывания.
$11
‚ Подождать нажатия клавиши” 1
ту ап, 1 Е
и 218 —
‚ Переключиться в Текстовый режим
поу ах, 3 | о 3
пт 108 | - }
‚ и завершить программу. ь
моу ап, дсп
пе 218
АМ_зед епд$ ``». `

РМ_зе9 зедтеп{ рага риб]1с “С00Е” изеЗ2


| аззите —с$:РМ_зе9
; Таблица глобальных дескрипторов.
ан
а
а
бот ]абе1 уе ” -
96 8 44р(0)
бОТ_11а10$ 6 ОРЕй, РЕВ, 0,0,0, 10010010, 110011115, 0 .1
607_165116$ 6 ОРЕЛ, ОРРВ, 0,0,0, 100110106, 0,0 7
бОТ_3251165 95 ОРЕВ, ОРЕР, 0,0,0, 100110106, 116011116, 0 т
99=_$12е = $-60Т р Ё
94г @м 99+_317е-1 .. Ее лимит | |
94 ? ; и адрес. . ` .:
ЗЕЁ_11а{05 еди 0010006 ; Селектор 4-гигабайтного ‘сегмента данных." Е
ЗЕБ_16611С$ еди 0100006 : ; Селектор сегмента кода М_зе9. :
ЗЕЁ_ 3261405 еду 0110006 _; Селектор сегмента кода РМ_$е9.
: Точка входа в 32-битный защищенный режим.
РМ_епхгу:
; Загрузить сегментные регистры, включая стек.
хог еах, еах
тоУ ах, ЗЕ. Е1а10$
_ тоу 95, ах
оу ‚ ев, ах
; Создать’ каталог страниц. ‚ |
том 231; 001000001 - -. ; Его физический адрес - 1 Мб.
МОУ. вах, 001010071 ; Адрес таблицы 0 = 1 Мб + 4 Кб.
$10$49 `. : ... р Записать первый элемент каталога.
Роу еск, 1023 . ; Остальные элементы каталога -
хог < еах, вах ; нули.
_ гер 310$9 . .
; Заполнить таблицу страниц 0.
мо вах, 000000071 , ;.0 - адрес страницы 0.
оу есх, 1024 _ ; Число страниц в таблице..
раце_хаЫе: о В | ,
81050 _ - ; Записать элемент таблицы. -:
Ее еах, 000010001 ; Добавить к адресу 4096 байт
1оор раде_таБ Ле ; и повторить для всех элементов.
. Поместить адрес каталога страниц в 683. | |
мо вах, 001000008 ; Базовый адрес = 1 №6...
МОУ сг3З, еах
: Включить страничную адресацию.
тоу еах,сг0о —
ог еах, 800000001
по сгО, еах ° '
; А теперь изменить физический ‘адрес страниц АТО00Н на А200ОН.
тоУ еах, 000А20071 .:
поу е$:001010001+0А1И*4, еах
`_; Если закомментировать предыдущие две ‘команды, следующие четыре
: закрасят весь экран синим цветом, но из-за того, что мы переместили одну
; страницу, останется черный .участок. . 7
моу есх, (320*200)/4 ; Размер экрана в двойных словах.
воу е91, ОА0ОбОн ‚; Линейный адрес начала видеопамяти.
ОУ еах, 010101011 . : Код синего цвета в УбА - 1. |
_гер $1054 |
; Вернуться в реальный режим.
['°) ОЕАВ
94 оЁРзее ВМ_гетиогп
Ч ЗЕК_ 1661165
РМ_5е9 епдз

; Сегмент стека - используется как 16-битный.


этаск_3е9 зедтеп{ рага зфаск “5ТАСК”
эфаск_зтаге в 1004 9ир(?)
зТаск_5е9 614$
епа ‘втагт
‚ЕСИ
ИИ ИИ Процессоры гие! в защищенном режиме:
10.7. Механизм защиты
Теперь рассмотрим механизм, который дал название режиму процессора, — меха-
низм защиты. Защита может действовать как на уровне сегментов, так и на уров- 2
не страниц, ограничивая доступ в зависимости от уровня привилегий (четыре -
уровня привилегий для сегментов и два для страниц). Она предотвращает воз- ;
можность вносить изменения в области памяти, занятые операционной системой 1
или более привилегированной программой. Процессор проверяет привилегии не-
посредственно перед каждым обращением к памяти и, если происходит наруше-
ние защиты, вызывает исключение #СР.
Когда процессор находится в защищенном режиме, проверки привилегий выпол-
няются всегда и их нельзя отключить, но можно использовать во всех дескрипторах
и селекторах один и тот же максимальный уровень привилегий - нулевой, и созда-
стся видимость отсутствия защиты. Именно так мы поступали в вышеописанных
примерах - поля РЕ. и ВЕРЕ. инициализировались нулями. Для осуществления не-
заметной проверки прав на уровне страничной адресации надо установить биты Ц
и У" во всехэлементах таблиц страниц, что мы также выполняли в программе риа3З.азта.
За механизм защиты отвечают следующие биты и поля:
Ов дескрипторах сегментов:
— бит $ (системный сегмент);
— поле типа (тип сегмента, включая запреты на чтение/запись);
— поле лимита сегмента;
— поле ОРГ, определяющее привилегии сегмента или шлюза, указывает, по
крайней мере, какой уровень привилегий должна иметь программа, чтобы
обратиться к этому сегменту или шлюзу;
О в селекторах сегментов: .
— поле ВРГ, определяющее запрашиваемые привилегии, позволяет програм-
мам, выполняющимся на высоких уровнях привилегий, обращаться к сег-
ментам, как будто их уровень привилегий ниже; /
— поле КРГ.селектора, загруженного в С$, называется СРЕ. и является теку-
щим уровнем привилегий программы;
Ов элементах таблиц страниц:
— бит О (определяет уровень привилегий страницы);
-— бит \\ (разрешает/запрещает запись).
Уровни привилегий в процессорах ще:
90 — максимальный (для операционной системы);
Я1и2 — промежуточные (для вспомогательных программ);
Я 3 — минимальный (для пользовательских приложений). у
Перед обращением к памяти процессор выполняет несколько типов проверок,
использующих все указанные флаги и поля. Рассмотрим их по порядку.
.10.7.1. Проверка лимитов
Поле лимита, в дескрипторе сегмента запрещает доступ к памяти за пределами
сегмента. Если бит С дескриптора равен нулю, значения: лимита могут быть от 0 до.
ОБЕЕЕЕВ (1 Мб). Если бит С установлен— отОЕЕРЕВ (4 Кб) до ОЕЕЕЕЕЕЕЕЬ (4 16).
Для сегментов, растущих вниз, лимит принимает значения от указанного плюс 1 до
ОЕКЕРВ для 16-битных сегментов данных и до. ОЕЕЕЕЕЕЕЕВ- для 32-битных. Эти
проверки отлавливают такие ошибки, как неправильные вычисления адресов.
Перед проверкой лимита в дескринторе процессор выясняет лимит самой табли-
цы дескрийторов на тот случай, если указано слишком большое значение селектора.
Во всех случаях‘исключение #СР вызывается с.кодом ошибки, равным индек-
‚су. селектора, посредством которого нарушается защита.

10.7.2. Проверка типа сегмента. ,


1. Загрузка селектора (и дескриптора) в регистр:
в С$ можно загрузить только сегмент кода;
в 2$, Е$, Е5,С5 можно загрузить только селектор сегмента данных, сег-
мента кода, доступного для чтения, или нулевой селектор;
в $$ можно загрузить только сегмент данных, доступный для записи;
в ОТВ можно загрузить только сегмент ГОТ;
в ТК можно загрузить только сегмент Т55. р
2. Обращение к памяти:
никакая команда не может писать в сегмент кода;
никакая команда не может писать в сегмент данных, защищенный от записи;
`никакая команда не может читать из сегмента кода, защищенного от чтения;
нельзя обращаться к памяти, если селектор в сегментном регистре нулевой.
3. Исполнение команды, использующей селектор в качестве операнда:
дальние САЦ. и] МР могут выполняться только в сегмент кода, шлюз вы-
зова, шлюз задачи или сегмент Т$$;
команда Е.1.ОТ может обращаться только к сегменту тот,
команда ГТВ может обращаться только ‘к сегменту Т$$; ^
„команда [АК может обращаться только к сегментам кода и данных, шлю-
зам вызова и задачи, [ОТи Т$5;
команда 1.5[.может обращаться только к сегментам кода, данных; тот и 15$;
элементами ШТ могут быть только шлюзы прерываний, ловушек и задач.
4. Некоторые внутренние операции:
при переключении задач целевой дескриптор может быть только ›Т5$ или
шлюзом задачи; —
при передаче управления через шлюз сегмент, на который шлюз указыва-
ет, должен быть сегментом кода (или Т$$ для шлюза задачи); .
при возвращении ‘из. вложенной задачи: селектор в поле связи Т$$ дол-
‚ жен быть селектором сегмента Т5$5. но:

10.7.3. Проверка привилегий.


Все неравенства здесь арифметические, то всть А> В означает, чтоуровень
привилегий А меньше, чем В: ы
’Опри загрузке регистра 0$, Е$, Е$ или 5 должно
д выполняться ‘условие:
ОР! > шах(ВРГ,СРГ.); /
ЕЗИИВОНИНИИ ВНИИ! Процессоры ие! в защищенном ‘режиме -
. О при загрузке регистров 5$ должно выполняться условие: ОР1. =СРЕ-ВРГ;
О при дальних ]МР, САМ, ВЕТ на неподчиненный сегмент кода должно вы-
полняться условие: ОРТ, = СРТ. (ЕР. игнорируется); ,
О при дальних ]МР, СА, ВЕТ на подчиненный сегмент кода должно выпол-
няться условие: СРТ. > ОРГ. При этом СРУ. не изменяется;
О при дальнем СА. на шлюз вызова должны выполняться условия: 'СРЬ < ОРГ.
шлюза, КРГ.< ОРТ. шлюза, СРТ. > ОРУ. сегмента; |
О при дальнем ] МР на шлюз вызова должны выполняться условия: СРГ. < ОРГ,
шлюза, КРЁ. < ОРГ шлюза, СРТ, > ОР]. сегмента, если он подчиненный,
СР. = ОР: сегмента, если он неподчиненный.
При вызове процедуры через шлюз на неподчиненный сегмент ‘кода с другим
уровнем привилегий процессор выполняет переключение стека. В сегменте Т55
текущей задачи всегда хранятся значения $5:Е$Р для стеков уровней привиле-
гий 0, 1'и2 (но не стек для уровня привилегий 3, потому что нельзя выполнять
передачу управления на уровень 3, кроме как при помощи команд ВЕТ/ЛВЕТ).
При переключении стека в новый`стек помещаются, до обратного адреса, пара-
метры (их число указано в дескрипторе шлюза вызова), флаги или код ошибки
(в случае ПМТ), старые значения 5$:ЕЗР; которые команда ВЕТ/ТВЕТ использует \
для обратного переключения. То, что надо выполнить возврат из процедуры, ВЕТ. 3
определяет так: КРТ. селектора, оставленного в стеке, больше (менее привилеги- -.
рованный), чем СРГ.
Даже если операционная система не поддерживает многозадачность, она дол- |
жна оформить сегмент Т$$ с действительными $55:Е$Р для стеков всехх уровнейу” }
если она собирается использовать уровни привилегий. | р

10.7.4. Выполнение привилегированных команд.


1. Команды СОТ, ЫОТ, ГТК, ОТ, МОУ СВп, ГМ$У, СЕТ, мо\У РЕВп,
ВМУО, \УВТМУО, ПМУГРС,. НЕТ, ВОМ$В, \УВМ$В, ВОРМС, ВОТЗС,
ЗУ$БХИТ могут выполняться, только если СР. =0 (хотя биты РСЕ и ТЗО
_ сегмента СВА разрешают использование команд ВОРМС и ВОТ5С с любо-
го уровня).
2. Команды ОТ, 5ЕОТ, ТВ, ТВ, 131, ГАК, УЕВВ, ЕВ 1
и АВР. можно
выполнять только в защищенном режиме — вв реальном и \86 возникает ис-
‚ключение #00. .
3. Команды Си $Т1 Выполняются, только т если СРГ. < РЕ, ОРТ. это двух-
битная область в регистрефлагов). Если установлен бит РУТ в регистре СКА,
эти команды выполняются с любым СРГ,, но управляют флагом УЕ а не 1Ё
4. Команды ПМ, ОПТ, ПУ5В, 1$, 14$), ОЧТЗВ, ОЧТ$\, ОУТ$Р выпол-
няются, только если СР1. < ТОРГ и если. бит в битовой карте ввода-вывода,
соответствующий данному порту; равен нулю. (Эта карта= битовоеполе
в сегменте Т$$, каждый бит которого отвечает за. один порт ввода-вывода.
Признаком ее конца служит слово, в котором все 16 бит установленыв 1.)
Управление задачами — ‘^ _пинниииинио
` 10.75. Защита на уровне страниц^
1. Обращение к странице памяти с битом о в атрибуте страницы или таблицы
страниц, равным нулю, приводит к исключению #РЕ, если СРГ.= 3.
2. Попытка записи в страницу с битом \/ в атрибуте страницы или таблицы
страниц, равным нулю, с СРГ.= 3 приводит к исключению #РЕ _
3. Попытка записи в страницу с битом \\ в атрибуте страницы или таблицы
‘страниц, равным нулю, если бит \Р в регистре СКО равен 1, приводит к ис-
ключению #РЕ |

10.8. Управление задачами


Следующий очень важный механизм, действующий только в защищенном ре-
жиме, — многозадачность. Задача— это элемент работы, которую процессор мо-
жет исполнять, запустить или отложить. Задачи используют для выполнения про- |
грамм, процессов, обработчиков прерываний и исключений, ядра онерационной
системы и пр. Любая программа, выполняющаяся в защищенном режиме, должна
осуществляться как задача (хотя мы пока игнорировали это требование). Процес-
сор предоставляет средства для сохранения состояния задачи, запуска задачи и пе-
редачи управления из одной задачи в другую. .
Задача состоит из сегмента состояния задачи (Т$5), сегмента кода, одного или
‚ нескольких (для разных уровней привилегий) сегментов стека и одного или не-
скольких сегментов данных. Она определяется селектором своего сегмента Т$5.
Когда задача выполняется, ее селектор Т5$ (вместе с дескриптором в скрытой
части) загружен в регистр ТК. процессора.
Запуск задачи осуществляется при помощи команды САЦ. или ] МР на сег-
мент Т5$ или на шлюз задачи, а также при запуске обработчика прерывания или
исключения, который описан как шлюз задачи. При этом автоматически осуще-
ствляется переключение задач. Состояние текущей задачи записывается в ее Т55,
состояние вызываемой задачи считывается из ее Т55, и управление передается на
новые С$:ЕТР. Если задача не была запущена командой ]МР, селектор сегмента
Т$$ старой задачи сохраняется в Т5$ новой и устанавливается флаг МТ, так что
следующая команда 1ВЕТ выполнит обратное переключение задач... >
Задача не может вызываться рекурсивно. В дескрипторе Т55-задачи, которая
была запущена, но не была завершена, тип изменяется на «занятый Т55»и пере-
ход натакой Т$5 невозможен.
Задача может иметь собственную таблицу дескрипторов <«ГОТ)и: полный ком-
плект собственных таблиц страниц, так. как регистры ГОТК и СВЗ: входят в со-
стояние задачи. _

` 10.81, Сегмент состояния задачи В


- Сегмент состояния задачи (ТЗ$) - это структура данных, в которой сохраня-
ется вся информация о задаче, если ее выполнение временно прерывается.
5201 ТП | Процессоры те! в защищенном режиме _
Т$5 имевт следующую структуру:
+00Ъ: 4 байта.- селектор предыдущей задачи (старшее слово содержит нули -
° _ здесь и для всех остальных селекторов) Е
+041: 4 байта - ЕР для СРЕ.= 0
+081: 4 байта - $$ для СР. =0
+0СКВ: 4 байта - Е$Р для СРТ. = 1
+10Ъ: 4 байта - $$ для СРГ. = 1.
° +146: 4 байта — ЕЗР для СР1.=2
+186: 4 байта - $5 для СРЕ=2
+1СВ: 4 байта - СВЗ —
+20Б: 4 байта - ЕТР
+24Ъ: 4 байта - ЕЕГАС$
+288: 4 байта - ЕАХ
+2СВ: 4 байта - ЕСХ
+305: 4 байта - ЕБХ .
+345: 4 байта - ЕВХ
‚ +38: 4 байта - Е5Р
' +3СЬ: 4 байта - ЕВР.
+40Ъ: 4 байта — ЕЗТ
+446: 4 байта — ЕБТ
+48: 4 байта - Е$
+4СЬ: 4 байта —-С$
+505: 4 байта - $$
+546: 4 байта - 0$
+588: 4 байта - Е$
+5СЬ: 4 байта—-С5
+601: 4 байта - ГОТВ:
+641: 2 байта— слово флагов задачи_
бит0’ - флаг Т. вызывает #0В при переключении на задачу
- остальные биты не определены и равны нулю
+66}: 2 байта — адрес битовой карты ввода-вывода. Это 16-битное смещение от
начала Т$5, по которому начинается битовая карта разрешения
ввода-вывода (см. разделы 10.7.4 и 10.9.2) и заканчивается бито-
вая карта перенаправления прерываний (см. раздел 10.9.1)) дан-
ной задачи.
‚Т$$ является полноценным сегментом и описывается сег ментным дескрипто- . 1
ром, формат которого мы рассматривали раньше (см. раздел 10. 4.3). Кроме того,
лимит Т5$ не может быть меньше 67}— обращение к такому дескриптору приво-
дит к исключению #Т5. Размер Т$$ может быть больше, если в него входят бито-
вые карты ввода-вывода и перенаправления прерываний и если операционная
система хранит в нем дополнительную информацию. Дескриптор Т$$ способен
находиться только в СОТ - попытка загрузить его из ГОТ вызывает исключение
#СР. Для передачи управления задачам удобнее использовать дескрипторы шлю-
за задачи, которые можно помещать как в СОТ, так и в ГОТ или ШТ.
Управление задачами МОСС
10.8.2. Переключение задач |
Переключение задач осуществляется, если:

Отекущая задача выполняет дальний ]МР или САМ. на шлюз задачи или пря-
мо на Т$5;
О текущая задача выполняет 1ВЕТ, если флаг МТ равен 1;
О происходит прерывание или исключение, в качестве обработчика которо-
гов ОТ записан шлюз задачи.

Пипереключении процессор выполняет следующие действия:


1. Для команд СА. и]МР проверяет привилегии (СРТ. текущей задачи и КРИ.
селектора новой задачи не могут быть больше, чем ОРГ. шлюза или Т5$, на
который передается управление).
ое). Проверяется дескриптор Т5$ (его бит присутствия и лимит). ‹
. Проверяется, что новый Т$$5, старый Т$$ и все дескрипторы сегментов на-
ходятся в страницах, отмеченных как присутствующие.
. Сохраняется состояние задачи.
. Загружается регистр ТВ. Если на следующих шагах происходит ‘ибключе-
ние, его обработчику придется доделывать переключение задач, вместо того
чтобы повторять ошибочную команду.
. Тин новой задачи в дескрипторе изменяется
1 на занятый, и флаг Т$ устанав-
ливается в СКО.
. Загружается состояние задачи из нового Т5$: ГОТВ, СВЗ, ЕЕГАС$, ЕТР, ре-
гистры общего назначения и сегментные регистры.

Если переключение задачи вызывается командами \ОМР, САЦ, прерывани-


ем или исключением, селектор Т55 предыдущей задачи записывается в поле свя-
зи новой задачи и устанавливается флаг МТ. Если флаг МТ установлен, команда
ТВЕТ выполняет обратное переключение задач.
При любом запуске задачи ее тип изменяется в дескрипторе на занятый. По-
пытка вызвать такую задачу приводит к #СР. Сделать задачу снова свободной
можно, только завершив ее командой 1ВЕТ или переключившись на другую зада-
чу командой МР .
| На следующем примере покажем, как создавать задачи и переключаться меж-
ду ними.
з

рт4. аз
Пример программы, _ выполняющей переключение задач.
Запускает две задачи, передающие управление друг другу 80 раз, задачи выводят
на экран символы АЗСТТ с “небольшой задержкой:
Компиляция : `
ТАЗМ:
Тазт /т рм4.азт
пк Их /3 ри4.06]
МАЗМ:
, мазт рт4.азт
, м11пК 111е рт4.06} Гогт.00$
неее
Процессоры \{е! в защищенном режиме

м] /с ри4. аз
Ик ри4.063,,МИЕ,,,

. 386р
АМ_зед зедтеп{ф рага риб11с “СО0Е” изе16
аззите с5:ВМ_зе9,
45:РМ_3е0, 53: зтаскК_5е0

: Подготовить сегментные регистры,


ризв РМ_5е9
рор 98
‚ Проверить, не находимся ли мы уже в РМ.
моу еах, сго
тезт а1,1
. 2 по_\86 *
‚ Сообщить и выйти.
том 9х, оРРзе{ у86_т$9
егг_ех1т:
ризй с5 ”
‘рор 9$
МОУ ан,9
17 218
моу ‘ан, 4Сп
11 218

; Убедиться, что мы не под И1пдомз.

тому ах, 16008


1" ЕВ
тезт а],а1
Ву по_м1100м$
; Сообщить и. выйти.
моу 9х, оРРзет м1п_тз9
пр эПогЕ егг_ех1т

‚ Сообщения об ошибках при старте.


5 "Процессор в режиме \86’- нельзя переключиться в
Г’ “Программа запущена под МА пфом$ — нельзя перейти в кольцо 0$"

; Итак, мы точно находимся в реальном режиме.


по_м1п00м5: `
‚ Очистить экран,
том ах,3
1м 10%
; Вычислить базы для всех дескрипторов сегментов данных.
хог еах, еах
оу ах, ВМ_зе9
38] еах,4
оу мога руг бОТ_1651165+2,ах
Аг еах, 16
оу Бусе рфг бОТ_165116$+4,а1
моу ах, РМ. зед
31] вах,4
по мога руг 60Т_3261105+2,ах
моу мог рег СОТ_32611$$+2,ах С
ЗАг еах, 16
моу ‘руте руг 60Т_326511С$+4,а1
моу Буте руг 60Т_3261455+4,а1
; Вычислить линейный адрес 60Т.
хог еах, еах
тому ах, РМ_зе9
$8] еах,4
ризВ еах '
а34 еах, оЕЁРзет бот
моу ЧиогЯ руг 94%г+2,еах _
; Загрузить 607.
1991 Тмог@ руг д99г
; Вычислить линейные адреса сегментов Т55 наших двух задач.
рор еах
ризН еах
249 < еах, оЕЕРзет 155_0
моу мога руг бОТ_Т$$0+2,ах
$Вг еах, 16 ^_
мо Буте руг бОТ_Т$$0+4,а1
рор вах
ад9 еах, оЕзет Т55_1
ту ‘мога рег ВОТ _Т5$1+2,ах
эйг еах, 16
| моу Буте ртг 60Т_Т$$51+4,
а1
; Открыть А20.
моУ а1,2
ош 921,а1.
! Запретить прерывания.
с]1
; Запретить ММГ..
1п а1, 708
ог ’ а1, 808
. сит ТОН, а1
; Переключиться в РМ.
том еах, сго ]
ог а1,1
_» МОМ сго, еах
; Загрузить 65.
96 668
35 ОЕАВ
94 оЁРзет РМ-ептгу
Чи ЗЕЁ_3251168

АМ_гетиги: |
; Переключиться в реальный режим ВМ:
моу еах, сго
{| Процессоры ие! в защищенном режиме
апа а1, ОРЕН р
мо\у сг0, еах
; бросить очередь предвыборки и загрузить 0$.
96 ОЕАВ
9м $+4 *
дм ВМ_зе9
; Настроить сегментные регистры для ‘реального режима.
ей ах, РМ_зе9
оу 9$,ах
тоу ез, ах
поу ах, зтаск_5е9
оу Ьх, зтаск_1 у
тоу . 8$, ах
ту эр,Бх
; Разрешить ММТ.
11 а], 70Н
апд а1, О7ЕН
ош 708, а1
; Разрешить прерывания.
$11 у
; ‘Завершить программу.
оу ав, 4СВ
11% 218
АМ_зе9 епд$

РМ_зед зедтепе рага риуб11с "С00Е” изеЗ2


аззиме сз:РМ_зе9 ‹

; Таблица ‘глобальных дескрипторов.


вот ]абе1 Буте
Ге) 8 9ир(0)
СОТ_Р]а{0$ ` 95 ОЕЕВ, ОРЕВ, 0,0,0, 100100106, 110011116, 0
60Т_1661165 [9 ОЕЕА, ОРЕИ, 0,0,0, 100110106,0,0
СОТ_326116$ Ч6 ОРЕН, ОРЕВ, 0,0,0, 100110106, 130011116,0
С0Т_32611$5 Ге) ОЕЕп, ОРЕА, 0,0,0, 100100105, 110011116,0
; Сегмент. Т$3 задачи 0 (32-битный свободный Т55). :
бот_15$0 [ее 0671,0,0,0,0, 100010015, 010000006, 0
‚ ; Сегмент Т5$ задачи 1 (32-битный свободный Т$$).
ВОТ _Т5$1 95 067, 0,0,0,0, 100010016, 01000000, |
одвле = $-С0Т | 8
оЧЕг Ом 99_$17е-1 ; Размер ВОТ.
99, ? ; Адрес 607.
‚ Используемые селекторы.
ЗЕЁ_Ё]а{0$ еду 0010006
ЗЕЁ_166110$ еди 0100005.
ЗЕЁ_326116$ еди ‚0110006 й
ЗЕ. 3261155 еди 1000006
ЗЕЕ. Т$$0 еду 1010005
ЗЕЕ_Т8$1 еди 110000
Управлемие задачами ^^ №
; Сегмент Т5$_0 будет инициализирован, как только мы выполним переключение
; из нашей основной задачи. Конечно, если бы мы собирались использовать
; несколько уровней привилегий, то Нужно было бы инициализировать стеки.
1$$_0 _ 96 681 вир{о)
; Сегмент Т$$_1. В него будет. выполняться переключение, поэтому надо
; инициализировать все, что может потребоваться: ` `
1581 909 0,0,0,0,0,0,0,0 -_; связь, стеки, С8З
94 оРЁзет тазк_1, ; ЕР.
; Регистры общего назначения.
99. 0,0,0,0,0, зтаск_12,0,0,0881401 ; (ЕЗРи ЕТ)
; Сегментные регистры. р .
. | [9] ЗЕЕ 1 а05, $Е-_326146$, ЗЕЁ_32511$$, ЗЕ 114105, 0,0
06 0 , ; ВТА.
99 0 : ; Адрес таблицы ввода-
. ; вывода.

‚ Точка входа в 32-битный защищенный, режим. ..-


РМ_ептгу:
; Подготовить ‘регистры.
хог еах,еах
оу ах, ЗЕЁ_Р1а10$
тоу 9$,ах
ое е5, ах
оу ах, $Е1_3261153
`моу = еБх, зфаск_1
тоу $$, ах
тоу езр,ебх.
‚ Загрузить 155 задачи 0 в регистр ТН.
° ПОМ ах, ЗЕЁ_Т550
Аг ах . .
; Только теперь наша программа выполнила все требования к переходу
‚ в защищенный режим,

хог еах, еах


оу е91, 0880008 ‚ ; 05:ЕОТ - адрес. начала экрана.
тазк_о:
том Буще руг 93:[е91}, а] ; Вывести символ АС на экран.
: Дальний переход на Т55З задачи 1.. -
96 ОЕАН
99 0
Чи ЗЕ .Т$81 .. : ,
а94 е91,2 у : ; 0$:ЕБТ - адрес следующего
| ;, символа.
1пс а1 ; АЁ - код следующего символа,
стр а1, 80 . ; Если это 80,
35 ° Тазк_@ ; выйти из цикла.
; Дальний переход на процедуру выхода в реальный режим.
4 ‚ ОЕАВ
94. огР5ет ВМ_гефигп
9 ЗЕЁ_1661%0$
ЭВ! Процессоры н\е! в защищенном режиме
; Задача 1.
Тазк_1:
оу Буте рег 93: [е41],а1 ; Вывести символ на экран.
Тис `а1 ° р Увеличить код символа.
а9д . 641,2 ‚ Увеличить адрес символа.
; Переключиться на задачу 0. ‚ ‚ . |
5 ОЕАВ -
99 0
ди ЗЕЁ_Т5$0 |
; Сюда будет приходить управление, когда задача 0 начнет выполнять переход
; на задачу 1 во всех случаях, кроме первого.
| мам есх, 020000008 ; Небольшая пауза, зависящая от скорости
1юоор $. ; процессора,
Этр тазк_1 |
РМ_вед епдз

з{аск_зе0 зедтепт рага этаск “5ТАСК” .


\ эфаск_зэТагт 45 1001 9ир{?) ; (тек задачи 0.
зТаск_1 = $-зТаск_зТаге
зТаск_тазК2” 96 1001 `Чир(?) ; Стек задачи 1.
$Таск_12.= $-зтаск_зТагт
зТаск_зе9 `. паз
. епо ‘таг
Чтобы реализовать многозадачность в реальном времени на нашем примере,
достаточно создать обработчик прерывания системного таймера 1ВО0 в виде от-
дельной (третьей) задачи и поместить в ШТ шлюз этой задачи. Текст обработчи-
ка для нашего ‘примера мог быть крайне простым:
Тазк_3: ; Это отдельная задача - не нужно сохранять регистры!
по\ а1, 201
оц 201,а1
Этр Тазк_0
° МОУ а1, 201
бит. 20, а].
Эир Та$к_1
„№ 19%)
Нопривызове обработчика прерывания старая задача помечается как занятая
в СОТ и повторный ] МР на нее приведет к ошибке. Вызов задачи обработчика
прерывания, так же как и вызов задачи командой САГТ, подразумевает, что она
завершится ‘командой ТВЕТ. Именно команду 1ВЕТ проще всего вызвать для пе-
редачи управления из такого обработчика - достаточно лишь подменить селек.
тор вызвавшей нас задачи в поле связи и выполнить ВЕТ.
Тазк_3: ; При инициализации 0$ должен быть установлен на РМ 569.
моу а1, 201
о. 201,а1
том мога руг Т$$_3, $ЕЁ_Т5809
16+ |
тоу а], 201
о 201, а1
моу могЧ рфг Т5$_3, ЕЕ _15$1
1гет
р Тазк_3

Единственное дополнительное изменение, которое нужно внести, — инициали-


зировать дескриптор Т$$ задачи (азК_1 как уже занятый, поскольку управление
‚ на: него будет передаваться. командой ВЕТ, что, впрочем, не вызывает никаких
проблем.
_ Помните, что во вложенных задачах команда ТВЕТ не означает конца програм-
мы — следующий вызов задачи всегда ‘нередает управление на очередную коман-
ду после ВЕТ.

10.9. Режим виртуального. 8086


Режим \86 - это задача, исполняющаяся в защищенном режиме, в которой
флаг УМ регистра ЕЕГАС$ равен единице. Внутри задачи процессор ведет себя
так, как если бы он находился в реальном режиме, за исключением того, что пре-_
рывания и исключения передаются обработчикам защищенного режима вне ее
(кроме случая, когда используется карта перенаправления: прерываний).
Программы не могут изменить флаг УМ. Его допускается указать, только за-
писав, образ ЕЕГ.АС$ с установленным УМ при создании Т$$ новой задачи И за-
тем переключившись на нее. Кроме этой задачи для нормальной реализацки \У86
требуется монитор режима (УММ) - модуль, который выполняется с СР. = 0
и обрабатывает прерывания, исключения и обращения к портам ввода-вывода из
задачи \86, осуществляя фактически эмуляцию всего компьютера.
Чтобы выполнять в системе сразу несколько У86-задач, применяется странич-
ная адресация. Каждая У86-задача использует ровно один мегабайт линейного ад-
ресного пространства, который можно отобразить на любую область физического.
Процессор переключается в \У86 в трех ситуациях:
О при переключении в задачу, Т55 которой содержит установленный‘флаг УМ;
О при выполнении команды 1ВЕТ, если МТ = 0’'и копия ЕЕГАС$ в стеке содер-
_ жит установленный флаг УМ;
Опри выполнении команды ТВЕТ,еслии МТ - 1 и копия ЕРГАС: В 15$ содер-.
„жит установленный флаг УМ. : о.
` 10.94, Прерывания в Увб те. г. |
Если происходит прерывание или,исключение |в режиме 86, процессор ана-
лизирует биты ТОРГ. регистра: флагов, бит УМЕ регистра СВА. (Репёйиа и выше)
и соответствующий бит из карты перенаправления прерываний данной задачи
(только если УМЕ = 1).
Эта карта- 32-байтное поле, находящееся в регистре 'Т55 данной задачи, на пер-
вый байт за концом которой указывает смещение в Т5$ по адресу +66Ъ. Каждый
из 256 бит этого поля соответствует одному номеру прерывания. Если он уста-
новлен в 1, прерывание должно подготавливаться обработчиком из ШТ в защи-
щенном режиме, если он 0 - то 16-битным обработчиком из реального режима.
ШЕИ Процаесврыиче! в-защищенном режиме
Если УМЕ = 0, прерывание обрабатывается (через ТОТ) при условии, что
ТОРУ.= 3, иначе вызывается исключение #СР
Если бит УМЕ = 1 и ОРГ= 3, обработка прерывания определяется битом из
битовой карты перенаправления прерываний. ,
Если УМЕ - 1, ОР < З›и бит. =.‘битовой карте равен единице; вызывается.
обработчик из ШТ. | |
Если УМЕ = 1, ОРГ. <Зибитв битовойкарте равен нулю; происходит следу-
ющее:
если АЕ 0 или если УТЕ=1.1но произошло исключение
и или ММТ - вызы-
`_ вается обработчик из реального режима; "
бесли УЕ = 1 ипроизошло аппаратное прерывание — ‘вызывается обработчик
#СР из защищенного режима, который должен обработать прерывание,
установить флаг УТР в копий ЕЕГАС$ |в стеке и вернуться в У86; р
Оесли УР -Ти\МЕ=0 из-за выполненной в У86 команды СЕТ - вызывается |
° обработчик #СР из реального режима, который должен ‘обнулить \МЕи МР
в копии ЕЕГАС$ в стеке.
Бит УТЕ-это флаг для облегчения поддержки команд СП] и ЭТИ в задачах \У86.
Если в ‘регистре СВ4` ‘установлен бит УМЕ, команды СТЛ/ЗТ1 изменяют значение
именно этого флага, оставляя 1Е нетронутым для того, чтобы операционная: сис-
тема могла обрабатывать прерывания и управлять другими задачами.
При вызове обработчика, находящегося в защищенном режиме, из реального
режима в стек нулевого уровня привилегий помещаются' 6$, Е$, 0$, Е$‚. $$,
ЕЕГАС$, С$, ЕТР и код ошибки для некоторых исключений в этом порядке, а фла-
ги УМ, ТЕ и ТЕ обнуляются, если вызывается шлюз прерывания.

10.9.2. Ввод-вывод в У86 .


В режиме \86 текущий уровень привилений, СРГ., всегда. равен трем. В со-
ответствии с правилами защиты выполнение команд СМ, ЭТЬ РОЗНЕ РОРЕ.
МТ и ВЕТ приводит к исключению 'ЁСР, если ТОРЕ, < 3. Однако команды ПМ,
ОЧТ, 1М5$, ООТ$, ‚ чувствительные к ТОРЕ. в защищенном режиме, в У86 управ-
ляются битовой картой ввода-вывода,‚ расположенной в Т5$ задачи. Если бит,
соответствующий порту, установлен в 1, обращение к нему из М86-задачи при- `
водит к исключению # СР; если бит«брошен - команды работы с портами вво-
да-вывода ВЫПОЛНЯЮТСЯ,
`Мыне будемрассматривать пример прораммы, реолноующей режим У86, из-
39 610 размеров Практически веб 13 ТОГО, что Необходимо для его создания о

пе ть МЫ Ро
уе жи
об оба
ул боч
и. авпра ров ани й"ранили ый
ЗАДаЧ),
и р

Глава 11. Программирование


на ассемблере в среде ОМХ
Операционная система М$ 2ОО$, получившая дальнейшее развитие в виде
УЛп4о\з, долгое время была практически единственной ОС для персональных
компьютеров на базе процессоров [(е!. Но с течением времени мощность процес-
соров выросла настолько, что для них стало возможным работать под управлением
операционных систем класса УМХ, использовавшихся обычно на более мощных
компьютерах других компаний. В настоящее время существует свыше двадцати
операционных систем для пие|, представляющих те или иные диалекты УМХ.
Мы рассмотрим самые популярные из них: | о
О Цпих- бесплатно распространяемая операционная система, соединяющая
в себе особенности двух основных типов ОМГХ-систем (Зузет У и В5О)
‘приблизительно в равной мере. В ней много отличий и отступлений от лю-
бых стандартов, принятых для МХ, но они более эффективны;
о ЕгееВ$О- бесплатно распространяемая операционная система, представля-
ющая вариант В5Р ОМХ. Считается наиболее стабильной из ОМХ-систем
для И\е|;
0 50]а115/х86 — коммерческая операционная система компании Зип Мгсго-
зузетз, представляющая вариант Зузет У ОМХ, изначально созданная для
компьютеров $ип, существует в версии для Те! 80х86. Распространяется
бесплатно с образовательными целями.
Несмотря на то что при программировании для ОМХ обычно употребляется
исключительно язык С, пользоваться ассемблером в этих системах можно, и даже
очень просто. Программы в МХ выполняются в защищенном режиме.с моде-
лью памяти Йа и могут вызывать любые функции из библиотеки НЬс или других
библиотек точно так же, как это делают программы на С. Конечно, круг задач, для
которых имеет смысл использовать ассемблер в ОМХ, ограничен. Если вы не за-
нимаетесь разработкой ядра операционной системы или, например, эмулятора
ТО$5, практически все можно сделать и на С, но иногда нужно создать что-то осо-
бенное. Написать процедуру, выполняющую что-то как можно быстрее (напри-
мер, воспроизведение звука из файла в формате МР3), или программу, использу-
ющую память более эффективно (хотя Это часто можно повторить на С), или
программу, применяющую возможности нового процессора, поддержка которого
еще не добавлена в компилятор, оказывается очень просто (если вы знаете ассем-
блер для ОМХ). |
| 5351 1111 | Ассемблер в среде УМХ
11.1. Синтаксис АТ&Т
Проблема в том, что ассемблер для УМХ кардинально отличается от того, чте
рассматривалось в этой книге до сих пор. В то время как основные ассемблеры|
для М5 ОО5 и УЙп4о\%$ используют синтаксис, предложенный компанией [п6&,
изобилующий неоднозначностями, часть которых решается за счет использова-
ния поясняющих операторов типа Буе р, мог4 ри или 4\ог4 ры, а часть не ре-
шается вообще (все те случаи, когда приходится указывать код команды вруч-
ную), в ОМХ с самого начала используется вариант универсального синтаксиса |
АТ&Т, синтаксис ЗузУ /386, который специально создавался с целью устранения
неоднозначностей в толковании команд. Вообще говоря, существует и ассемблер
для РО5/ЛМ 40%, использующий АТ&Т-синтаксис, — это 523, входящий в набор
средств разработки О] СРР а также ассемблер, использующий [ш(е]-синтаксис
и способный создавать объектные файлы в формате ЕТ. применяемом в большин-
стве ОМХ-систем, — это бесплатно распространяемый в Ицегпе ассемблер МА$М.
Мы будем рассматривать только ассемблеры, непосредственно входящие в состав
операционных систем, то есть те, которые вызываются стандартной командой а$.
11.1.1; Основные правила
|

Итак, в ассемблере АТ&Т в качестве допустимых символов текста программы


рассматриваются только латинские буквы, цифры и символы % (процент) $ (дол-
лар), * (звездочка), . (точка), ‚ (запятая) и _ (подчеркивание). Помимо них суще-
ствуют символы начала комментария, отличающиеся для разных ассемблеров
и для комментария размером в целую строку или правую часть строки. Любые
другие символы, кроме кавычек, двоеточия, пробела и табуляции, если они не
часть комментария или не заключены в кавычки, считаются ошибочными.
Если последовательность допустимых символов строки не начинается со спе-
циального символа или цифры и не заканчивается двоеточием - это команда про-
цессора:
// Остановить процессор.'
в

Когда последовательность допустимых символов начинается с символа % -


это название регистра процессора:
// Поместить в стек содержимое регистра ЕАХ.
рузВ1 %еах

Если последовательность начинается с символа $ — это непосредственный опе-


ранд:

// Поместить в стек. 0, ` число 10:и адрес переменной маг1аб1е.


ризВ1 $0
ризй1 $0х10
ризв1 $уаг1а1е
В том случае, когда последовательность символов начинается с точки, — это
директива ассемблера:
Синтаксис АТ&Т | —=н
.а1190п 2
Если последовательность символов, с которой начинается строка, заканчива-
ется двоеточием — это метка (внутренняя переменная ассемблера, значение кото-
рой соответствует адресу в указанной точке):
‚етегпа1_1оор: )тр етегпа1 _]оор
уаг1аб]е: „уе 7

Метки, состоящие из одной цифры от 0: до 9:, используются как локальные —


обращение к метке 1{ соответствует обращению к ближайшей из меток 1: вперед
по тексту программы; обращение к метке 4Ь соответствует обращению к ближай-
шей из меток 4: назад по тексту программы.
Одни и те же метки могут использоваться без ограничений и в качестве цели
для команды перехода, и в качестве переменных.
Специальная метка . (точка) всегда равна текущему адресу (аналогично $ вас-
семблерах для РО$/\ шо).
Если число начинается с * - это абсолютный адрес (для команд тр и сай),
в противном случае — относительный.
Если метка начинается с символа * -— выполняется косвенный переход.
11.1.2. Запись команд
Названия команд, не принимающих операнды, совпадают с названиями, при-
нятыми в синтаксисе [е!;:
пор
К названиям команд, которые имеют операнды, добавляются суффиксы, отра-
жающие размер операндов:
ОБЬ - байт;
О\- слово;
О] - двойное слово;
09- учетвере ное слово;
Оз - 32-битное число с плавающей запятой;
О] - 64-битное число с плавающей запятой;
0+ - 80-битное число с плавающей запятой.
// том Буе
руг уагла Ле, 0
моУб $0, уаг1аб]е
// 1119 дмог@ руг уаглае
#1194 уаг1аБ]е

Команды, принимающие операнды разных размеров, требуют указания двух


суффиксов, сначала суффикса источника, а затем приемника:
// тюузх едх, а1
поу$6] — Фа1, Жедх

Команды преобразования типов имеют в АТ&Т названия из четырех букв - С.


размер источника, Т и размер приемника:
Ассемблер в среде ИМХ

119

Но многие ассемблеры понимают и принятые в [пе] формы для этих четырех


команд. |
Дальние команды передачи управления (тр, са! ге) отличаются от ближних
префиксом 1:
// са] РГаг 0007:00000000
]са11 $7,$0
// гетт 10
| 1гет $10
Если команда имеет несколько операндов, операнд-источник всегда записыва-
ется первым, а приемник - последним, тоесть в точностигинаоборот по сравнению
с Пие|--синтаксисом:
// том ах, 6х
ПОМ фбх, Фах
// НиТ вах, есх, 16
11411 $16, %есх, Феах

У всех префиксов перед командой, для ‘которой данный префикс предназна-


чен, есть имена, как у обычных команд. Имена префиксов замены сегмента — $е9сз,
5е84$з, ер3$, зерф, зер9з: имена префиксов изменения разрядности адреса и операн-
да — а44г16 и 4айа16:
5е97$
Мом уаг1а]е, %еах
гер
$1054

Кроме Того, префикс замены сегмента будет включен автоматически, если ис-
пользуется оператор : в контексте операнда:

пу] %15: уаг1а


Те, Жеах

11.1.3. Адресация
Регистровый операнд всегда начинается с символа %:

// хог едх, еах


хог] феах, %еах

Непосредственный операнд всегда начинается с символа $:


Операторы ассемблера ТОМИ ОИЕНИЙ
^/ тому едх, оТЕзет уаг1аб1е
о\1 $Уаг1а
Ле, Фейх
Косвенная адресация использует немодифицированное имя переменной:

// ризй дмог@ ртг маг1аб1е


ризИ1 уаг1аб]е

способы адресации удобнее рассматривать как варианты мак-


Более сложные
симально сложного способа — по базе и индексированием, и сдвигом:

// том еах, Базе_аааг[ебх+е41*4] (наиболее общий случай)


Ом]. Базе_ад9г(%ебх ,
%е91 ,4), Жеах
// Леа вах, [еах+еах*4]
1еа1 %еах, 4),
(%еах ‚Хеах
// том ах, мог рфг [6р-2]
момм -2(%е5р),%ах
// том еах, 9мог4 рег [е91*2]
поУ1 (,%е01,2), Жедх

11.2. Операторы ассемблера


Ассемблеры для МХ, как и для 2О$, могут вычислять значения выражений
в момент компиляции, например:
// Поместить в ЕАХ число 320*200.
мо\у1 $320*$200, %еах

В этих выражениях встречаются следующие операторы.

11.2.1. Префиксные, или унарные, операторы


— (минус) — отрицательное число
- (тильда) — «логическое НЕ»

11.2.2. Инфиксные, или бинарные, операторы


Высшего приоритета:
- * — умножение;
/ - целочисленное деление;
% — остаток;
< или << - сдвиг влево;
> или >> - сдвиг вправо.
Среднего приоритета:
|- побитовое «ИЛИ»;
& - побитовое «И»;
^ — побитовое «исключающее ИЛИ»; |
| - побитовое «ИЛИ-НЕ» (логическая импликация).
Низшего приоритета:
+ — сложение;
— — вычитание.
534 |1 Ассемблер в среде УМХ
11.3. Директивы ассемблера
Все директивы ассемблера В ОМХ всегда начинаются с символа . (точка). Из-
за большого количества операционных систем и ассемблеров для них возникли
многочисленные часто встречающиеся директивы. Рассмотрим наиболее полезные.

1.31. Директивы определения данных


Эти директивы эквивалентны директивам ЧБ, 4\,, 44, ЧЁ и т. п., применяющимся
в ассемблерах для ОЗ/\МИт4о\. Основное отличие здесь состоит в том, чтобы
дать имя переменной, значение которой определяется такой директивой; в ассем-
блерах для (МХ обязательно надо ставить полноценную метку, заканчиваю-
щуюся двоеточием,
Байты:
„Буте выражение...

Слова:
„мЮГа выражение... или .Пмога выражение... или. ЗПОгт выражение...

Двойные слова:
.1п{ выражение... или .10п9 выражение...

Учетверенные слова (8-байтные переменные):


. дцаа выражение. ..

16-байтные переменные (окта-слова):


.осТа выражение. ..

32-битные числа с плавающей запятой:


.Е]оаф число... или .$1191е число..

64-битные числа с плавающей запятой:


.9ои6]е число...

80-битные числа с плавающей запятой:


„дЕюат число...

Строки байтов:
.а$с11 строка...

Строки байтов с автоматически добавляемым нулевым символом в конце:


`.а8с12 строка... или .3Тг1п9 строка

Блоки повторяющихся данных:


.$К1р размер, значение или .зрасе размер, значение // Заполняет области
// памяти указанного
// размера байтами
// с заданным значением.
Директивы ассемблера |ИОЗИИИИЕНЕНЕЯ
.111] повтор, размер, значение // Заполняет область памяти значениями
// ‘заданного размера (0-8 байт) указанное
// число раз. По умолчанию. размер
// принимается равным 1, а значение - 0.

Неинициализированные переменные:
„1сопм символ, длина, выравнивание // Зарезервировать указанное число байтов
// для локального символа в секции .0$$.

11.3.2. Директивы управления символами


Присвоение значений символам:
‚еци символ, выражение //`Присваивает символу значение выражения.

.едиу1у символ, выражение // То же, что и .еди, но выдает сообщение


// об ошибке, если символ определен.

‚ .зет символ, выражение // То же, что и .еди, но можно повторять


// несколько раз. Обычно, впрочем, удобнее
// написать просто «символ = выражение».

Управление внешними символами:

.91061 символ или .9106а1 символ // Делает символ видимым для компоновщика,
// а значит, и для других модулей
// программы.

‚ехтегп символ // Директива „ехфегп обычно игнорируется -


//все неопределенные символы считаются
// внешними.

‚сот символ, длина, выравнивание // Директива эквивалентна .1сотт, но, если


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

Описание отладочных символов:

„де символ // блок описания отладочного символа.


. епдеР `

Мы не коснемся описания отладочных символов, так как их форматы сильно


различаются между разнообразными операционными системами и разными фор-
матами объектных файлов.
11.3.3. Директивы определения секций
Текст программы делится на секции - кода, данных, неинициализированных
данных, отладочных символов и Т. д. Секции также могут делиться на подсекции,
располагающиеся непосредственно друг за другом, но это редко используется.

„дата подсекция

Следующие команды будут ассемблироваться в секцию данных. Если подсек-


ция не указана, данные ассемблируются в нулевую подсекцию.
`
1535] : | | |1 Ассемблер в среде УМХ
.Техе подсекция

Следующие команды будут ассемблироваться в секцию кода.

‚зесф1оп имя, флаги, @тип или .зест1оп “имя”, флаги

Общее определение новой секции:


О флаги (для ЕЁЕ):
— м или #уиЩе — разрешена запись;
— х или #ехестяг — разрешено исполнение;
— аили #а[ос — разрешено динамическое выделение памяти (65$);
О тип (для ЕЁР):
— @рговЬиз — содержит данные;
— @поБиз -— не содержит данных (только занимает место).

11.3.4.. Директивы управления разрядностью


. соде16

Следующие команды будут ассемблироваться как 16-битные.


.с04е32

Отменяет действие .со4е16.

11.3.5. Директивы управления программным указателем


.а119п выражение, выражение, выражение

Выполняет выравнивание программного указателя до границы, отмеченной


первым операндом. Второе выражение указывает, какими байтами заполнять про-
пускаемый участок (по умолчанию - ноль для секций данных и 90 для секций
кода). Третье выражение задает максимальное число байтов, которые может про-
пустить эта директива.
В отдельных системах первое выражение - не число, кратным которому дол-
жен стать указатель, а число битов в указателе, которые должны стать нулевыми.
.огд новое значение, заполнение

Увеличивает программный указатель до нового значения в пределах текущей


секции. Пропускаемые байты заполняются указанными значениями (по умолча-
нию - нулями).

11.3.6. Директивы управления листингом


Запретить листинг:
.п01151

Разрешить листинг:
. 1181

Конец страницы:
.е]есе
Директивы ассемблера | БЕЙ
Размер странины (60 строк, 200 столбцов по умолчанию):
„рз17е строки, столбцы

Заголовок листинга
.{1е текст

Подзаголовок:
‚55111 текст

11.3.7. Директивы управления ассемблированием


Включить текст другого файла в программу:
„1ис1и4е файл

Ассемблировать блок, если выполняется условие или определен либо не опре-

делен символ:

.1Г выражение
.1Рает символ
„1ЕидеЁ символ или .1РпофдеР символ
.е1зе
‚ еп

Выдать сообщение об ошибке:


.егг

Немедленно прекратить ассемблирование:


.‚абогте

11.3.8. Блоки повторения


Повторить блок программы указанное число раз:
‚герф число повторов
‚ епдг

Повторить блок программы для всех указанных значений символа:

.1гр симол, значение...


‚ епдг

Повторить блок программы столько раз, сколько байтов в строке, устанавли-


вая символ равным каждому байту по очереди:
.1грс символ, строка
‚.епаг

Внутри блока повторения на символ можно ссылаться, начиная его с обратной


косой черты (то есть как \символ). Например, такой блок
.1гр рагам, 1,2, 3
МОУ] %$1(0),%$1(\рагам)
‚.епаг
| |||]
538 10 Ассемблер в среде УМХ
как и такой
.1грс рагам, 123
мо\1 %$1(0), #51 (\рагат)
. епдг
ассемблируется в:
мо\1 %51(0),%$1(1)
м0\1 %$1(0),%$1(2)
пом] %$1(0),%31(3)

11.3.9. Макроопределения
Начало макроопределения:
‚.масго имя, аргументы

Конец макроопределения:
. епдт

Преждевременный выход из макроопределения:


‚ ех1 {т

Внутри макроопределения обращение к параметру выполняется аналогично


блокам повторения, начиная его с обратной косой черты.
Хотя стандартные директивы и включают в себя такив вещи, как блоки повто-
рений и макроопределения, их реализация достаточно упрощена, и при програм-
мировании для ОМХ на ассемблере часто применяют дополнительные препроцес-
соры. Долгое время было принято использовать С-препроцессор или М4, и многие
ассемблеры даже могут вызывать их автоматически, но в рамках проекта СМО
был создан специальный препроцессор для ассемблера - вазр. Он включает раз-
личные расширения вариантов условного ассемблирования, построения циклов,
макроопределений, листингов, директив определения данных ит. д. Мы не будем
заниматься реализацией таких сложных программ, которым может потребовать-
ся дазр, даже не воспользуемся и половиной перечисленных директив, но о суще-
ствовании этого препроцессора следует помнить.

11.4. Программирование с использованием Пс


Все программы для (МХ, написанные на С, постоянно обращаются к различ-
ным функциям, находящимся в 1Ьс.50 или других стандартных или нестандарт-
ных библиотеках. Программы и процедуры на ассемблере, естественно, могут де-
лать то же самое. Вызов библиотечной функции выполняется обычной командой
са|, а передача параметров осуществляется в соответствии с С-конвенцией: пара-
метры помещают в стек справа налево и очищают стек после вызова функции.
Единственная сложность здесь состоит в том, что к началу имени вызываемой
функции в некоторых системах, например ЕгееВ$О, приписывается символ под-
черкивания, в то время как в других (Глпих и Зо1аг15) имя не изменяется. Если
имена в системе модифицируются, то имена процедур, написанных на ассембле-
ре. включая ша!л(), также должны быть изменены заранее.
Программирование с Ис |ООО
Посмотрим на примере программы, выводящей традиционное сообщение
ЦКеНо ухо, как это делается.
// Не11ое1Р.3 .
// Минимальная программа, выводящая сообщение “Не110 мог19”.
// Для компиляции в формат ЕЁЕ.
// |
// Компиляция:
// аз -о Ве110е1{Р.о пе110е1Т.$
// Компоновка:
// (пути к файлу сг1.о могут отличаться на других. ‘системах)
// $0]аг1$ с ЗипРго С
// 19 -з -о пе110е11.501 ве110е1Р.о /ор*/ЗУМИрго/$С4. 2/1 1ЬИсгЕ 1.0 -16
// $01аг18 с 6№ С
// 19 -5 -0 №е110е11.9з0 не11ое1.0
// /оре/дпи/11Ь/дсс-115/1586-си661-301аг152.5.1/2.7.2.3.1.1/сгЕ1. 0 -]с
// ЕТпих
// 14 -3 -м е11 1386 -о пеПое!.1пх Иизг/11ЬИсгЕТ. 0 Иизг/ЗАЬИсгт1.0
// 1 /изг/116/дсс-116/1586-сибб1-11пих116с1/2.7.2 пе110е1Р.0 -1с -19сс
// /чзг/ АИС. о
// или 9сс -о пе110е1{.]пх пе11ое1Р.0
‚ Техт
// Код, находящийся в файлах сгт*.о, передаст’ управление на процедуру ма1п
// после настройки всех параметров.
. 9106] мат
па] п:
// Поместить параметр (адрес строки теззаде) в. стек.
ризВ1 $теззаде
// Вызвать функцию рутз (теззаде).
са11 рут$
// Очистить стек от параметров.
рор1 %ебх
// Завершить программу.
гет

. дата
теззаде: , О | в >
сэтг1п9 “Не\1о” мог19\0"" В 7 а

В случае с ЕгееВЗР придется внести всего два изменения— добавить символ


подчеркивания в начало имен функций ри и таш и заменить директиву зи1п8
на ‚азси, так как версия ассемблера, обычно ‘распространяемого с Ргее ВЗР, зеп8
не понимает.
// пе110сот. 5
// Минимальная программа, выводящая сообщение “Не? 10 мог".
// Для компиляции в вариант формата СОЕЕ, ‚используемый во ЕгееВЗО 2.2.

// Компиляция для 'ЕгееВ$0:


// аз -о ве110осоР.©о Пе11осоЁ.$
// 19 -3 -0 Не110сот.6$9 /изг/АЬ/сгЕ0. о ве]1обог. о -1с
5401 |||] Ассемблер в среде ИМХ
‚ техе
.9106]1 _ма1п
_ма1т:
рузй1 фтеззаде
са11 рут
рор1 фебх
гет
. дата
теззаде:
‚азс11 “Не110 мог19\0”

Пользуясь этой техникой, можно создавать программы точно так же, как и на С-
но выигрыш за счет того, что на ассемблере допускается соптимизировать програм-
му на несколько процентов лучше, чем это сделает компилятор с С (при максималь
ной оптимизации), окажется небольшим по сравнению с потерей переносимости.
Кроме того, при написании любой сколько-нибудь значительной программы це-
ликом на ассемблере мы столкнемся с тем, что, как и в случае с * 1132, нам при-
дется создавать собственные включаемые файлы с определениями констант
и структур, взятых из включаемых файлов для С. А поскольку эти ассемблеры не
умеют работать со структурами данных, необходимо описывать их средствами нс-
пользуемого препроцессора - срр или 14.
Лучшее применение ассемблера для МХ (кроме собственно разработки ядра
системы) все-таки остается за незначительными процедурами, требующими боль-
шой вычислительной мощности, — кодированием, архивированием, преобразова-
ниями типа Фурье, которые не очень сложны и при необходимости могут быть
легко переписаны заново на ассемблере для другого процессора или на С.

11.5. Программирование без использования 16с


Может оказаться, что программа вынуждена многократно вызывать те или
иные стандартные функции из НЬс в критическом участке, тормозящем выполне-
ние всей программы. В этом случае стоит обратить внимание на то, что многие
функции НЬс на самом деле всего лишь более удобный для языка С интерфейс
к системным вызовам, предоставляемым самим ядром операционной системы.
Такие операции, как ввод/вывод, вся работа с файловой системой, с процессами,
с ТСР/ТР ит. п., могут выполняться путем передачи управления ядру операцион-
ной системы напрямую.
Чтобы осуществить системный вызов, надо передать его номер и параметры
на точку входа ядра аналогично функции НЬс зузсаП(2). Номера системных вызо-
вов (находятся в файле /изг/лисе/зуз/зузсаЙ.В) и способ обращения к точке
входа (дальний са|| по адресу 0007:00000000) стандартизированы 5у5\/386 АВЕ
но, например в лпих, используется другой механизм — прерывание 80Ъ, следова-
тельно, получается, что обращение к ядру ОС напрямую делает программу при-
вязанной к конкретной системе. Часть указанных ограничений можно убрать,
используя соответствующие #4ейпе, но в общем случае выигрыш в скорости
Программирование без с ЗИ
сти, чем само применение ассезе-
оборачивается еще большей потерей переносимо
блера в МХ.
вы в представленных примерах
Посмотрим, как реализуются системные вызо
// ве1101пх.3 1155
“Не?1о мог19” на 1лих без использования
// Программа, выводящая сообщение
//
// Компиляция:
// аз -0 пе1101пх.0 не110]пх. $
// 14 -$ -0 пео]пх Ве110]пх.о
//
.Техт
.91061 _этаге
_этаге: =
параметры‘ в |1пох помещают слева направо,
// Системный вызов #4 “игле”,
%еах, %е5х, чесх, %едх, %$1, %е91.
// в регистры
ом] $4, %еах
хог1 Фебх, %ебх
1161 фебх
// Жеьх = 1 (идентификатор 9190и1)
О\1 $теззаде, %есх ..
0о\1 фтеззаде_1,%еах .
с номером 801.
// Передача управления в ядро системы - прерывание
17% $0х80

вызов. #1 “ех1” (\еах = 1, %ебх = 0).


// Системный
хог] феах, Феах
1051 Феах
хог] фебх, %ебх
171 $0х80 _
ВИ |
‚дата
пеззаде:
„зтг1пб “Не]1о мюг19\012”
= .-меззаде- Ё
меззаде_1
к системным вызовам. В 60-
1рих является уникальным случаем по отношению
и боапв — системные вызовы реали-
_ лее традиционных ОМ Х-системах — Етеё ВЗР
различие в программах заключает-
зованы согласно общему стандарту 5у3\ /386, и рживает некоторые
ый с Егее ВЗР, не подде
ся лить в том, что ассемблер, поставляем
команды и директивы.

и, :
// Не1106$4.3 110.
“Не110 мог19” на, ЕгееВ$0 без использования
// Программа, выводящая сообщение
//
// Компиляция:
// аз -0 е1106$4.0 ле110539.$
// 19 -8 -о пе110639 ве110634.0
// —.
542 111 Ассемблер в среде ИМХ
‚Техе
.91051 _$Тат
_зтагт:
// Системная функция 4 “мгМе”.
// В ЕгееВЗО номер вызова помещают в %еах, а параметры - в стек
// справа налево плюс одно двойное слово.
ризв1 $теззаде_1
// Параметр 4 - длина буфера.
ризй1 $тез5аде
// Параметр 3 - адрес буфера.
ризй1 $1
// Параметр 2 - идентификатор устройства.
мом1 $4, Хеах
// Параметр 1 - номер функции в еах.
ру$И1 Феах
// В стек надо двойное слово, но мы поместим номер вызова.
поместить любое
// для совместимости с 30}аг1з и другими строгими операционными системами.
// 1са11 $7,$0 - ассемблер для ЕгееВ50 не поддерживает эту команду. .
„Буте 0х9а
. 1019 0
.могГа 7
// Восстановить стек.
а391 $16, %езр

// Системный вызов 1 “ех1т”


хог1 феах, Хеах
ризй1 %еах
1пс]1 Феах ’
ри$в1 феах
// 1са11 $7,$0
.Буте Ох9А ,
. 1019 о. „в
МОГ 7 7
и}
‚ дата
теззаде:
‚23611 “Не]10 мог19\012”
меззаде_] = .-меззаде

И теперь то же самое в 50]а115:, -


// Пе110$01.3
// Программа, выводящая сообщение “Не110 мог149” на $0]аг1$/х86 без использования 116с.
и
// Компиляция:
// аз -о 1е110301.0 №е110301.5
// 19 -3 -о №е110301 Не110$01.0
//
. Техе
.91051 _зТаг
Переносимая программа для ИМХ ПИН
_зТагт:
// Комментарии - см. №е1100$4.3.
. ризй1 $теззаде_1
ризН1 $теззаде
по\1 $4, Жеах
ризВ1 %еах
]са11 $7,$0 “
а491 $16, %езр

хог] феах, %еах


ризй1 феах
1161 феах
ризв] Феах
]са11 $7,$0
в
. Чата
теззаде:
.51г119 “Не110 мог19\012”
меззаде_1 = .-теззаде

Конечно, создавая данные программы, мы нарушили спецификацию 5у5\/386


АВГ несколько раз, но лишь потому, что не обращались ни к каким разделяемым
е
библиотекам, это прошло незамеченным. Требования к полноценной программ
и все они выполне ны
сильно отличаются в различных операционных системах,
-
с максимально возможной тщательностью в файлах сг{*.о, которые мы подключа
ли в примере с использованием библиотечных функций. Поэтому, если вы не зада-
етесь целью сделать программу абсолютно минимального размера, гораздо удобнее
ке.
назвать вашу процедуру таш (или _та1п), добавляя сг(*.0 и -[с при компонов

11.6. Переносимая программа для имхХ


Как вы могли заметить, отличия между программами на ассемблере для раз-
ных ОМХ-систем сводятся к разнообразным способам вызова системных функ-
ций. Кроме того, следует заметить, что номера этих функций могут тоже отличать-
ся. Рассмотрим на примере простой программы — аналога системной команды
р\, как эти различия можно учесть.
к.
Мы начнем создавать программу р\'А без использования системных библиоте
на одной
В таком виде она может быть полезна как, например, часть мини-ОМХ
дискете. Как мы позднее убедимся, размер нашей версии р\4 станет меньше такой
С до-
же программы на С (в 50-100 раз) без учета того, что любой программе на
полнительно нужна библиотека |1с.50, занимаю щая сотни килобайт .
Команда р\/4Ч должна всего лишь вывести на стандартный вывод полное имя
текущего каталога. Для этого можно воспользоваться различными алгоритмами:
1. Системный вызов вес\4(), который присутствует в Мпих 2.2 (номер 183)
и ЕгееВ$О 3.0 (номер 326). Этой функции передается адрес буфера и его раз-
мер, а она записывает в буфер полное имя текущего каталога. Данный способ —
самый эффективный, и мы в первую очередь будем использовать именно его.
| |111
544 Ассемблер в среде ИМХ
2. Специальный файл /ргос/зеН/с\м4 в Глпих 2.2 является символической
ссылкой на текущий каталог того процесса, который проверяет ее.
3. Некоторые интерпретаторы передают запускаемым программам значение те
‚кущего каталога в переменной среды РУ’. Такой способ - самый ненадежный.
потому что под другим Ве! нашу программу нельзя будет запустить.
4. Классический алгоритм, в котором праграмма поэтапно исследует содержи-
мое вышележащего каталога (../, затем ../../ и т. д.) и находит запись, совпа-
дающую с предыдущим рассмотренным каталогом (./, ../, и т. д.). Такой ал-
горитм мы будем использовать, если в системе не поддерживаются ни
системный вызов ес\4(), ни специальный файл /ргос/зе{/с\4.
Поскольку имена большинства системных вызовов разнятся, разместим их в от-
дельном файле сопй2., который будет включен в программу директивой лас1аде:
// Способ обращения к системному вызову (установить
// ЗУЗСАЬ_11пих в 1, если используется 1п* $0х80, и
// ЗУЗСАЕЕ ип1х = 1, если используется 1са11 $7,$0).
ЗУ$САЕ:
11 пих = 0
ЗУ$САН: ип1х = 1

// Максимальная длина пути (из 110118. В).


МАХ_РАТН = 4096

// Стратегия для рма:


// 1, если используется системный вызов детсма(),
РМО_зуз = 1
// 1, если используется файл /ргос/зе1ТР/сма,
РМО ргос = 0
// 1, если. используется обычный (переносимый) алгоритм,
РИО_роз1х = 0
// 1, если используется переменная среды РМО.
РМО ету = 0

// Номера используемых системных вызовов (из зу3/зузса11$.П):


// ех() - всегда 1.
ЗУЗСАН: ЕХТ = 1
// чгМе() - всегда 4.
ЗУ$САЦ: МАТТЕ = 4
// ореп() - всегда 5.
5У5САЦ. ОРЕМ = 5
// с10зе() - всегда 6.
ЗУЗСАЦЕ СЕОЗЕ = 6
// геад111К() - 58 на ЕгееВ$0, 85 на 11пих.
ЗУЗСАН-_ВЕАБЕТМК = 58
// геад91г() - нет на ЕгееВЗ0, 89 на Е1пих.
УУЗСАН._ВЕАООТВ = 0
// ветдепт$() - нет на ЕгееВ$0, 141 на Е1пих.
ЗУЗСАН: _СЕТОЕМТЗ = 0
// дета1гептг1ез() - 196 на Ёгее8$0, нет на Е1пих.
ЗУ$САН. СЕТОТВЕМТВТЕЗ = 196
Переносимая программа для УМХ
// зхат() - 188 на ЕгееВ$0, 106 на Шлпих.
ЗУЗСАГ-_ЭТАТ = 188
// 1эхат() - 190 на ЕгееВ$0, 107 на пих.
ЗУЗСАЕЕ [$ТАТ = 190
// Езхаф() - 189 на РгееВ$0, 108 на [Лпих.
ЗУ$САН. _РЭТАТ = 189
// детсма() - 326 на ЕгееВ$0 3.0, 183 на Е1пих 2.2
// нет на старых версиях.
ЗУУСАЕЕ_бЕТСМО = 326

// Размеры используемых структур.


// Размер згисф Ч1гепт:-
// 1024 на ЕгееВ$0, 266 на Шпих.
ЗТ2Е_ОТВЕМТ = 1024
// Смещение 91гепт.1по от начала структуры.
ОТАЕМТ_Т№0 = 0
// Смещение Ч1гепт.1еп от начала структуры:
// 4 на ЕгееВЗ0, 8 на 11пих.
ОТВЕМТ_ГЕМ = 4
// Смещение 91гепт.пате от начала структуры:
// 8 на ЕгееВЗ0, 10 на Е 1пих.
ОТВЕМТ_МАМЕ = 8

// Размер структуры зТаЁ и смещения ее элементов:


// Чем, 1то и ПИК...
УТЛЕ_ЭТАТ = 64
УТ_0Е\У = 0
Т_1№0 =4
ЗТ_МЕТМК = 10

Для всех пунктов этого файла можно написать сценарий с целью автоматичес-
кого конфигурирования, аналогичный СМО ацбосопйеиге, при использовании ко-
торого модификация вручную будет не нужна. Этот сценарий, а также другие про-
стые программы на ассемблере для ОМХ доступны в Ицегпей по адресу: Бер://
уми поп мше. оге/-саБЫ/зегоиз/азпих. ВЕТ.
Теперь, когда все возможные различия между версиями системы предусмотрены,
перейдем непосредственно к программе. Упрощая задачу, не станем обрабатывать со-
общения об ошибках, но код возврата в случае ошибки всегда будет ненулевым.
// Включение файла соп{19.1.
„пс иае “сопЁ19. 1”
// Начало программы.
.01061 _зфаге
_8Тагт:

.1Е РМО_роз1х
// Переносимая (и сложная) стратегия для. рма.

// В %ебр будет храниться указатель на первый символ части искомого пути,


// определенной к настоящему моменту.

18 Зак. 459
546 | || ||П Ассемблер в среде УМХ
// Она заполняется справа налево - от текущего каталога к ‚корневому.
тоу] $рт_Би{Рег+1024-1,%ебр
// Искомый путь инициализируется символом перевода строки.
то\1 $0хОА, (%ебр)
// В %е$1 будет храниться указатель на путь вида “../../../”,
оу] Фир_Би Рег, %е$1
// инициализированный как ".\0”.
поуи $0х002Е, ир_Би{ Рег
// Выполнить этат(“/”), чтобы определить 1поде и Чем для корневого каталога
// (по ним мы позже установим, когда он `будет достигнут).
„ТЕ ЗУЗСАНЕ
ип х
ризН1 $5Е_зтат
ризй1 $гоот_рати
том] $5У5$САЦС_5ТАТ,
Жеах
ризВ1 Феах
.буте Ох9А
.1019 -0
. мОГа 7
а991 $12, Жезр
. епо1Е
.1Е ЗУЗСАЦ
11пих
оу] $э1_зтат, Жесх
по\1 $гоот_ратн, %ебх
тпо\1 $ЗУ5САН. _5ТАТ, %еах
11 $0х80
‚ епа1Е
{е$11 феах, %еах
)п2 еггог_ех1т
// Сохранить 4еу и 1по4е корневого каталога.
оу] 5{_31а1+5Т_ОЕ\, %еах
тоу1 феах, гоо{_дем
оу] 5{_з{а1+5Т_1М№0,Жеах
по\1 феах, гоо*_1по
// Главный цикл - перемещение по каталогам,
та1п_роз1х_сус1е:
// Вызвать 13та{() для текущего каталога типа “../../../",
// чтобы определить его 1поде и Чем. .
.1Р ЗУЗСАН: _ип1х |
ризй1 $5т_зтаф
ризй1 фир_БиР Рег
оу] $ЗУ5САЬЕ
1 5$ТАТ, Жеах
ризй1 феах
.„Бухе Ох9А
. 1919 0
.МОГа 7
2491 $12, Жезр
. еп91Е
Переносимая программа для ИМХ ПР 1547
‚1 ЗУЗСАНЕ_11пих
по\у1 $51_з{ат, Жесх
поУ1 $ир_виГ Рег, Жебх
оу] $5У5САЕЕ_ЕЗТАТ, %еах
111 $0х80
. епдтЕ
{е311 феах, %еах
72 еггог_ех1т
// Сохранить 1поде и деу каталога, который сейчас будет сканироваться.
то\1 3{_$Та{+5Т_ВЕМ, Феах
оу] Феах, де\
101 3Е_этат+5Т_Т№,Жерх
оу] ферх, 1по
// Проверить, не совпадает ли этот каталог с корневым.
стр] феах, гоот_аеу
пе ро$1х_пот_11п13Пед
стр] Чебх, гоот_1по
]пе ро$1х_пот_11п15йед
// Если совпадает - вписать последний символ “/” на левом конце искомого пути
ес] Февр
моб $0х2Е, (Фебр)
// и вывести его на экран.
тр р9$1х_ мге
// Иначе -
ро$1х_пот_Е1п1зпед:
// добавить “..\0” к ир_БиРРег, чтобы перейти к вышележащему каталогу
ХА ФОХ2ЕРЕ, (%е$1)
1151
%е$1
1151 %е$1
тмоуб $0, (%е$1 )
// Открыть данный каталог только для чтения (0_ВООМУ).
‚1 ЗУЗСАЦ_ип1х
риу$й1 $0
рузВ1 фир_БиРег
по\1 $5У5САЕЕ_ОРЕМ,
%еах
ризН1 феах
„Буте Ох9А
.19п9 0
‚мОГа 7
2931 $12, Жезр
. епт
.1Е ЗУЗСАН: 11пих
то\1 $0, %есх
оу] Фир_БиРРГег, Жерх
поу1 $5У5САН. _ОРЕМ, еах
17 $0х80
‚ епа1 Е
|

Ассемблер в среде ЧМХ '


|
1е$11 феах, Хеах |
|
ри еггог_ех1т
то\1 феах, %е91
// Выполнить Рзта{т над этим каталогом,
„ЗЕ ЗУЗСАЦЕ ип х
ризН1 $31 зтаф
ри$й1 Чеах
по\1 $5У5САН. Е$ЗТАТ, Феах
ру$и1 Феах
‚ Буте Ох9А
.10п9 0
. МОГа 7
а991 $12, Жезр
‚ епд1Р
.1Е ЗУЗСАЕЕ
11 пих
по\1 $${_зтат, %есх
1о\1 %еах, Фебх
оу] $ЗУ$САН: ЕЭТАТ, Жеах
1т $0х80
. епо1Р
Те$11 %еах, Феах
12 еггог_ех1т
// Если все в`порядке, добавить “/” для следующего каталога.
то\б $0х2Е, (%е51)
1161 $е$1
// Вложенный цикл: рассмотреть каждую запись в вышележащем
// каталоге и сравнить ее 1поде и деу с текущей.
хог] ферх, %ебх
геада1.г_сус]1е:
// Вызов геа941г() легче использовать, чем дет4епт$().
.1Т ЗУЗСАЦ-_ВЕАБОТЯ
.1Р ЗУЗСАЦЕ ип1х
рии] $1
ризВ1 $91 гепс
`ризй1 %$е01
по\1 $5У$САЦ. _ВЕАООТВ, Жеах
ри$й1 Феах
.Бусе Ох9А
. 1019 0
‚.моГа 7
а39] $16, %езр
.епо 1
.1Е ЗУЗСАЦЕ
11 пих
то\]1 $1, Жедх
то\1 $а1гепх, Фесх
том] фе91
‚ Хебх
10\1 $5У$САЦ- _ВЕАООТВ, %еах
1п $0х80
. епа1 Е
Переносимая программа для УМХ | 5-8
/ В $е5х будет структура 91геп{, над которой мы работаем в настоящий момент.
по\1 $91гепт, %ебх
4ес1 %еах
- пе потРоипа
е1зе

нет геа491г(), но есть детаепт$ и де+91гепег1ез, алгоритм усложняется, так


// Если
возвращают не одну структуру 91геп{, а столько, сколько поместится в буфер.
// как они
1е$11 ферх, %еБх
32 11те_То_детдепе
хог1 феах, %еах
ФА ОТВЕМТ_СЕМ(%еБх)
, %ах
а991 чеах, Хех
// Проверить, выйдет ли %ебх за пределы буфера после добавления 1ЕМ.
хог1 феах, %еах
моУм ОТВЕМТ_1Е№(%ебх)
‚Хах
| стр] %еах
Ч1гепт_1111е9,
39е 11 те_1о_де{Чепт
Те ОТВЕМТ_1ЕМ(%ебх)
,%ах
1е511 феах, Феах
912 $К1р_детдепт
{1те_То_дефдепт:
// Если выходит - пора делать дефдеп{$() или 9е191гептг1ез() -
// в зависимости от операционной системы.
‚1 ЗУ5САН._ип1х
.1Р ЗУЗСАЦ:_бЕТОЕМТ$
ризй1 $517Е_ОТВЕМТ
ризй1 $А1геп*
ризН1 %е01
пу] $ЗУ$САЦЕ_бЕТОЕМТ$,
%еах
ризП1 Феах
.Буте Ох9А
. 10п9 0
‚мОГа 7
а991 $16, %езр
‚ 21 зе
ризН1 $Базер
ризв1 $$Т17Е_ОТВЕМТ
ризН] $а1гепт
ри$й1 %е91
оу] $5\$САЦ. _СЕТОТВЕМТАТЕ$, еах
ризй1 Феах
‚Буте 0х9А
. 1019 0
.мОГа 7
299] $20, %езр
‚ еп9 те
‚епд1Р
5501 |1 ||| Ассемблер в среде ИМХ
.1Г ЗУЗСАН._11пих
то] $$Т2Е_ОТВЕМТ, %едх
то] $Ч1гепт, %есх
м0\1 %е91, Хебх
то\1 $5У5САЬ-_СЕТБЕМТ$, %еах .
111 $0х80 |
. @п91Г
|
тоУ1 Феах, 41гепт_Е111е9 |
Те$11 Феах, Жеах
де потРоипд
по\] $Ч1гепт, Жебх
эК1р_детдепе:
‚ @п91Е

// Скопировать в сканируемом каталоге имя полученной записи


// в конец строки ../../../../, не смещая указатель в %е$1.
хог] Фесх, %есх
ри$Н1 %е$1
ризН1 %е41
то\1 %$е$1
, %ед1
по\у] Ферх, %е31
а991 ФОТВЕМТ МАМЕ, %е$1
МОУм ОТВЕМТ_ЕЕМ(%ебх), %сх
11с1 Фесх
гер
МОУ$Ь
рор1 %е91
рор1 %е$1
// Выполнить 131а{() для этой записи, чтобы получить ее 1поде и 9е\.
ризН1 Фебх
.1Е ЗУЗСАН-_ип1х
ризН1 $зт_эТат
ри$И1 фир_Би Рег
тоу] =®$ЗУЗСАЦ _19ТАТ, %еах
ри$81 феах
. Буте Ох9А
. 1019 0
‚ МОГа 7
а991 $12, Жезр
‚ епа1+
„Г ЗУЗСАН: _11пих .
то\] $$1_зТат, Жесх
Мо\1 фир_БиЕРег, Жебх
оУ1 $ЗУ$САН. ЕЗТАТ, %еах
17 $0х80
. епа1т
рор1 Ферх
1е$11 Феах, %еах
9п7 геа941г_сус1е
Переносимая программа для МХ || |551
// Если они не совпадают с сохраненными 1по4е и дем для
// текущего сканируемого каталога - продолжить.
1О\1 ем, %еах ,
стр1 Феах, э1_зТат+5Т_ВЕ\
пе геа991г_сус1е
по\1 1по, Хеах
стр1 Чеах, з1_з{та1+5Т_Т№0
пе геад91г_сус1е
// Вернуть ир_БиЁРег в состояние ../../../../../, соответствующее вышележащему каталогу.
поу] $0, (%е$1 )

// Добавить “/” в создаваемый путь ри (кроме случая, если это был самый первый каталог)
стрь $1, Р1гзе
]е пот 11751
дес] Фебр
тоуб $0Ох2Е, (%ебр)
пот _Е1гэт:
тоуЬ $0, Е1гз+
// Сдвинуть указатель в %ебр на пат1]еп байтов влево.
хог] Фчедх, %едх
.1Е ЗУЗСАЦ: _ВЕАБОТВ
поУм ОТВЕМТ_ГЕМ(%ебх),%9х
‚ е]зе
ризН1 %е$1
хог1 фесх, #есх
е ФеБх, %ез1
а991 $ОТВЕМТ_МАМЕ, %е$1
зееК_тего: .
1151 фесх
момь (%е31 , %есх, 1), ®а1
тезть фа1 ,%а1
12 зееК_2его
ед Фесх, Фейх
рор1 %е51
. епд1ТР
8461 Федх, Жебр
// Скопировать имя найденного каталога в рма, не сдвигая указатель.
хог1 Фесх, Фесх
ри$й1 %е51
ру$В1 фед1
то\1 фебр, %е41
101 феБх, %е$1
а94] ФОТВЕМТ_ МАМЕ, %е$1
.1Е ЗУ5САН: _ВЕАБОТН
оУм ОТВЕМТ_ГЕМ(%еБх)
,%сх
‚ е]зе
по\1 феах, %есх
„епа1Р
| гер
552 РТВ Ассемблер в среде МХ
ПОУ$Ь
рор1 %е61
рор1 %е31
// Закрыть открытый каталог
.1Р ЗУЗСАЦЕип х
ри$Н1 %е01
то\1 $ЗУЗСАН: _С109Е, Жеах
ри$й1 чеах
.буте Ох9А
. 10пд 0
‚ МОГа 7
а99] $8, Жезр
‚ епа1Е
‚1Е ЗУ5САНЕ_11пих
оу] феа1 , Фебх
оу] $ЗУЗСАЕЕ_С10$Е, Жеах
11 $0х80
‚ епа1Р
// Продолжить главный цикл, пока не будет достигнут корневой каталог.
пр ма1п_роз1х_сус1е
поРоипа:
тр еггог_ех1*
ро$1х_мг1Те:
// Вывести на экран найденный путь.
по\у1 $рт_Би{РРег+1024,
%едх
$461 Фебр, %едх
по\1 Фебр, Фесх
хог] фебх, Жерх
111 Фебх
.1Е ЗУЗСАЦ уп1х
ризН1 %едх
ри$П1 фесх
ри$зй1 Фебх
ПО\У1 $ЗУ$САЕС_ИНТТЕ,
%еах
ризй1 чеах
„Бусе Ох9А
. 1019 0
‚ МОГа 7
а991 $16, Жезр
. епа1Е
.1Е ЗУЗСАНЕ_11пих
МОУ] $ЗУЗСАЕЕ_ИВТТЕ,
%еах
Ти $0х80
‚ епатЕ
‚ еп1Р
// Конец стратегии РИО_розах.

// Просто распечатать значение переменной среды РМО (плохая стратегия).


.1Р РМО. епу
с19
Переносимая программа для УМХ | 1553)
ТЕТ
рор1 фебх
то\1 4(%езр,
%еБх, 4), %е91
// Теперь адрес списка переменных в %е91.
хог] феах, Хеах
// Сканирование переменных в поисках той, начало которой совпадет с епу_папме.
епми_зсап_сус1е: |
стр. $0, (%е91 )
92 еггог_ех1т
тоу] © Фепу_пате, %ез1
то\1 фепу_пате_1,Фесх
гере
стрзо
1х2 Роупа_маг1аб1е
хог] фесх, %есх
дес] фесх
герпе
эсаз6
тр епу_зсап_сус1е

// Теперь %е91 - адрес значения переменной Риб. заканчивающийся нулем.


Роипд_уаг1а]е:
хог]. федх, %едх
ес] Ф%едх
// Найти его длину
1оор_7его_зсап:
1пс1 федх
стро $0, (%ед1‚ Жеах, 1)
те 1оор_7его_зсап
ПоУБ $ОхОА, (%е91 ,%еах, 1)
1151 федх
// и вывести на экран.
„1 ЭУЗСАЕЕ ип1х
ризп1 Федх
руз81 %е91
ризй1 $1
о] $ЗУ$САЕЕ_МВТТЕ,
Феах
рузН1 феах
‚ Буте Ох9А
. 10п9 0
‚МОГЧ 7
аа91 $16, Жезр
‚ еп
.1е ЗУЗСАЦЕ_11пих
то\1 %ед1 ,%есх
то\1 $1, Жебх
101 $ЗУЭСАНЕ: _ИВТТЕ, Феах
111 $0х80
. епд1Ё
. @па1е
554 ТТИ Ассемблер в среде ИМХ
// Стратегия ргос - выводится имя каталога, на который
// указывает символическая ссылка /ргос/зе1/сив.
‚1 РМО_ргос
// Вызвать геад11иК(“/ргос/зетЕ/сма").
по] $255, %едх
тоУ1 $11пих_БиЕ Рег, %есх
по\1 $11пих_рм9,
Жебх
том] $5У5САН-_ВЕАБЕТМК, %еах
// Эта стратегия осуществима только в [1пих.
111 $0х80
. епа1Е

// Стратегия с использованием системного вызова.


.1Р РМО_зуз
// Вызвать детсма()
„11 ЗУЗСАНЕ
ип х
ризН1 $МАХ_РАТН
ри$й1 $ 1пих_БыЕЕег
ОУ] $5У5САЦ. _бЕТСИО, %еах
рузИ1 Феах
.Буте Ох9А
. 019 0
.МОГа 7
а99] $12, чезр
. еп91Р
.1Р ЗУЗСАЕЕ
11 пих
ФУ $МАХ_РАТН, %есх
пом1 $11пих_виР Рег, ебх
101 $ЗУ5САН: _бЕТСИО, %еах
17 $0х80
.еп91Е
{е$11 Уеах, Феах
33 еггог_ех11
9ес1 феах
// В случае с ЕгееВ$0 надо дополнительно определить длину возвращенной строки
.1Р ЗУЗСАЕЕ ип х .
хог1 феах, Жеах
хог] Фесх, Жесх
ес1 %есх
ОУ] $11 пих_Би
Рег, %е91
герпе
зсаз6
$461 $11пих_БиЕ
Рег, %е41
по\1 %е41
, Хеах
11с1 феах
‚ епатЕ
‚ епа1Е

// Вывод на экран для стратегий ргос и зуз.


// Добавить символ новой строки в конце.
Переносимая программа для УМХ 55
11 РМО_ргос | РМО_зуз$
момо $ОхОА, 11пих_Би{
Тег (%еах)
1пс] %еах

// Вывести на экран 11пих_БиЕег.


.1Е ЗУЗСАН:ип Хх
ризй1 феах
ри$Н1 $11 пих_ Би Рег
ри$й1 $1
ту] $ЗУ$САЦЕ _МВТТЕ, %еах
ризй1 феах
. Буте 0х9А
. 1019 0
.мОГ@ 7
а991 $16, Жезр
‚ епа1Р
.1Е ЗУЗСАЦЕ _11пих
по\У1 феах, %едх
хог] чех, %ебх
оу] $11пих_БиЁРег,
%есх
111 %ерх
то\у1 $ЗУЗСАЕЕ_МВАТТЕ,
Феах
11 $0х80
. епт
. епо1т

// Выход из программы без ошибок ех11(0).


ех1\{:
хог] фебх, %ебх
.1Е ЗУЗСАНЕ ип1х
рузВ1 фебх
то\у1 $ЗУ5САН._ЕХТ ,Жеах
ризй1 %еах
‚ бусе Ох9А
. 1009 0
.МОГО. 7
‚ еп 1
‚1 ЗУЗСАНЕ
11 пих
101 $5У$САНЕ _ЕХТТ, %еах
111 $0х80
‚ епт Ре

// Выход из программы с ошибками.


ИЕ 7 (-РМО_ргос)
ех1{_еггпо:
ех11_ЕМОЕМТ:
еггог_ех1т:
.14 ЗУЗСАЕЕ ип1х
ру$В1 $1 -
оу] $ЗУ5САЕЕ ЕХТТ, Феах
556| | || 111 `Ассемблер в среде ИМХ
ризй1 феах
. Буте Ох9А
. 1019 0
.МОГа 7
. епа1Р
‚1 УСА 1 пих
хог] ферх, Жебх
115] Ферх
то\1 $ЗУ$САЕ._ЕХТ,
%еах
111 $0х80
‚ епа1е
. епа1

// Область данных.
. дата
.1Р РМО_ро$1х
// Текущий каталог для зтат()
риа_ратн:
.а3с11 “.\000”
// Корневой каталог для зтат().
гоот_ратв:
.а3с11 "/\000”
// Флаг, нужный для того, чтобы не ставить “/” перед первым элементом пути.
Е1гэт:
‚.буте 1
. епд1

// Имя файла в /ргос для геад11пк().


‚1 РМО_ргос
11пих_рмд:
.а3с11 “/ргос/зе1Р/сма\
000“
‚ епа1Р

// Переменная среды для стратегии РМО.


‚17 РИО_епу
еп\и_памте: .
.азс11 “РМО="
епу_пате_1 = .-епу_паме
‚еп Е |
// Указатель для системного вызова де%91гепег1ез().
.1Р ЗУЗСАЦЕ_бЕТОТВЕМТАТЕ$
разер:
‚ 1019 0
‚.епа1Е

. 63$
// Буфер для зтат()
‚1 РМ№О_роз1х
.1сотт 3{_зТат, $17Е_5ТАТ
‚ впа1т
Переносимая программа для ЧМХ "В Ал ал-4

// Буфер для результата работы детсма() и геа914пк().


‚1 РМО_ргос | РМО_$у$
„]сопт 11пих_виуЕег, МАХ_РАТН
. еп 1

„17 РМО_роз1х‘
// Буфер для вывода риа.
„]1совт ру_Би{Рег, 1024
// Буфер для сканируемого каталога (../../..И../)
.1сотт ир_биуРЕег, 1024
. епт Е

// Различные переменные.
.1Р РМО_роз1х
.]1сотм гооф_4ем,4
.]сотм 9е\,4
„]сотт гоот_1п0,4
„]сомт 110,4
.]сопм орт,4
// Буфер для записи из каталога (91геп®).
.]сотт Ч1гепт, эТ7Е_ОТНЕМТ
.1Е ЗУЗСАЦ СЕТОЕМТ$ | ЗУ$ЗСАН-_бЕТОТВЕМТАТЕ$
.]1сотт 91гепх_1111е9,4
. епт
. епатЕ

Для компиляции этой программы на любой системе достаточно двух команд:


аз -о рид.о рмд.$
19 -о рма рма.о

Полученная версия р\/’ занимает:


она [ллах 2.2 — 428 байт (системная версия - 19 332 байта);
она Слих 2.0 — 788 байт (системная версия - 18 440 байт);
она ЕгееВ$О 3.1 - 484 байта (системная версия - 51 916 байт);
она ЕгееВ$ЗО 2.2 — 8192 байта (системная версия - 45 056 байт).
Если на ЕгееВЗО 2.2 установлена поддержка запуска ЕГЕ-программ, можно
скомпилировать работающий на ней файл р\4 длиной 940 байт, но в любом слу-
чае эти размеры впечатляют. Более того, для работы нашей версии р\ не требу-
ется никакая библиотека типа 1с.50 — это полностью самостоятельная статичес-
кая программа. Такие программы, написанные целиком на ассемблере, не только
но
отличаются сверхмалыми размерами (в 20-100 раз меньше аналогов на С),
и работают быстрее, потому что обращаются напряму ю к ядру системы.
ОНИ ОИ ООО ОИ
ООО ОИ ЗИ 0 &

Заключение
Итак, прочитав эту книгу, вы познакомились с программированием на языке ас-
семблера во всей широте его проявлений- от создания простых программ и про-
цедур, вызываемых из приложений на других языках, до драйверов устройств
и операционных систем. Теперь должно быть очевидно, что ассемблер не только
не сдает свои позиции, но и не может их сдать - он неотъемлемо связан с компь-
ютером, и всюду, как только мы опускаемся с уровня абстракций языков высоко-
го уровня, рано или поздно встречаемся с ним. В то же время и абстракции,
и сложные управляющие структуры, и структуры данных реализуются на языке
ассемблера наиболее эффективно - не зря же Дональд Кнут, автор знаменитой
книги «Искусство программирования», использовал для иллюстрации перечис-
ленных структур и алгоритмов только ассемблер.
Ассемблер настолько многогранен, что нет никакой возможности описать в од-
ной книге все области программирования, в которых он может быть использован.
Методы защиты от копирования и противодействия отладчикам, строение :раз-
личных файловых систем, программирование на уровне портов ввода-вывода та-
ких устройств, как ШЕ- или $С$[-диски, и многое другое осталось в стороне,
и это‘иравильно, потому что мир ассемблера не заканчивается вместе с этой кни-
гой, а только начинается.
Я 8 ПИ О О О О О ООО

Приложение 1. Таблицы символов


1. Символы А$СН
Номера строк соответствуют первой цифре в шестнадцатеричном коде симво--
ла, номера столбцов - второй, так что, например, код большой латинской буквы
А - 41Ъ (см. рис. 18). |

02345
6738 ЭАВСЮЕЕ
ера а Г Ге [а 8 [Ги [* |
ЕЕ а кана ЕЯ

7 перер
Рис. 18. Таблица символов АЗСИ
560 | | 11111 Приложение 1
2. Управляющие символы А$СН

Таблица 23. Управляющие символы АУСИ

Назначение
Пусто (конец строки)
ЗОН ^А Начало заголовка
зТХ ^В Начало текста
^С Конец текста
Конец передачи
Подтверждение
ВЕС ^ Звонок
| в$ ^Н Шаг назад
ю||о
хочю
.|Горизонтальная табуляция
ОА ЕЕ ^ | Перевод строки
ов Гут т ^К | Вертикальная табуляция
0С РЕ | ЩЕ _| Перевод страницы
00 СВ Возврат каретки
^М | Выдвинуть

- ^о _| Сдвинуть
10 ОЕ 1 ^Р | Оставить канал данных
11 Гос /ХОМ ^а | Управление устройством-1
т

Управление устройством-2
| Управление устройством-3
Управление устройством-4
Отрицательное подтверждение
$\УМ ^\ Синхронизация
17 ЕТВ м Конец блока передачи
18 САМ | Хх | Отмена
19 ЕМ | ^у Конец носителя
Замена
“[ Езсаре
Г: —
Разделитель файлов
Разделитель групп
Разделитель записей
1Е и8 ^
т. _
Разделитель полей
Пробел
Удаление
Таблицы символов 551
3. Кодировки второй половины А$СП
Кодировка по умолчанию для первых компьютеров - этот набор символов хра-
` нится в постоянной памяти и используется ВТОЗ `(см. рис. 19)
0 2 АВС Р ЕЕ

Рис. 19. Кодировка 1ВМ ср437

Кодировка ср866 используется ОО$-приложениями как основная кодировка


и компьютерной сетью Е!Чопе как транспортная кодировка (см. рис. 20).

Рис. 20. Кодировка 1ВМ ср866


[5621 1 Приложение 1
Кодировка КО18-г используется как транспортная в [лйегпей и как основная
в большинстве бесплатно распространяемых операционных систем (см. рис. 21).

Е Е

ПЕР ТЕРТЕН РЕРЕНТа


ЗИ ПС ЕЕ СЗ
ея а ЕЕ НЫЕ
|8 тян сто
жи кл [мн о.
ища

Рис. 21. Кодировка КО!8-г(ВЕС1489)


\
Кодировка 150 8859-5 используется как основная в большинстве коммерчес-
ких ОМХ-совместимых операционных систем (см. рис. 22).

абв где жз ий к [лм но п


вре ту фич шщьыь | юя
ее ее рвы в
Рис. 22. Кодировка 150 8859-5 .
Таблицы символов ИГТ
| 1563]
Кодировка ср1251 ибпользуется как основная в графических приложениях для
Мигозо& УЛи4о\$ (вмгрис. 23). |

ВЕ РР ГЕ ТОЬЫ‹ ЫКГУр

ее авары В рэ
“Рис. 23. Кодировка ср1251
564| ТГ 11 Приложение 1

4. Коды символов расширенного А$СИ

Таблица 24. Расширенные А$С!-коды!

Гони [Клонныя кон[клаюнье Колков коТклнинья Кол


$НИ-Р11 АК-ТаБ
$1-Е12 С-Таб

АК-Епа АК-Ё 261


АН-Ноте [Г сы-вюн | 748
АК-п5$ | С#-Епд 758
АН-РаУр Си-Ноте| 77
АК-РоОп Си-РаОп | 768
АН-Ещег Си-Ро/р! 841
С-Е1 АН-Ор |98
СИ-Р2 АК-Оомп АО
СИ-ЕЗ АК-ГеН ВВ
С-Е4 АН-ВОВЕ ||9он
С1-Е5 АК-К/ АЗП
С1И-Рб АК-К* З7Н
ЗИ-Таь | С-Р7 АН-К- ДАП
27Н [15 С-В АН-К+ ЕВ
28в | бе СИ-Р9 АК-Кещег | АбН
29 | ЗузВа С#-Е10 1 | С-К/ 958
541 | Бомп С#-Е11 Си-Кк* 6
551 | 1еЯ С-Е12 Сй-К- ВЕК
561 | Ном АК-А С-К+ 908
АК-Е11 | м- 571 | Ур АН-В С-к8 вон
АК-Е12 | - `58и | Епа АН-С Си-К5 ЗЕВ
АЁ-М Н- 596 | Ноте АК-О Си-К2 918
АНК-М [эн БАЙ | РдОп АН-Е С-Ко 928
РоЧр - Си-кК.
С\-Еей
5В-Е10 АН-Е$С

'Префикс «К» соответствует клавишам на цифровой клавиатуре.


Таблицы символов ИТТ 1565
5. Скан-коды клавиатуры

Таблица 25. Скан-коды'

Ген кн он Емег
Кия ея к
т! О
И
025 |Сы Т зо м 38 |оеа 5ЗВ
2@ 03» |А ТЕК |5Р З9в | эузВа 54В
3# 048 $ ТЕРЬ Сарз$ ЗАН Масго 56н
4$ 05 |0 208 |Е1 — ЗВВ |Е11 57Н
5% ов |Е 218 |Р2 зсн |212 58В
6^ отт |6 228 |3 30н |РА1 БАН
78 ов |Н 238 |4 ЗЕВ |ЕАЗАМИИ 5ВН
8* 09 |у 245 | Е5 ЗЕН |Е14/АМИА
9( бАН |К 251 |6 - 401 | Е15/Мепи 50Н
о) овв |1 261 (Е? т мн |216 6зв
-_ осн |;: 271 |Е8 428 |217 Г 64н
-+ Г 00» |." 288 | Е9 Г 438 |218 658
В5 ОЕН |`- 291 |210 448 |219 66н
Таь О АВ [Мот 45н |220 67н
| 10 |\| 2Вн | ото! 46 | Е21 68
М 118 |2 26н |Ноте 47н [222 ии 69п
Е 125 |Х 20 |. 48 — Е23 6АВ
В 1
1 [С ЗЕн | Роцр дон - |Е24 вн
т 141 у 2ЕВ К- ДАП ЕгазеЕОЕ бов
у 155 |В зов || 4вн |Сору/мау 6ЕВ
т _| ен Е 31п | К5 4Снп | Сгзе! 72Н
| 17 |М 321 |©® 408 | Рена т
[ 18 |< 331 |К+ 4ЕВ | ЕхЗе! тв
Р Сеаг
[
] АЭН

! Префикс «К» соответствует клавишам на цифровой клавиатуре.


566 Приложение 1

Таблица 26. Служебные скан-коды

|
код _
Ошибка‘самотестирования

ев АВЕ
Ошибка клавиатуры
Приложение 2. Команды ние! 80х86 |
В этом приложении приведены скорости выполнения всех команд процессоров
Гие] от 8086 до Репёит П и машинные коды, которые им соответствуют.

1. Общая информация о кодах команд


1.1. Общий формат команды процессора пе!
Команда может содержать до шести полей:

1. Префиксы - от нуля до четырех однобайтных префиксов.


2. Код - один или два байта, определяющие команду. |
3. МоаВ/М - 1 байт (если он требуется), описывающий операнды:
биты 7-6: поле МОР - режим адресации;
биты 5-3: поле В/О - либо указывает регистр, либо является продолжени-
ем кода команды;
биты 2-0: поле К/М - либо указывает регистр, либо совместно с МОР -
режим адресации.
4. ЗТВ - 1 байт, если он требуется (расширение МоаВ/М для 32-битной адре-
сации):
биты 7-6: $ - коэффициент масштабирования:
биты 5-3: [- индексный регистр;
биты 2-0: В - регистр базы.
сл. Смещение - 0, 1, 2 или 4 байта.
.
6. Непосредственный операнд - 0, 1, 2 или 4 байта — будем использовать /1Ь
и /1\ для указания этих операндов.

1.2. Значения полей кода команды


В кодах некоторых команд мы будем встречать специальные биты и группы
битов, которые обозначим \, 5, 4, гез, зтер и сопа:
О \ = 0, если команда работает с байтами;
© \ 2 1, если команда работает со словами или двойными словами;
О $ = 0, если непосредственный операнд указан полностью;
О $ = 1, если непосредственный операнд — младший байт большего операнда
и должен рассматриваться как число со знаком:
О 9-= 0, если код источника находится в поле В/О, а приемника - в В/М;
О 4 = 1, если код источника находится в поле В/М, а приемника - в В/О.

Запись 104% будет означать, что код команды — 0001004.


568| 111 И | Приложение 2
Поле геё определяет используемый регистр и имеет длину 3 бита:
000 — АГ/АХ/ЕАХ/$Т(0)/ММо/ХММо
001 —- СГИСХ/ЕСХУ ТС/ММИ/ХММ1
010 —- РГ/ОХИЕРХ/$Т(2)/ММ2/ХММ?
011 - ВГ/УВХ/ЕВХ/$ Т(3)/ММЗ/ХММЗ
100 - АН/ЗР/Е$ РУ$Т(4)/ММА/ХММА
101 - СН/ВРИЕВР/$Т(5)/ММ5/ХММ5
110 - РН/ЗИЕЗИЗ$Т(6)/мм6/ХМмМ6
111 - ВН/ОМИЕБВИ$ТСЕ)/ММ7/ХММ?7
Запись С8г будет означать 11001тев.
Поле-зге8 определяет используемый сегментный регистр:
000 — Е5
001 - С5
010 - $$
011-05
100 — Е5
101 - 65
Поле соп4 определяет условие для команд ]сс, СМО\сс, ЗЕТсс, ЕСМО\Усс.
Его значения для разных команд:
0000 -О
0001 - МО
0010 - С/В/МАЕ
0011 —- МС/ИМВИАЕ
0100 — Е/7
0101 - МЕ/МЕ
0110 - ВЕ/МА
0111 - МВЕ/А
1000 -5$
1001 - №
1010 -Р/РЕ
‚1011 — МРИРО
1100 -— 1/МСЕ
1101 - МГ/СЕ
1110 - ЦЕ/МС
1111 - ГМЕ/С
Запись типа 4сс будет означать 0100соп4.

1.3. Значения поля МодВМ


Поле В/О (биты 5-3) содержит либо дополнительные три бита кода команды,
либо код операнда, который может быть только регистром. Будем обозначать вто-
рой случай гер, а в первом записывать используемые биты.
Поля МОР (биты 7-6) и В/М (биты 3—0) определяют операнд, который мо-
жет быть как регистром, так и переменной в памяти:
Команды те! 80х86 т 1569
о МОР = 11, если используется регистровая адресация и В/М содержит код
регистра геё
с МОЛ = 00, если используется адресация без смещения ([ВХ + $1 или
[ЕОХ] |
о МОР = 01, если используется адресация с 8-битным смещением (уаг!-
аЫе[ВХ + $1)
о МОР = 10, если используется адресация с 16- или 32-битным смещением
\
Значение поля В/М различно в 16- и 32-битных режимах.
В/М в 16-битном режиме:
000 - [ВХ + $1
001 - [ВХ +21
010 - [ВР+ ЗП
011 - [ВР+ ОП
100 - [$0
101 - [РП
110 - [ВР] (кроме МОГ = 00 - в этом случае после МоаВ/М располагается
16-битное смещение, то есть используется прямая адресация)
111 - [ВХ]
В/М в 32-битном режиме:
000 — [ЕАХ]
001 - [ЕСХ]
010 - [ЕРХ]
011 - [ЕВХ]
100 — используется З1В
101 - [ЕВР] (кроме МОП = 00 - в этом случае используется ЗТВ, после кото-
рого располагается 32-битное смещение)
110 - [ЕЗН
111- [ЕРП

1.4. Значения поля $1В


Значение поля 5:
00 — не используется
01 — умножение на 2
10 — умножение на 4
11 - умножение на 8
Значения полей Ги В:
(Т- регистр, используемый в качестве индекса, то есть умножающийся на 5; В -
регистр базы, который не умножается)
000 -ЕАХ
001 -ЕСХ
‚ 010 -ЕРХ
011-ЕВХ
50 ТТИ < ‚Приложение?
100 — для [- индекса нет. 7”; - т

для В - ЕЗР
101 - для [- ЕВР
для В - ЕВР только если МОП= 01 или 10; если„мор - 00 — базынет
110- ЕЗ
111 - ЕО

Поля Моав/М и $1В будут записываться как /т, если поле В/О содержит код
регистра, или /0 — /7, если поле К/О содержит дополнительные три бита кода
команды. В других случаях поля МоаК/М и $1В отсутствуют только у команд без
операндов, поэтому они не будут обозначаться дополнительно.

2. Общая информация о скоростях Запблнений


Скорости выполнения команд для процессоров 8086 —.Р5 даны в тактах (ког-
да говорят, что тактовая частота процессора 100 МН?, это. означает, что за секун-
ду проходит 100 миллионов тактов). г
Для процессоров Р5 (Репиит, Репёит ММХ) помимо скорости указано; ‘мо-
жет ли команда выполняться одновременно с другими, И 6сли да, то в каком' кон-
вейере (см. раздел 9.3.2): аня
о ОУ- может выполняться одновременно, в любом конвейере;
о РО - может выполняться одновременно, в Ч-конвейере;
о РУ- может выполняться одновременно, в У-конвейере:
О ЕХ - может выполняться одновременно с командой ЕХСН;
в МР - не может выполняться одновременно (для ММХ - не может выпол-
няться одновременно с командой того же типа, который указан после буквы п).
Для процессоров Рб (Репёит Рго, Репнит П) указано количество микробпе-
раций, на которые декодируется команда. Буквой С отмечены команды со слож-
ным строением (см. раздел 9.3.3).
Во всех случаях даны минимально возможные скорости — если шина данных
не заблокирована, операнды выровнены по границам двойных слов‚операнды на-
ходятся в кэше данных, команды по адресу для перехода расположены в кэше
кода, переходы угаданы процессором правильно, в момент выполнения команды
не происходит заполнения кэша, страницы находятся в ТГВ (иначе для Р5 следу-
ет прибавить 13-28 тактов), в момент выполнения команды нет исключений, не
происходят АСТ и т. д.
Операнды обозначаются следующим образом:
О 1т - непосредственный операнд;
О 16, 116, 132 - непосредственный операнд указанного размера;
О ас -— ЕАХ, АХ, АГ;
Я г- любой регистр общего назначения;
3 :8 - АН, АГ, ВН, ВТ, ОН, БТ, СН, СГ;
4 г16 - АХ, ВХ, СХ, БХ, ВР, $Р $1, ОЕ
Команды име! 80х86 ЕТ| |571
О г32 - ЕАХ, ЕВХ, ЕСХ, ЕОХ, ЕВР ЕЗР ЕЗТ, ЕП;
О зт - сегментный регистр;
С м - операнд в памяти;
@ тт - регистр ММХ;
О хим - регистр 55Е;
О $50 - регистр $Т(0);
О & - регистр $Т@).
Для команд условных переходов приводятся два значения скорости выполне-
ния — если переход произошел и если нет. у
Другие используемые сокращения:
О РМ - защищенный режим;
О ЕМ - реальный режим;
о УМ - режим \86;
О Т$ - переключение задачи;
С СС - шлюз вызова;
О ТС - шлюз задачи;
О /лп - увеличение привилегий;
О /оц{ - уменьшение привилегий;
О /МТ - переход во вложенную задачу.
Время переключения задачи:
о Репиит: Т$ = 85 при переключении в 32-битный и 16-битный Т$$ и 71 при
переключении в \86 Т$$;
О 80486: Т$ - 199 при переключении в 32-битный и 16-битный Т5$ и 177 при
переключении в \86 Т$$; |
О 80386: Т$ = 307-314 при переключении в 32-битный и 16-битный Т$$
и 224-231 при переключении в \86;
О 80286: Т$ = 280.

3. Префиксы
Все префиксы выполняются за 1 такт и имеют размер 1 байт:

ОЕ0Ь: ТОСК
ОЕ25: ВЕРМЕ/ВЕРМ,
ОЕЗЬ: ВЕР/ВЕРЕ/ВЕР7
2ЕВ: С$;:
361: $5:
ЗЕЪ: 0$:
265: ЕЗ:
64в: Е$:
65Ъ: С5:
661: 0$
67,: А$
5721 ОР Приложение 2

4. Команды процессоров \е! 8088 - Репйит Ш


Таблица 27. Команды

Команда Код
ААА 37
ААП 18 05 № 60
ААМ 18 045 7 83
ААЗ ЗЕ 8
АОС асит 14 т 4
АОС гут 80$“ /2 т 4
АОС тит 80$м /21т 23+еа
АБС г,г 104 /г 3
АОС туг 10а\м /г 24+еа
АБС ет 104 г | 13+еа
АОБ асит Од т 4
АБО гит 805м /0 ит. 4
АБО пут 80$ /0 т 23+еа
АБО гг 09мм /г 3
АБО т,г Оба\м /г 24+еа
АБО гп О009\ /г 13+еа
АМО аст 24 ип 4
АМОгт 805м /4 т
АМО т, 805\ /4 т
АМО г,г 20а\ /г
АМО тг
АМО гт 209 /г
АВРЕ г,г 63 /г
АВРЕ тг _
| —бЗ/
ВОЧМО г.п 62 /г
ВЗЕ г16,г16 ОЕ ВС /г
ВЗЕ г32,г32 ОЕ ВС /г
ВЕ г16,т16 | ОРВС/г
ВЗЕ г32,т32 | ОЕВС/г
ВЗВ г16,`16 | ОЕВО/г
ВЗВ г32,г32 | ОРВО/
ВЗВ г16,т16 | ОЕ ВО /г
ВВ г32,т32 | ОЕ ВО /г
ВУ\МАР г32 ОЕ С8г
ВТ гг ОР АЗ /г
ВТт,г ОР АЗ /г
ВТг,8 ОЕ ВА /4 5
ВТ т,‚8 ОЕ ВА /4 5
ВТС г,г | ОР ВВ /г
ВТС т,г ОЕ ВВ №
|ВТС г/8 ОЕ ВА /7Ь
Команды И\е! 80х86 1:| 1573]

Таблица 27. Команды (продолжение)

Код вот [80186 80266 90380 80486 РБ Рб


ВТС тв ОЕ ВА /7Ь `- 8 8 8 МР | 4т
ВТВ гг ОЕ ВЗ /№ 6 | 6 7 МР 1т
ВТА т.г ОЕ ВЗ /г 13 13 и 13 МР С
ВТН г/18 ОЕ ВА /6 № Г. 6 6 7 МР т
ВТВ 118 ОЕ ВА /6 8 8 8 М. | 4т
ВТЗ гг ОЕ АВ /г 6 | 6 7 МР Чт
ВТ тг ОЕ АВ /г — 13 3 | 13№ Тс
ВТ$ г/8 ОЕ ВА /5 5 6 6 7 МР Чт
ВТ$ м8 ОЕ ВА /5 5 | 8 8 ЗМ | 4т
САЦ. пеаг им | ЕВ п 23 14 7 7 |3 1 РУ 4т
САЦ. пеагг ЕЕ /2 20 [|
13 и [7 5 | 2 МР С
САЦ. пеаг п ЕЕ /2 29+еа 19 11 10 5 2 МР с
м) таг ит | ЗА ИИ 36 23 13 17 | 18 | 4№ с
М таг т ЭА т 26 34 20 | 4азм | С
САЦ т (Сб) | А | 41 и 52 35 22№Р | С
али ЭА п 2 | 86 | 69 44мм | С
САЦ ип (7$) | ЗА | 177 15 | 37+1$ | 21415 МР | С
САН Лт (Тб) | ЭАт 177 15 | 2741$ | 22475 МР | С
и таг т ЕЕ /3 53+еа 38 16 22 | 17 | а4№ с
—5.14№ | С
т г

ме" | РВ | 9 38 20
САЕтСб | Е/З “ 44 56 35 22 С
САЦ т Сб/п| ЕР /3 3 90 69 44№ | С
САЦ. т Т$ ЕЕ /З | 1$
Т | 37+1$ | 2475 № | С
СААтТЬ | РЗ | тв |37тв 22+Т$ № | С
СВУ 198 2 2 3 Е 3 МР т
с5а 99 2 З 2 МР Чт
сс ЕВ 2 2 2 2 2 2 МР 1
[1] ЕС 2 2 2 2 2 2МР | 4т
си | ЕА 2 2 Е Е 5 7 МР [с
СЕт$ ОЕ 06 2 5 7 10М [С
СМС 5 | 2 2 2 2| 2 | 2 МР 1
СМО\Усс гг ОЕ 4сс /г 2т
СМО\сс г.п | ОЕ 4сс /г Зт
СМР ас т ЗС\ т 4 4 Е] 2] 1 1 ОУ Чт
СМР гит 805 /7 ит 4 4 3 2 1 1 У 1т
СМР пит |805м /7т[__ 14+еа| 10 [6 |6 2 2 [|2
57 ГВ ‚ Приложение 2
Таблица 27. Команды (продолжение)

Команда Код 8087 __| 80186 |80289 |80389 |в0486 | 25 |6


СМРтл З8 ам /г з 3 2 2. 1 ТИ. Ат
СМР т,г З8 ам /г 13+еа 10 7 `.5 < 2 21 |. 2т
СМР г.п Зв /г 10+еа 10 6 в |2 20м [2т
СМРЗВ Аб 30 22 8 10 |8 БМР —|С.
ВЕР” СМРЗВ | [2/3 Аб 9+30п | 5+22п | 5+9 | 5491 | 7+7 | 9+41 МР
О А7 30 22 8 10 8 5№ |С
ПЕР”
СМР$\/О ЗАТ | 94301 | 54221 | 549 | 549 | 747 | 94амР
ЛР [С
СМРХСНС г.г | ОЕ ВО /т 6 БМ | С.
|СМРХСН@ т,г |ОЕ Вб\м /г 7..10 6 МР ^ С
СМРХСНСВВ ОЕ С7 /1 | 10. | С
СРИЮ ОЕ А2 | 14 13 МР. ^|"С
[И 99 5 4 2 | 2 3 2мР Ат
СМЮОЕ 98 3 [.3 ЗМ. |1
АА 27 4 4 Е 24 |2 ЗМ. |1
ОА$ 2Е 4 | 4 Е [4 |2. ЗМ. |4
ОЕС :16/32 48. Е — 3 2 2 1 тим. |1
РЕСг РЕМ /1 33 2 2. = 1 1 т
РЕС т РЕму /1 23+еа 15 7 6 .3 3 [4т
ОМ 18 Ебму /6 80.90. | 29 | 14 14 -16 17 МР. |Зт
О№ г16 Ебм /6 | 144.162 | 38 22 22 ‚24 25 МР .-|4т
ОУ 32 Ебм /6 | 38 40, 41 МР |4т
боба
Ебм /6 _| 150..168+еа
[85
БМ т32 Рбм /6 |
ЕММ$ 077 |
ЕМТЕВ {16,0 | С8м® И.
ЕМТЕВ 16,1 | С8м® | 25
ЕМТЕВ 16.8 | С8мЬ | (т=п-1) (22416| 12+4т | 15+4т
Е2ХМ1 310.630 _ [316.630 211.476

ЕАБО п32 08/0 | 90..120+еа | .- 90..120 | 24..32 т20, м. ЕХ


| РАБО п64__ 0С/
| | 95..125+ва | 95..125 | 29.37
ЕАОБ 30,5 08 С0г | 70..100 |. 70.100 |` 23.34 ЗИЛ ЕХ
ЕАОЬ 31,50 0СС0г | 70..100 |. 70..100 | 23..34 Е |
|ЕАООР 5,50 | ОЕСбг | 75..105 31. 75..105 |'_23..31 |` 8.20 | З/ТЕХ [Чт
[ЕВС т80 ОЕ /4 | 290..310+еа 290..310|266..275] 70..103 | 48..58 МР. 16.
Командь : ууе! 80х86 т 575,
Таблица 27. Команды (продолжение)

РЕВЗТР т80 ОР /6
80286 | 80386
ВОТ |90186 |вот |возёт 60486 в
148..154 МР]
_С |
[24.25 [6 1х
Зт

|
ГЕСмоУЕ зо вс [|
ЕСМОУВЕ
[2]о х.
РУМО\МО 50,51 ОА О8г
ЕСМОУМВ
ОВ С0г
Ф о ч.
ЕСМОУМЕ
ОВ С8г
50,51

вв
ЕСМОУМВЕ
м
О О О ПО О НЕ
ГЕсомтз2 | ве | вотонеа | [во | 26 | 4 | аи |2]
ГЕСОМтб4 | 06/2 [65.75% | [6575] м | 4 | 4” |2т|
сом | 0800г | 40.50 | [40.50 а [аи
ое ов оное а Е
ГЕСОМР ба | 5С/3 [65.75% | [65.26 [ м | 4 | 4х
ГЕсомРя | 9808г | 42.52 | [4252 | 26 | 4 [чм [т
Гесомев [Е | 45.55 | [45.5 | 6 |5 | ам [т]
ПЕС Е ОЕ С ООО ООО ООО ООО ООО ООО СС
ПС О ООО ООО ООО ООО ООО ООО ТС
0 [9 || | [188.72[257.384 18.14 МР] ©.
Геос | 59 | 69 | [ее | № [т
[ЕО тз2_ | 08/6 [215.225%8| _ [215.25] № | 18 | 398 |2т|
[РОМ 64 | 06/6 |220..230+еа | [220.230] 94 | 73 | 399 |2
ГЕОз0 | О8РОг | 193.208 | [198.208] 88-91 | 23 | 39 [1]
[ЕСМ 5.50 | ОСИ8г | 193.203 | [193.203] 88-9 | 79 | 3975 [1]
ГЕБМР 3.50 | ОЕРВГ | 197.207 | [197.207 9 | 29 | 399 [т]
[ЕО т32 | 08/7’ |216.226 | [216.226] в | 23 | 39 |2)
сл [221.291 [224.2] 9 | 239 | 39 [2
ов | 194.204 | [194.204 8851 | 29 | 397 [шт]
остог | 194.204 | [194.204] 88.91 | 29 | з9х [|
ГЕОМЯР 9.50| БЕРГ | 198.208 | [198.208] 9 | 28 | з9х [т]
[м |
| О ОО
ГЕРАЕЕЯ | [3 | [|
576 | 11| Приложение 2
Таблица 27. Команды (продолжение)

Команда Код 8087 80286 | 80386


80186 80287 | 80387 80486 Р5 рб
РАБО 32 БА/0 | 102.137+еа [| 102..137| 71..85 | 20.35 | 7/амР |С
РАБО п64 0Е/0 | 108..143+еа 108..143| 57..72 | 19.32 | 7/4 № [с
ЯСОМ т16 | ОЕ/2 | 72..86+ва 72.86 _ 71.75 | 16.20 | в/4м | с
АСОМ т32 | ©А/2 [| 78..91+ва 78.91 | 56..63 | 15.17 | 8/4м№ | С
АСОМР т1б | 0Е/3 | 74..88+еа 74.88 | 71.75| 16.20 | в/м |С
АСОМР т32 | А/З | 80..93+еа | 80.93 | 56.63 [15.47 | 8/9мМ | С
НОМ т16 ОА /б__ 224..238+еа | [224.238] 136.140| 85.89 | 42№ | С
НОМ т32 2Е/6 | 230..243+еа| -|230..243| 120..127| 84.86 | 42м№ |С
АОМВ п16 | ОА/7 | 225..239+еа 225..239| 135.141] 85.89 | 42м№ | С
НОМЯ т32 | 2Е/7 | 231..245+еа [231.245 121.128 84.86 | 42№ | С
НЕ т16 || ОЕ | 46..54+ва [46.54 | 61.65| 13.16 [ З7 М |4
ЕКО п32 ОВ /0 | 52..60+ва |52.60 | 45.52 | 9.12 | ЗАМ | 4т
ЕО 164 | 02/5 | 60.68+еа 60.68 | 56.67 | 10.18 | З/МР |4т
ЯМУ п16 | АЛ _124.138+еа| — [124.138] 76.87 | 23..27 | 7/4м№ [С
АМУЕ 32 ОЕ/1 | 130..144+еа 130..144| 61.82 | 22.24 | Там | С
АМСЗТР 09 Е7 6.12_ || | 6.12 аз | ам | т
АМТ вов ЕЗ | 2.8 | 2..8 3 | м | 16№ | С
АСТ т16 ОЕ/2 | 80..90+еа 80..90 | 82..95 | 29.34 | 6№ |4т
АЗТ т32 08/2 | 82..92+ва | Е 92 | 79.93| 28.34 | 6м |4т
АЗТР 16 | 02/3 | 82.92+ва |
82..92| 82.95| 29.34 | 6м№ |4
АЗТР п32_ | 08/3 | 84..94+еа 84..94| 79.93 | 28.34 | 6м№ | 4т
ЯЭТР т64 _ _ОР/7 | 94..105+еа | | 94.105] 80.97 | 28.34| бм | 4т
АЗИВ т16 БЕ/4 | 102..137+еа|| [102.137] 71.8 | 20.35
5 | амР_| С
НЗИВ т32 РА/4 |108..143+еа\_ _ |108..143| 57.82 | 19.32 | там | С
АЗИВЯ т16 | 0Е/5 | 102..137+еа —[102..137[ 71.85 | 20.35 | 1/4\№ | С
АБОВЯ 32 ` 0А/5 | 108..143+еа| —[108..143| 57..82 | 19.32 | там | С
Яр 32 | 09/0 |38..56+еа | [38.56 | 2 | 4 [| 1 | т
ЕО 64 06/0 _| 40..60+еа | 40.60| 25 3 ТЕХ | т
РИО т80 ОВ /5 | 53. .65+еа | 53.65 | 44 | 3 | ЗМ |4
Ея 9960г [17.2 ||. м | 4 | 1 АТ
ЕСО | 09Е8 | 15.21 [ 15.21 | 24 |4 | 2м [2
Рот — | 099 16..22 | [16.22 40 8 [| 53№ [2
Р.Е —| БЭЕА г 15.21 | 15.21| 4% |8 5/3 МР_ | 2т
ЕГОР! О9ЕВ | 16.22 16.22 | 40 8 5/3 МР_| 2т
оеЯ 09 ЕС 18..24 [18.24 | 41 8 | 5/3№ | 2т
ри 09 ЕБ 17.23 ||. м | 8 [| 53№ [2
157: [о о9ЕЕ [м о Ги [20 4 2м№ |1
ЕОС\! т16 | 09/5 | 7.14+еа | - 7.14 | 19 4 7М | Зт
ЕЕРЕМУ п14 | 09/4 | 35..45+еа| 35.45 [71 44 | 37№ | С
АМ 4 | 94
(РМ) | В 71 34 | 32.33 № | С
|
Команды Н\е! 80х86 ИЕ 577
Таблица 27. Команды (продолжение)

Команда Код 8087 | 80287 | 80387

ЕМИЕ 32 08/1 | 110..125+еа —110..125| 27.35


ЕМОГ 164 0с/1 | 154..168+еа 154.168 32.57 |
ЕМАХ 50,51 08 С8г 90..145+еа 1 90..145 29..57 16 3/1 ЕХ 1
ЕМОЕ $,50 ОС С8г | 90..145+еа | 90.145 29.57 16 ЗАЕХ | тт
ЕМОЕР $150 ОЕ С8г 94..148+еа |94..148 29.57 16 3/1 ЕХ 1т
ЕМСТЕХ ОВ Е? 2..8 | 2.8 11 - 9.9 МР 3Зт
ЕМО5 ОВ Е! 2..8 Г ЕМОР |
ЕМЕМ ОВ Еб 2..8 ЕМОР
ЕММТ ОВ ЕЗ 28 | 2..8 33 17 12мР С!
ЕМОР 0900 10.16 | 10.16 12 3 Тм т.
м п 6/6 | 197..207+еа |197..207| 375.376 | 154 127.151МР С
м т 00 /6 375..376| 143 | 124МР | С
ЕМЗЕТРМ ОВ Е4 2.8 | ЕМОР|
ЕМЗТС\/ т16 | 09/7 12..18 12.18 | 15 3 2МР | Зт
ЕМЗТЕМУ т16| 09/6 | 40..50+ва 40..50 |103..104| 56.67 |48.50 № | С
Е5Т5М п16 | 98 00/7 ` 12.18 12.18 | 15 3 2М |З3м
ЕЗТЗМ АХ | 9В ОЕ ЕЙ 10.16 | 13 3 2МР | Зт
ЕРАТАМ О9ЕЗ | 250.800 | [250.800 [314.487 218.303 19.134 М| С
ЕРВЕМ 09 ЕВ 15.190 15.190 | 74.155 | 70.138 | 16.64 № | С
ЕРВЕМ1 29 Е5 | 95.185 |72.167 |20.70 № | С
ЕРТАМ 09 Е? 30..540 30..540 [191..497 |200..273| 17..173 №| С
ЕАМОМТ 29 ЕС 16..50 16.50 | 66.80 | 21.30 | 9.20№ | С
м т 00 /4 | 197..207+еа 197..207| 308 131 | 75.95 № | С
| — |
м т 00 /4 308 120 70 | С
и п | 9800/86 |197..207+ва тело375..376| 154 |127..151 МР] С
ЕБАУЕ т (РМ)| 9В 00 /6 375..376| 143 124 МР | С
ЕБСАЕЕ 09 ЕБ 32.38 32.38 | 67.86 | 30.32 | 20.31МР | С
ЕЗЕТРМ ЭВ ОВ Ед | 2.8 | ЕМОР ||
Ем 9 ЕЕ | 122.771] 257..354| 16.126 №| С
Е5МСО$ 09 ЕВ 194..809| 292..365| 17..137 МР | С
ЕЗОАТ БЭЕА | 180.186. 180..186| 122.129] 83.87 | 70М | 1т
ЕЗТ т32 09/2 | 84..90+еа 84.90 | 44 7 | 2№ |2т
ЕЗТ 64 06/2 | 96..104+еа 96.104 | 45 | 8 2мМР |2т
ЕЗТ $ 00 00г 15..22 15..22 11 Е 1 МР т
{9 Зак. 459
5781 111111 Приложение2
Таблица 27. Команды (продолжение)

Команда Код 8087 (80186 80286 | 80386


0267 | 80387 Р5
ЕЗТР тЗ2 09/3 | 86.92+еа 86.92 2 МР
ЕЗТР 164 0073 | 98..106+еа | 9эв..106 8 2 МР
ЕСТР т80 ОВ/7 | 52.58+еа | 52. 3 МР
ЕЗТР 5 00 08г 17..24 17.. 1 МР
ЕЗТСМ п16 | 98 09/7 | 12.18 [ [ 12. 2 МР
ЕЗТЕМУт | 98 09/6 | 40..50+еа .. 103..104 `48..50 МР
ЕЗТЗМ т16 | 98 00/7 | 12.18 . 15 2 МР
ЕЗТ$МИ АХ | ЭВОЕ ЕО .. 13 2 МР
ЕЗИВ т32 08/4 | 90.120+еа .. -32 | 8.20 ЗАЕХ | 2т
ЕЗОВ пб4 0С/4 | 95..125+еа| . .36 | 8.20 | ЗЛЕХ [| 2т
ЕЗОВ $0,1 08 `Ебг | 70.100 .. .37 | 8.20 | З/1ЕХ
ЕЗОВ 51,50 ОС Е8г | 70.100 .. .37 | 8.20 | ЗАЕХ | т
ЕЗИВР 5,50 | РЕЕВг | 75.105 |. . .34 | 8.20 | ЗАЕХ [ т.
ЕЗОВВ п32 | 08/5 | 90..120+еа . .32 | 8.20 | ЗАЕХ [| 2м
ЕЗУВВ "64 | 0С/5 | 95..125+ва .. .. 8.20 | ЗМЕХ | 2т
ЕЗОВВ $0,5 | 08 Её8г | 70.100 . . 8.20 | ЗАЕХ
ЕЗОВВ 5,50 | ОСЕбг | 70.100 - 70. .. 8.20 | ЗА ЕХ
ЕБИВЕР 5.30 | БЕЕОГ | 75.105 . .. 8.20 |З/ЕХ
ЕТЗТ 09 Ед 38..48 4 4/1 ЕХ
РОСОМ = ОО Ебг 4/1 ЕХ.
РОСОМР5 | 00 Евг 4 ЕХ
РИСОМРР ОА ЕЯ О 4ЕХ |
РОСОМ! 50,5 | ОВ Евг —
ОМ ОР Е8г

РМАТ в 4 З 6 1..3 МР
ЕХАМ | 29 Е5 12.23 12.23 | 30.38 21 МР
ЕХСН 09 С8г 10..15 10..15 18. 1 РУ
ЕХАЗТОВ м | ОЕАЕ /1
ЕХТВАСТ 09 Е4 27.55 27.55 | 79.76 | 16.20
ЕХЗАМЕ т ОЕ АЕ /0
РУЕ2Х О9Е1 | 900..1100 |900..1100| 120.538! 196..329
РУ2ХР1 | 0929 | 700..1000 700..1000 |257..547 |171..326
НЕТ 2
1СН\ г8 101.112
12 716 165.184
ЮМ г32
СУ т8 107..118+еа
1ЮМ т16 | 171..190+еа
Команды
те! 80х86 1 579.
Таблица 27. Команды (продолжение)

80386
Команда Код 8087 80387 80486 Р5 рб
ОУ т32 Ебми /7 46 44 46 МР 4т
МАЕ г8 Рб\ /5 80..98 9..14 13..18 11 М 1т
МУЕ г16 би /5 128..154 9..22 13..26 11 МР Зт
МОЕ г32 Рбм /5 9..38 13..42 10 МР Зт
МОЕ т8 Еём /5 86..104+еа 12..17 | 13..18 | 11 МР 2т
МУ т16 |Е6\ /5 134..160+еа 12.25 | 13.26: ИМ 4т
МУ: г32 Рем /5 12.41 | 13.42| 10 МР 4т
МУ г.г,8 бВль 9..14 13..18 10 МР ‚т
+
МУ
г16,г16,116
69 /гт 9..22 13..26 10 МР ‚ тт
——ф-
МОЕ
69 /гит 9..38 13..42 10 МР тм
г32,г32132 —
ТМ г,г18 бвВлЬ 12..17 | 13..18 10 МР 2т
МУ | 69 /гит 12..25 | 13..26 10 МР
г16, т16,116 |
ИМИЕ _ .
69 /гит 12..41 | 13..42 10 МР
г32,т32132
МОЕ г16,
г16
ОЕ АЕ /Г 9..22 13..18 10 МР
МАЕ г32,г32 ОР АР /г 9..38 1 13..42 10 МР
——
МОЕ г16,
ОР АЕ /г 12..25 13..18 10 МР
т16 (
1МУЬ гЗ2,
т32
ОЕ АЕ /г 12..41 13..42 10 МР
№ ас/8
(АМ)
т Е4м | 14 12 14 1 МР
И№ асл8
(СРЕЗЮРЬ) Е4\м 4 МР
1№ аси8
Е4\м 6 21 МР
(СРЕ>ЮРИЕ)
1№ ас/!8
Е4м 6 19 МР
(\86)
№ ас,0Х
ЕС\ 7 №
(АМ)
1№ ас,оХ
ЕС\ 4 МР
(СРЕЗЮРИ}
1№ ас.оХ
ЕС\
(СРЕ>ЮОРЬ)
№ ас,0Х
ЕС\
(\86)
МСт РЕМ /0
1МС г16/32
мт -
1№5* (АМ)
580 | |1 ТПП Приложение 2
Таблица 27. Команды (продолжение)

Команда
| Р5
|
\5*
СРЕЗЮРИ) 6С\м | 9 10 6№ с
1№5* = и
(СРЫЮРЫ | 6С\ | 29 32 24 МР
1\5* (\86) 6С\ 22 | 30 | 22№
ИМТ 8 (АМ) | С0ь 71 47 23 37 30 16 МР
МТ 18 (РМ) Со 40 59 | 44 | 31 С
МТ 18 (РМ/п)| СО 78 99 71 48 МР С
мт 8 (86) | Соь 78 119 82 60 МР С
ИМТ 18 (Тб) соь | 167 | 15 [| 3741$ | 23475 № | С
1МТЗ (АМ) сс 72 45 23 33 | 26 16 МР С
ИТЗ (РМ) сс 40 59 | 44 30 МР [5
МТЗ (РМ/п) | СС | 78 99 71 47 МР С
МТЗ (У86) сс 78 119 82 59 МР |
ИМТЗ (Тб) [976 167 | 15 | 37415 | 22415 № [С
МТО (ОЕ=0) | СЕ 4 4 Е Е Е 4 МР С
МТО (ВМ) СЕ | 73 48 24 35 28 13 МР С
МТО (РМ) | СЕ | 59 | 46 |й 30 МР С
МТО (РМИп) СЕ 99 73 47 МР С
1МТО (№86) СЕ 118 84 59 МР С
МТО (Тб) СЕ 17$ | 29-15 | 22415 МР | С
1\УО ОЕ 08 | 4 15 МР | ©
ММЕРС пп ОЕ 01 /7 | 12 25 МР С
1ВЕТИВЕТО
(ВМ) СЕ 44 28 17 22 15 7№ с
'ВЕТЛВЕТО
(РМ) СЕ 31 | 38 15 10..19 МР | С
1ВЕТЛВЕТО
РМ СЕ | 55 82 36 27 М с
ВЕТЛВЕТО
М/Т) СЕ 169 1$ | 32+1$ | 10+т$ | С
сс 18 70сь. т тт
(не вып.) 4 4 3 3 1 1 РУ
сс 18 (вып.) | 70с№ 16 13 7 7 Е 1 РУ
ес ит ] и |
не вып.) ОЕ 80с № 3 1 1 РУ
сс ит (вып.) | ОЕ 80с № | 3 |1 1 РУ
3СХ218
не вып.) ЕЗЬ | 6 5 4 5 | 5 5М
3СХР 18 (вып.)| ЕЗЬ 8 | 16 8 9 8 6 МР
МР пеаг 8 | ЕВЮ 5 |3 [|7 7 Е 1 РУ
УМР пеаг
6/32 Е9 . 15 | 7 7 3 | ПР
Команды Не! 80х86 1]
| | |581
Таблица 27. Команды (продолжение)

80286 | 80386 ве|


Команда Код 80287 | 8036 |во4в6 | Р5 Рб

МР пеагг ЕЕ /4 11 11 т |2 2т
УМР пеаг т ЕЕ /4 18+еа 17 11 10 - 5 | 2 МР 2т
|
АМ)
УМР Тагт .
ЕА т 15 13 11 12 17 МР | С
УМР Фаг т
ем“ | ЕА .т 27 19 23 МР с |

а" БАшт | 38 ; 45 32 18 С
УМР таг ип 1 | 175.| | 1$ — | 42+1$ ‚ 1941$ МР
т) аг! ЕА ип
те) тагт ЕА т 180 | 1$ | 4341$ | 20%15 МР |
УМР таг т | 4 МР
АМ) ЕЕ /5 24+еа 26 15 12 13
УМР гт 18 23 МР
РР /5 31
ей @гт
УМР ЕЕ /5 | | 41 49 31 18 МР

р таг т ЕЕ /5 178 | 5415 | 41+Т8 | 19+1$ МР


16) таг т ЕЕ /5 183 | 5+15 | 42+Т$ | 20+1$ МР
ГАНЕ 9Е 4 2 2 2 3 2 МР
АВ гг
1 ОЕ 02 /№ 14 15 11 8 МР
ГАВ г. ОЕ02 /г | 16 | 16 11 8 МР
10$ гм (ВМ) С5/ 24+ва 18 77 6 4 МР
10$ гм (РМ) | С5/ Г 22 12 4.13 МР
ГЕА г.п 80 /г 2+ва 6 3 г 2 1.2 | 1
ГЕАУЕ 9 8 Г 5 4 5 3 МР
ТЕЗ гм (ВМ) | С4Д 24+еа | 18 | 7 7 6 | 4№ С
ТЕЗ гм (РМ) | С4/ 22 12 4.13 № | С
ЕЕ$ гит (АМ) | ОЕ В4 /г 7 6 4 МР С
ТЕЗ гм (РМ) | 0ЕВ4 Л
т +
22 12 4.13 МР | С
ЕбОТ т ОЕ 01 /2 11 11 11 6 МР С
16$ гм (АМ) | ОЕ ВБ / 7 6 4 МР С
(6$ гп (РМ) | ОЕ ВБД 22. 12 4.13 МР | С
НОТ т ОЕ 01 /3 | 12 11 11 6 МР С
ПОТг ОЕ 00 /2 17 20 11 9 МР С
ИОТ м ОЕ 00 /2 19 ‘24 11 ЭМР с
ЕМ$\/ г ОЕ 01 /6 Е 10 13 8 МР С
ЕМ$\/ т ОЕ 01 /6 6 13 13 8 МР С
тоСк ЕО 2 2 0 0 1 1 МР С
5821 ГОРЕ Приложение 2
Таблица 27. Команды (продолжение)

Команда Код
1400$8В/
ГОО$М// АС\
100$0
ГООР 18
(не вып.)
Е2Ь

1ООР 18 (вып.) | Е?
|ООРЕ 8
ЕТ Ь
(не вып.) |
1ООРЕ 18 (вып.) ЕЮ
ГООРМЕ В |
(не вып.)
ЕО Ю
1ООРМЕ 18
(вып.)
ЕО Ь

ЗЕ гг ОЕ 03 /г

ЗЕ г.п ОЕ 03 №

13$ гм (АМ) | ОРВ2л


155 гм (РМ) | ОЕВ2/
Г
000 /3
ОЕ 00 /3
889\ /г
МО\Утас —|Абды т
вам |
МО\ ас,т
МОУ гт
МОУ тит Сбм /0 т 14+еа
—_—— НИ ОИ
МОУ г8 18 Вог ь
МОУ
г16/32;116/32

МОМ зг,г (РМ)


МОУ эг,т
МО\ 5г,т (РМ
р
МОУ г,5г
МО\ т,г __| 8 |
МОУ СВО ОЕ 22
МОУ СА2.г Г ОЕ 22 /
Команды И\е! 80х86 О В И ПИ МЕ
Таблица 27. Команды (продолжение)

Команда Код 3о

МОУ СВЗ,г ОЕ 22 л
МОУ СВА4.г ОЕ 22л
МОУ г.СВх | ОЕ 20
МОУ ОРО-3,г ОЕ 23 /г
МОУ О0В4-5г ОЕ 23 /
МОУ ОНб-7,г ОЕ 23 №
МОУ г‚ОВО-3 ОЕ 21 /
МОУ г.ОН4-5 | 0221 /г
МОУ г.ОНб-7 ОЕ 21 Л ооо
ооо
оо
МОУ ТВб,г ОЕ 26 /6
МОУ ТН7,г ОЕ 26 /7
МОУ ТВЗ,г -
ОЕ 26 /3
МО\ г,ТАб +
ОЕ 24 /6
МО\ г,ТВ7 ОЕ 24/7
МОУ г,ТВЗ ОЕ 24 /3
МОУ
ОР 6Е /г
тит,32
МО\О г32,тт ОЕ 6Е /г
моур
ОР 6Е /г
т32, тит
ее
ОЕ 7Е г
64, тт
моУуа
и, 1164
ОЕ 6Е /г
моУуа
тт, пт
ОЕ *Е/г

МО\5Х гг ОЕ ВЕм /г
МОУ5Х г,т Г
ОЕ ВЕМ /г
МО\7Х гг ОЕ Вбм /Г
МОУ2Х г.п ОЕ Вбм /г

МУ г16 118..133
МЫ. г32
76..83+еа
МИ т16 124..139+еа
МУ т32
Приложение 2
Таблица 27. Команды (продолжение)

Команда _| Код 8087 80286 | 80386


80186 80287 (80387 80486 Р5 Рб
МОТ г Рбми /2 3 3 2 2 1 1 МР 1т
МОТ м Ебмм /2 24+еа | 13 7 6 3 ЗМ | 4т
ОВ асит ОС т | 4 3 2 1 тм |м
+
ОВ гит 805 /1 ит 4 4 3 2 1 1 ЧУ 1т
ОВ тит 805м /1 ип| 23+еа 16 7 7 3 Зи | 4т
ОВ гг 08 ам /г 3 3 2 2 1 1 им фт
ОВ тг О8а\ /г 24+еа 10 7 7 3 3 ИУ 4т
ОВ г,т ОВа\м /г 13+еа 10 7 6 2 2 и\ 2т
ОЧТ 8,ас .
(ВМ) Еб\м 65 14 9 3 10 16 12 МР [©
ОЧТ 8, ас .
(СРЕЗЮРИ Еб\ 16 4 11 УМР С
ОЧТ 18,ас .
(СРАЗЮРЫ Еб\/ © 24 Зл 26 МР С
ОЧТ 18,
ас .
(\86} Ебм Ю | 24 29 24 МР С
ООТ ОХ, ах
(АМ) ЕЕмМ/ 12 7 3 11 16 12 МР С
ОЧТ ОХ, ас
(СРЕЗЮРИ) ЕЁЕМ
|
5 10 9 МР [©
ОТ ОХ, ас
(СРЕ>ЮРЕ) ЕЕМ 25 30 26 МР С
ОЧТ ОХ, ас |
(\86) ЕЕ | 25 29 24 МР С
|
ОЦТ$* (АМ) бЕм 14 5 14 17 13.МР С
оот5*
(СРЕЗЮРИ
| бЕм | 7 [|
8 10 10 МР С
ОитТ5*
(СРЕ>ЮРИ бЕм 28 32 27 МР С
ОЧТ5* (\86) бЕм 28 30 25 МР
РАСК$ЗМ/В
"А ОЕ 63 /№ ЦУ МР1 1т
РАСКУЗМВ
тт, 64 ОЕ 63 /г | РУ МР1 2т
РАСК$ЗОМ/
1 ОР 6бВ № | Ц\ МР1 1т
РАСКЗ$ОМ |
пла, 164 ОЕ 6В г | РУ МР1 2т
РАСКУЗ\МВ
"Ат ОЕ 67 ЦУ МР1 1т
РАСКОЗМ/В
пт, 164 ОЕ 67 /г РУ МР1 2т
Команды Ип{е! 80х86 ТТТ
| |585 08
Таблица 27. Команды (продолжение)

8087 80186
80286 | 80386
80287 |80387 80486 | Р5 Рб
Команда Код

РАБОВ ОЕ ЕС /г | и\ Ат
пт,

РАБОВ ‚РУ 2т
тт, 64 ОЕ ЕС /г |
|
и +

РАБО ОЕ ЕО /г :
У 1"
шт”

РАББМ64
т ОЕ ЕО г РИ 2т

РАОООам ОЕ ЕЕ /г ИУ 1
тт,

РАБОБ |
тт, т64 ОЕЕЕ /г | | РУ 2т
- +| |
РАБОЗВ ОЕ ЕС /г | ТУ Чт
шт,
- 1

РАБОЗВ
64 ОЕЕС/г р | РИ 2т

РАБОЗМ ОЕ ЕО | и\ тт
шит | .

РАБОЗ\/ ОЕ ЕБ /г | РИ 2т
64

РАРОИЗВ ЕСИ и\ тт
пп, 707
РАБООЗВ
та ОЕОС Л | РУ 2т

РАБВУЗМ ОРОО /г ЦУ 1т
пт,

РАБОИ$М
тт, 64 ОРОО /
И , РИ 2т

РАМО ОЕ ОВ /г ИУ ат
шит,т
Г

АА по | ООВ РИ 2т

РАМОМ ОЕ ОЕ | У 1т
пит; | _
РАМОМ ОЕ ОЕ /г РИ 2т
тт, 164 |_ ОИ „ —
РСМРЕОВ
пгт ОЕ 74 № Ц\ 1т

РСМРЕЯВ ОЕ 74 /г РИ 2т

РСМ РЕМ | 75 им Ат
таит
5861 ТОРТ Приложение 2
Таблица 27. Команды (продолжение)

Команда Код 8087 |80186] 80287


80286 |
|80386
80387 | „56 Р5 Р6
РСМРЕВМ
тт, 164
> 0275 / | 1 РИ т 2т
| | — о _| |
РСМРЕСО ОЕ 76 /г и\
тит, пт | 1 _| _| с | |
Чт
РСМРЕСБ 76
тт, 164 РИ т
РСМРСТВ | ОЕ 64 /г
т |
_|
Г.
|
|
шт, тт - —+ о
У 1т
1 |
РСМРСТВ ОЕ 64 /г | РИ
тт, 1164 2т
РСМРЕТМ |
пит |ОЕ 65 /г | и\ ат
| |_ _| —
РСМРЕТМ" | и
тт, 164 ии
РИ т
| 1
ОМ
папу | обе —} | им
м | т
| | _| _ | |
РОМ об РИ
пт, 1164 |_ | |.
2
ОМ
шт, т
| ЕБ ИМ №Р2 _| 1т
__| _| 1
РМАБОМ
ОИ

та О ОЕ РБ | | _| Рома |2т
РМУЕНМ
тит ОЕ ЕБ /г ИМ МР? | 1т
| _|_ - | |
РМОСНИ
шт, 164 ОЕ ЕБ г. РИ МР? | 2т
| |
РММ
тт Г. ||.
ОЕ 05/1 Г
| | ИМ №2 | 1т
МОИМ
тт ОЕ05 Л - Г
РИ МР? | 2т
РОРГ 1
РОР т 5 6 2М | С
РОР 0$ (АМ) Е 2 8 5 7 |3 МР С
РОР 0$ (РМ) | Е | 20 21 9 3.12 М | С
РОР ЕЗ (АМ) 7 12 8 5 7 3 ЗМ С
РОР Е (РМ) 9 С
З С

РОР 6$ (АМ)
РОР 65 (РМ)
Команды И\е! 80х86 | |587
ИТТ
Таблица 27. Команды (продолжение)

Команда

РОРА/РОРАО
РОРЕ/РОРЕО | ср
(АМ)
РОРЕ/РОРЕБ 96 |
(РМ)
РОВ мт,тт | ОРЕВ /г

ОР ЕВ /г

ОЕРЕ1 М т

ОРЕТ М
|

ОЕ 71 /6 6

ОРЕ2 /г
Р$Н.0
тт, 64 ОЕ Е2

РЗЫО 01,18 | ОЕ 72 /6 Ю |

ОЕ ЕЗ /г

ОЗ ||
РЗЦ.О тт, [Е 73 /6 5
ОЕ.
ОЕЕ1

ОЕ 71 /4 6

ОЕ Е? /г
ОЕ Е? /г |
ОЕ 72 /4 №
1
ОЕ ОТ

ОЕО1 |

ОЕ 71 /2 №

ОЕ 02
БЕТ О ОА И | Приложение 2
Таблица 27. Команды (продолжение)

Команда

РЗВЕО
тв |
ОЕ 72 /2 1 ЦУ МР1 | 2т
РАГа
шт,тт
ОЕ 03 /г ИМ МРТ | 1т
|
| |
ои
РУЛЬ ОЕ 03 /г РИ МРТ | 1т
пт, т64 | |

РУЛЬ
1. т

тт, 18
ОЕ 73 /216 | ИУ МРТ || 2т
РЗУВВ
пт, т7
ОЕ ЕВ /е |
| См 1т
| | |_

РЗИВВ
тт, т64 ОР [8 /г | РИ 2т
РЗИВМ/ - ти
ЕО я я
ти, мт | | р
РЗИВМ/
тт, 64 ОР Е9 /г | РИ 2т
РЗИВО
т ОЕ ЕА /г им т
РЗИВО т 7] т

тип, 164 ОЕ ЕА /г _| РИ 2т
РЗИВ$В РЕВ № т
ПТИ, | | | _| |8

РЗИВЗВ
пт, 1164 ОР Е /г РУ 2т
РЗИВ$\ р ОЕ № и
шт, тт | .]

РЗИВ$М/
пт, п64 ОР Е9 /г | РУ 2т
| | Ч
РЗИВИЗВ 08 | № м
ти, мт | _| | |

РЗИВИ$В Г.
тт, 64 ОЕ 28 /г | | РИ 2т
РЗУВИ$М
пи, ОЕ 09 /г ЦУ 17

РЗИВИЗМ Е 9 | —}
м —т
ри
шт, 064 _| р_
РУМРСКНВМ | Е бз и
- |и - й

И ПИ
шт, тт 1 | [_
РИМРСКНВУ/
пт, тб4 ОР 68 /г РУ МРТ | 2т
РИМРСКНМ/О
т ОЕ 69 /
Команды пе! 80х86 | ПО О И ПИ ЕС
Таблица 27. Команды (продолжение)

80186
80286 [ 80386
80287 | 80387 80486 Р5
Команда Код

РОМРСКНУ О (Е 69 РИ МР1
тит, 64.

РУМРСКНОЯ | (бад У МР1


шт, пт

РОМРСКНОЯ | себ РИ МР1


тит, 1164

РОМРСКЕВМ | болг (М МР1


шт, |

РИМРСКЕВУМ
тб ОЕ 60 /г РИ МР1

РОМРСКЕМО | оби Ц\ №Р1


пп, 77
РОМРСКЕМО | орбаи РИ №Р1
пт, 764

РУМРСКРЯ | пб У МР1 |
шт,тт

РИМРСКЕОО
т 64 ОЕ 62 /г РИ МР1 | 2т
РИЗНГ 50г 5 | 0 3 2 1 тии | 3т
РИУЗН т ЕЕ /б 24+еа 16 5 5 4 2 МР 4т

РИЗНВ бАЪ Е 2 1 ТМ | Зт
РУЗН 6/32 | 68 т 3 2 1 МР |3
РИЗН С$ ОЕ 14 9 Е 2 3 ТМ 4
РИЗН 0$ ЧЕ 14 9 Е 2 Е МР | 4т
РИЗН ЕЗ 6 14 9 Е 2 Е МР | 4т
РИЗН $5 16 14 9 3 | 2 Е МР |4
РИЗН Е ОЕ АО 2 з ЧМ | 4т
РИЗН 6$ ОЕ АЗ 2 Е ТМ | 4т
РИЗНА/ Г 18 11 5 МР с
РИЗНАО 60 36 17
РИЗНЕ/
р РОЗНЕО (АМ) эс 14 9 3 4 4 9 МР с
РИЗНЕ/
РОЗНЕО (Рм)| С 3 4 3 3 МР с

РХОЯ ОЕ ЕЕ /г У 1т
па, А

РХОВ 64
тт, м ЕЕ /Гг РЦ 2т

ВСЕ г. ром /2 2 2 2 9 З ТРИ | 2т


АСЕ т,1 Сом /2 23+еа 15 7 | 10
ВСЕ г. СЁ О2\м /2
5901 ТП Приложение 2
Таблица 27. Команды (продолжение)

Команда Код 8087 [80186


80286 | 80386
зову | возв7 80486 Р5 рб
ВСЁ т, СЕ О2\м /2 28+еа+4п | 17+п 8+п 10 9..31 9..26 МР С
АСЕ г18 С0м /2 16 5+п 5+п 9 8..30 8..25 МР С
ВСЕ т,18 Сом /2 1 ‚| 1741 | 8+1 10 9..31_| 10..27 МР | С
ВСВ г,1 00м /3 2 2 2 9 3 ТРИ
ВСВ т,1 00м /3 23+еа 15 7 10 4 ЗРУ

ВЕТЕ (АМ)
ВЕТЕ (РМ) | СВ | 25 32 18 | 4.13 МР
ВЕТЕ (РМ/о)| —СВ- Г 55 62 | 33 | 23№
[ВЕИ6 ТЕ
(ЯМ) САМ | 33 25 15 18 14 | 4МР
НЕТ И6(М) САМ | Г 25 | 32 7 4.13№ ||
|
МИ) САМ | | 55 68 | 33 | 23№ [с
ОЕ Оо /0 2 2 |2 Е Е РО |1
23+еа 15 7 7 4 ЗРЫУ
ВОЕ г.СЕ
ы З 3 4 МР
<
28+еа+4п 7 | 4 4 №Р
ВОГ г.в Г | 5+ 3 |2 | 1Р
ВОГ т, | бби/оь | 17+п | 8+1 — 7 4 ЗРО
ОВ г.1 0 /1 2 |2 2 313 ТРИ
НОВ т, | 00%/1 | 23+еа | 74 | ЗР
ОВ ге | 02/1 | 8+4п _| 5+ | 5 [3 [3 [ 4№
АОЯ п,СЕ | 02/1 | 268+еа+4п | 17+п | вп |4 4 МР
ВОВ г Сом [| ПГ 5+ | бп 3 2 |
- | - т ——
ТРИ
ВОН т,‚:8 Сом /ТЬ |. 17+п в+п
т
7 4 ЗРИ
АЗМ
—+
ОРАА |
— —+ — +
83 МР
ЗАНЕ 9Е |3 [2 [2 | 2№
ЗАЕ г. ом /4 2 [2 2 |3 ТРИ
ЗАЕ т, 1 | 20% /4 23+еа | 15 7 7" |4 ЗРО
ЗАЕГСЕ | 02/4 | 8+4 5+1 | 5 Е Е] 4 МР
ЗАЕПьСЕ | 02/4 | 28+еа+4п [7 т 7 4
АС Г.В С0\ /4 15 З 2
Команды 1п*е! 80х86 НО И ПЕ
Таблица 27. Команды (продолжение)

80186
80286
80287 | 80387
Команда Код

ЗАЕ тив Сб\ /4 1741 | 8+ 7

28+еа+4п | 17+п 81 7 ‚ 4М№Р 4т


ЗАВ т, СЬ О2\м /7
5+п 5+1 ‘3 2 ТРУ | т
ЗАВ г18 С0\м /7 16
17+п 8+п 7 4 ЗРЫУ !4т
ЗАВ т,8 С0\ /7 5
4 | к 2 1 ТРИ ‘2т
ЗВВ ас/т 1 Си т
| 4 | З 2 1 ТРУ :2т
УВВ гит 80$м /3 т
805 /З т | 67 7.3 ЗРИ | 4т
ВВ пт
18 ам /г 221 1 РУ 2т
ЭВВ гг | 4 4
4+еа 10 7 7 3 ЗРУ 4т
5ВВ тг 184 /г
УВВ гп 18а /г 13+еа | 10 ' 7 6 2 2РЦЫ | 3т
ЗСАЗВ/ 4МР |3Зт
ЗСАЗМИ/ АЕМ ‚ 15 7 7 6
$САЗО | И _| |_
С
РЕР* $САЗ* | Е2/3 АЕм | 9+15п — 5+157 | 5+8п | 5+8п | 7+5п | 8+51 МР |
ЗЕТсс г8 | 4 4 1 № 1т
ОР 9сс Ч
+ — _ 4 _
(вып.) -—
ЗЕТсс г8 4 3 ЗМР Зт
ОЕ 9сс -
(не вып.) | | 1 | — |_
ЗЕТСс 8 ОЕ 9сс 5_ З ТМ || 1т
(вып.) | ри |

ЗЕТСс 118 ОЕ 9сс |. 5 4 ЗМ | 3т


(не вып.)
эботм _ | 0Е01/0 Ши 9 10 4МР |4т
ЗН г Бом /4 | | 2 2 3 3
ЗНЕ т,1 20\ /4 3+еа | 15 7 7 4
$НЕ Г.С 02 /4 51 | 5т | 3 Е
02\ /4 | ава 17+п 8+п _| 7 4
5НЕ т, СЕ
ЗН г
———
| С0м/4№ 5+0 | 54 Е т”
2
УНЕт,8 Сом /4 7 | вт | 7 4
ЗНВ г.1 00% /5 223 Е
ЭНА т,1 00%/5 | 23+ва 15 7 7 4
ЭНАС | 02/5 5+п | 5+ Е] Е
ЗНВ п, СЕ 02/5 | 28+еазат | 171 | вт |7
НЯ г8 См /5 |_ 5+1 | 5 | 3
/5 —_|[17+п
-7

8+1 7
| Сом
-
ЗНЯ 1,8 .
- + З
ЗНЕО Гм ОЕ Ад |.
$НЕО ггСЕ ОЕ АБ Е
[592 | [1111] Приложение 2
Таблица 27. Команды (продолжение)

Команда Код ` 8087


ЗН тит | бд | Г — 7 |3 АМ | 4т
ЗНЕО тг СЕ | ОЕА5 | 7 4 5 М | 4т
ЗНАО гам | ОРАС | | | ИЕ 2 М |2т
ЗНЯО г.СЕ | РАБ || [ Е Е МР | 2т
ЗНВО пугим | ОРАС |. "|3 4 МР
ЗНВО т,г.СЕ | ОЕАОБ | 7 4 5 МР
Тм ОЕ 01 /1 Г | № 9 10| 4№
ЗЕОТ 16 0Е00/0 | |] 2 2 2 2№ | 4т
ЗЕТ т16 | 0200/0 Гз [2 з | 2№
ЗМ$\М/ 116 ОЕ 01 /4 2 2 4 МР
ЗМ5М/ т16 | 0Е01 /4 | Е Е 4М |. С
2 2
2 2
эт Е 5
$то$в/
$ТО$М// АА\М 11 10 Е] 4 5 ЗМР Зт
$7050
ВЕР $Т05* | ЕЗ ААМ 9+14п 6+9п | 4+3п | 5%5п | 7+4 | Зам | С
ЭТВ 116 ОЕ 00/1 || 2 2 2 2МР |4т
ЗТЯ п16 (| 0Е00/1 3 2 3 2 МР [5
ЗВ асут 2Суи т 4 4 Е 2 1 тии |м
ЗИВгит | 805% /5 ип [4 [3 2 м |т
ЗВ тит 805м /5 т 23+еа 16 7 7 Зи
ИВ гг 28а /г ВЕ з 2 2 т ом [м
ЗОВ пьг 284% /г | 24+ва 16 7 7 Е ЗМ |4
ЗИВ т |
289 /г 13+еа | 10 7 в | 2 2м [2
ЗУЗЕМТЕЯ 034 || С
ЗУЗЕХТ ОЕ 35
ТЕВТасит | Вии | 4 [а [1 Г 15
ТЕЗТ гит |Р6м /4 т 5 |4 [3 И ИИ У
ТЕЗТ пыт | Рб\ /4 ит| 11+еа 10 6 5 2 | 2 |2
ТЕЗТ ГГ 84 /г 3 |3 2 |2 1 то |1
ТЕЗТ т.г 84м/г | 1З+ва 10 6 5 [2 2м | 2т
ТЕЗТит |84% 13+еа_ | 10 6 5 2 2
02 ООВ | |
УЕВВ г16 ОЕ 00 /4 14 оп | 7№ [С
МЕВЯ 16 _| 020014 | | 16 11 11 7 [С
МЕВ\ г16 ОЕ 00 /4 14 15 11 7 [С
\МЕВМ/ т16 ОЕ 00 /4 Г |
МАТ эВ
Команды \{е! 80х86
Таблица 27. Команды (окончание)

80486 Р5 Рб
Команда Код
и |
МиВиМУО ОЕ 09 [_ 5 | 2000+№ | С
М/ВМ5В 030 | Г. [ 30.45 № | С
_| 3 ЗМР 4т
ОЕ СО\м /г
ХАОО п ОЕ Сб\ /г | | 4 4 МР С
хсне ас,г / 90г 3 ТТ з 3 Е 2 |3
1 _
;
ХСН гг
|
86 /г 4 4 | 3 [3 Е ЗМР | Зт
—+
=—

5 5 ЗМ | С

хонс И | 86 25+еа |5
ХЬАТ
}

57 11 м | 5
_—

1
5 4 --
АМ и|

1
ХОВ аслт Зам т | 4 4 |3 2 1 ТУ т
1 м 1
1

ХОЯ гит _ [805% /б т 4 4 3 | 2


ХОА тит [805и/6 | 23+ | 16 | 7 7 Е Зи [4
3 3 2 Г 2 1 1 У 1т
ХОР гг _
| З09м г |
ХОВ тг 30а /г 244еа | 10 7 7 | оз [4 |
ХОВ гм 30а /г 13+еа 10 7 6 2 2№

Команда Код

МОУАР$ хтт, хтт/т128 | ОЕ 28 /г


МОМАР$ хтт/п128‚хгт ОЕ 29 №
МО\УР$ хтт,хтт/т128 — ОЕ 10 Л
МО\УИР$ хит, хтт/т128 | СЕМИ
МОМЁР$ хтт,тб64 [1 ОЕ 12 Л
МОМЕР$ тб4.хтт ОЕ 13 №
МОМНИР$ хит,хтт | 0Е12/
МОУНР$ хтт,тб64 о 0+ 16 Л
МОМЕНР$ хтт, хит ОЕ 16 №
МОУНР$ п164,хтт | ЕЛ
МО\$$ хтит,хтт/т32 ЕЗ ОЕ 10.
МО\$$ хтт/т32,хтт ЕЗ ОЕ 11 /г
АООР$ хтт,хтт/т128 ОЕ 58 /г
АОО$$ хти,хлт/т32 ЕЗ ОЕ 58 /г
ЗУВР$ хтт,хтт/т128 ОЕ БС /г
$18$$ хтт,хтт/т128 | ЕЗ 0Е5С №
МЦЕР$ хит, хпит/т128 Г ОЕ 59 /г
МУЕ$$ хтт,хтт/т32 |_ ЕЗ ОЕ 59 /г
ОМР$ хтит,хтт/т128 ОР5Е /г
0$$ хит, хит/т32. ЕЗ ОРЪ5Е г
7

594] |||] Приложение2


Таблица 28. Коды команд расширения $$Е (окончание)

| км | К |

РЗ ОЕ СГ

ве
СУТР!2Р$ хтт,тт/тб4 ОЕ 2А М

СУТР$2Р! тт, хтт/тб4 ОЕ 20 Л


ЕЗ ОЕ 20 /г
ОЕ2С
С\ТТ$$2$1 "32, хтт/т32 ЕЗ ОЕ 2С /г
АМОР$ хти, хтт/т128 ОЕ 54
АМОМР$ хтт,хтт/т128 ОЕ 55 Л
ОВР$ хтт,хтт/т128 ОЕ 56 №
ЯМ В О О ПО ООО О ПОНИ

Используемые сокращения
АВГ — АррНсаНоп Втагу Пиегасе Интерфейс для приложений
на низком уровне
АСТ — АЧ@гезз Сепегайоп Пиегоск Задержка для генерации адреса
АМ!$ АЁегпайуе МшШарех Ниеггаре Спецификация альтернативного
Зрессайоп мультиплексорного прерывания
АРГ — АррЁсайоп Ргоягат Ищбегасе Интерфейс между приложением
и программой
АЗСИ Атепсап З&ап4аг4а Со4е Американский стандартный код
юг шбюгтаНоп Пиегсвапее для обмена информацией
АТ&Т Атегсап Т@ерВопе апа Те!евгарВ Американский телефон и телеграф
(компания, которой принадлежала
торговая марка МХ)
ВСР — Вшагу Со4е4 ПОесипа] Двоично-десятичный формат
ВЮЗ Вазс шри/Ошриё Зужет Основная система ввода-вывода
ВГГ —Вшагу ей Двоичная цифра
ВРВ — В1О$ Рагатейег ВюсК Блок параметров ВТО$
(для блочных устройств)
ВЕМ В Кеа Моде Большой реальный режим
(то же, что и нереальный режим)
В$) Вегкаеу бу%ет Пузи1БиНоп Один из основных видов
ОМГХ-систем
В5$$ — Воск, Заке4 Бу ЗутБо! Участок программы, содержащий
неинициализированные данные
СМО5$ Сотр!етешагу Ме Ох!4е Комплементарные
Зеписопаисог металлооксидные пары
СОЕЕ Соттов Одес ЕЦе Еогтай Общий формат объектных файлов
СР. —Сштепё РиуЦерве Г.еуе] Текущий уровень привилегий
СВТ — Сафоде Кау Тие Электронно-лучевая трубка
РАС — Приаю Апаюв Сопуецег Цифро-аналоговый преобразователь
Орк —Онуегз Оеуеортепе КИ Набор для создания драйверов
ОМ. — ПупаписаЙу Сллкеа ГЛЬгагу Динамическая библиотека
ОМА Пес Метогу Ассезз Прямой доступ к памяти
00$ ПК Орегания Зует Дисковая операционная система
ОРГ. —ПОезсиреог РиуЦеве [леуе] Уровень привилегий дескриптора
596]
| | ||| АззетЫег для 00$, МИпдо\и и УМХ
ОРМТ ро$ Ргоеце4 Моде Пиегасе Интерфейс для защищенного режима
в РО$
О$Р Пека! $1па| Ргосеззог Процессор для оцифрованного звука
в звуковых картах
ОТА ПЕ ТгапзЕег Агеа Область передачи дисковых данных
(в 2О5$)
ЕТЕ — ЕхесшаЫе апа Глок Еогта* Формат исполняемых
и компонуемых файлов
ЕМ$ Ехрап4дед Метогу ресйсанол Спецификация доступа
к дополнительной памяти
ЕРВ — Ехесийоп Рвгат Воск Блок информации об исполняемой
программе
ЕАТ Ее АПосайоп Тае Таблица распределения файлов
ЕСК ЕО Сота Керлзег Регистр управления Е1ЕО
НЕО Ех Шш Еи$ Ощ Первый вошел — первый вышел
(очередь)
ЕМ Егедиепсу МодаНоп Частотный синтез
ЕРО — Ноаапя Рош Опи Блок для работы с числами
с плавающей запятой
СОТ —С]оБа Оезсиреог ТаЫе Глобальная таблица дескрипторов
НСГ Нитап Сотрщег Пуегасе Интерфейс между пользователем
и программой
НМА Не Метогу Агеа Верхняя область памяти
(64 Кб после первого мегабайта)
ВМ — шегпайопа] Виярез$ Мас тез Название компании
[С\ — Шиашайоп Сопего| \ога Управляющее слово инициализации
ШЕ — Шшергаед Опуе Вес готис$ Один из интерфейсов для жестких
дисков |
ШТ — Паеггаре Оезсир®ог ТаЫе Таблица дескрипторов обработчиков
прерываний
ТЕК — Пщеггаре ЕпаЫе Веззег Регистр разрешения прерываний
ТОСТЕ. при/Ошриш Сопёго| Управление вводом-выводом
ТОРГ. Тпри/ОибриЕ РиуЦеве Г.еуе! Уровень привилегий ввода-вывода
[ВО ‘мегаре Кедиез Запрос на прерывание
(от внешнего устройства)
[5Р Гиеггире Звания Ргобосо| Протокол разделения прерываний
СВ — Ипе Сопто] Вевязбег Регистр управления линией
ГОТ Гося Резсирог.ТаЫе Таблица локальных дескрипторов
ТЕ Гпеаг ЕхесшаЫе Линейный исполняемый формат
ТЕМ Гопв ЕЦе Мате Длинное имя файла
15В — пе Зфабиз Кезхег Регистр состояния линии
Используемые сокращения 1 ПИ ПО ООИЕСУ
МАЗМ Масго Аззетег Ассемблер компании М1сгозой
МСК Модет Сопго] Вензег Регистр управления модемом
ММХ Мшатеда Ежептзяоп Расширение для работы
с мультимедийными приложениями
М5В Модем Зе Вержег Регистр состояния модема
М$К —МасЬше Зресмйс Веяет Машинно-специфичный регистр
МЕ Ме\м ЕхесшаЫе Новый исполняемый формат
МРХ — Митенса| Ргосеззог Ежепя!юп Расширение для работы с числами
с плавающей запятой
ОСМ\М’ Орегайоп Сопёго] УУог4 Управляющее слово
(для контроллера прерываний)
РЕ РонаЫе ЕхесщаЫе Переносимый исполняемый формат
РОЗТ Ро\жег Оп Зе Тез Самотестирование при включении
РЭР Ргоргат Зевтень Ргейх Префикс программного сегмента
ВВК — Вечеуег ВиНег Везчег. Регистр буфера приемника
ВЕС — Кедаез Рог Соттепт6 Запрос для комментария
(форма публикации документов
в Ницегпеё, включая стандарты)
'ВЕМ Веа Её Моде Реальный Йа(-режим
(то же, что и нереальный режим)
ВТС Ве Типе С]оск Часы реального времени
ВРГ. —Ведиезог РиуЦере Тлеуе] Запрашиваемый уровень привилегий
КРМ — Веуегзе Роз Маайоп Обратная польская запись
(для арифметических выражений)
$С$Т Зта| Сотриег Зузет Пиегасе Один из интерфейсов для жестких
дисков
ЗУМ — Запюг4 Чшуегзиу МебуогК$ Название компании
ЗУСА Зирег УСА Любой видеоадаптер, способный
на режимы, большие 13Ъ
ТАЗМ Тиго АззетЫег Ассемблер компании Во[ап4
ТНЕ Тгапзпийег Но!её Веззег Регистр хранения передатчика
Т$В — Тегимаже ап вау Везет Завершиться и остаться резидентным
Т$$ — ТазК Земе Зертем Сегмент состояния задачи
ОМВ Оррег Метогу ВюсКк Блок верхней памяти
(между границами 640 Кб и 1 Мб)
УВЕ — УЕЗА ВОЗ Ежеряюп Спецификация УЕЗА
для расширения ВОЗ
УСРТ Уишиа! Сопёго! Рговгат Пиегасе Один из интерфейсов к защищенному
режиму для РОЗ
УЕЗА \У1ео Весгогис$ Збап4агА Ассоциация по стандартизации
Аззосайоп видео в электронике
[598 | |1 || А55етЫег для 00$, МИпо\ми$ и ОМХ
УСА — \4ео СгарЫсз Аггау Основной тип видеоадаптеров
Ухр Ушла Х Оеуке Виртуальное устройство Х.
(общее название виртуальных
/
драйверов в УЛп4о\$ 95)
У\МАЗМ Уакот АззетЫег Ассемблер компании У/асот
ХМ$ Ежепае4 Метогу ЗречйсаНоп Спецификация доступа
к расширенной памяти
Глоссарий
А
Активационная запись (асНуаНоп гесог4) — область стека, заполняемая при вы-
зове процедуры.
Ассемблер (аззету |априаве) — язык программирования низкого уровня.
Ассемблер (аззетЫег) — компилятор с языка ассемблера.
Б
Байт (Буе) — тип данных, имеющий размер 8 бит; минимальная адресуемая еди-
ница памяти.
Бит (516) — минимальная единица измерения информации.

Всплывающая программа (рорир ргоргат) — резидентная программа, активизи-


рующаяся по нажатию определенной «горячей» клавиши.
г
Горячая клавиша (роеу) — клавиша или комбинация клавиш, используемая не
для ввода символов, а для вызова программ и подобных необычных действий.

д
Двойное слово (доцЫе ога) - тип данных, имеющий размер 32 бита.
Дескриптор (Чезструог) — восьмибайтная структура, хранящаяся в одной из таб-
лиц СОТ, ГОТ или ГОТ и описывающая сегмент или шлюз.
Директива (Фгесиуе) — команда ассемблеру, которая не соответствует командам
`процессора. |
Драйвер (дпуег) - служебная программа, выполняющая функции посредника
между операционной системой и внешним устройством.
З
Задача ((25К) — программа, модуль или другой участок кода программы, который
можно запустить, выполнять, отложить и завершить.
Защищенный режим (ргобесе4 то4е) — режим процессора, в котором действуют
механизмы защиты, сегментная адресация с дескрипторами и селекторами и стра-
ничная адресация.
И
Идентификатор (рапе или еп йег) - число (если вап е) или переменная дру-
гого типа, используемая для идентификации того или иного ресурса.
600] | [||| Аз5етЫег для 20$, \Мтдоми$ и УМХ
Исключение (ехсерйоп) — событие, при котором выполнение программы прекра-
щается и управление передается обработчику исключения.
К
Код (со4е) - исполняемая часть программы (обычная программа состоит из кода,
данных и стека).
Компилятор (сотр!Иег) — программа, преобразующая текст, написанный на по-
нятном человеку языке программирования, в исполняемый файл.
Конвейер (р!ре) — последовательность блоков процессора, которая задействует-
ся при выполнении команды.
Конвенция (сопуепНоп) — договоренность о передаче параметров между проце-
дурами.
Конечный автомат (НпКе збабе тасЬше) — программа, которая может переклю-
чаться между различными состояниями и выполнять в разных состояниях раз-
ные действия.
Кэш (сасКе) — быстрая память, использующаяся для буферизации обращений к ос-
НОвНоЙ Памяти.

л
Лимит (|11110)— поле дескриптора (равно размеру сегмента минус 1).
Линейный адрес (Ппеаг а4гез$) — адрес, получаемый сложением смещения
и базы сегмента.
Ловушка (тар) — исключение, происходящее после вызвавшей его команды.

м
Метка (1аЪе]) — идентификатор, связанный с адресом в программе.

Н
Нить ((геа4) — процесс, данные и код которого совпадают с данными и кодом
других процессов.
Нереальный режим (ипгеа] то4е) — реальный режим с границами сегментов по 4 Гб.

о
Операнд (орегап4) — параметр, передаваемый команде процессора.
Описатель носителя (теа дезстрбог) — байт, используемый ОО для иденти-
фикации типа носителя (обычно не используется).
Останов (аБоге) —- исключение, происходящее асинхронно.
Отложенное вычисление (]а7у еуащайоп) — вычисление, которое выполняется,
только если реально требуется его результат.
Очередь предвыборки (рге{есВ диеце) — буфер, из которого команды передают-
ся на расшифровку и выполнение. |
Ошибка (116) — исключение, происходящее перед вызвавшей его командой.
Глоссарий = 1601
п
Пиксел (р:хе]) - минимальный элемент растрового изображения.
Повторная входимость (геепёгапсу) — возможность запуска процедуры из обра-
ботчика прерывания, прервавщего выполнение этой же процедуры.
Подчиненный сегмент (сопюгшше зевтепе) — сегмент, на который можно пере-
давать управление программам с более низким уровнем привилегий.
Прерывание (ищеггир() — сигнал от внешнего устройства. приводящий к преры-
ванию выполнения текущей программы и передаче управления специальной про-
грамме-обработчику (см. ловушка).
Р
Разворачивание циклов (1оор ипгоШп8) — превращение циклов, выполняющих-
ся известное число раз, в линейный участок кода.
Реальный режим (геа] то4е) — режим, в котором процессор ведет себя идентично
8086 — адресация не выше одного мегабайта памяти, размер всех сегментов огра-
ничен и равен 64 Кб, только 16-битный режим.
Резидентная программа (гез1ет ргоёгат) — программа, остающаяся в памяти
после возврата управления в РОЗ.

С
Сегмент (зевтелё) — элемент сегментной адресации в памяти или участок про-
граммы для РО$/\МЛиао\.
Секция (5есйоп) - участок программы для ОМХ.
Селектор (з@есфог) — число, хранящееся в сегментном регистре.
Скан-код (5сап-со4е) —- любой код, посылаемый клавиатурой.
Слово (\огА) — тип данных, имеющий размер 16 бит.
Смещение (оН5е() — относительный адрес, отсчитываемый от начала сегмента.
Стековый кадр ($асКк Нате) — область стека, занимаемая параметрами процеду-
ры, активационной записью и локальными переменными или только локальны-
ми переменными.
Страничная адресация (рартайоп) — механизм адресации, в котором линейное
адресное пространство разделяется на страницы, которые могут располагаться
в разных областях памяти или вообще отсутствовать.
т

Таблица переходов (литрёаЫе) — массив адресов процедур для косвенного пере-


хода на процедуру с известным номером. |
Ш
Шлюз (ва(е) — структура данных, позволяющая осуществлять передачу управле-
ния между разными уровнями привилегий в защищенном режиме.
Алфавитный указатель

А
Адресация Байт 15
косвенная 25 Байты состояния клавиатуры 149
с масштабированием 26 Бит 15
непосредственная 25 Блоки
по базе информации УВЕ 158
с индексированием 27 параметров РЗР 202
со сдвигом 26 параметров запускаемого файла 204
по смещению 25 Блоки повторений 123
полная форма 27 вИМХ 537
прямая 25 Буфер клавиатуры 150
регистровая 24 расширение при помощи драйвера 377
Активационные записи 219
дисплей 223
Ввод
стековый кадр 222 из стандартного устройства ввода 14]
Алгоритмы с клавиатуры 148
вывода на экран с помощью мыши 166
шестнадцатеричного числа 142 Видеопамять
генераторов случайных чисел 238
в $УСА-режимах 156
генерации пламени 406
в графических режимах 154
неупакованного ВСВ в АЗС! 201 в текстовом режиме 139 _
преобразования Видеорежимы
цифры в АЗСИ-код 39 ЗУСА 156
шестнадцатеричного числа УСА 151 `
в десятичное 201 Виртуальная память 511
рисования Виртуальные прерывания (в У86} 527
круга 164 Вложенные процедуры . 222
прямой линии 169 Время выполнения микроопераций 473
сортировки 242 Вывод
Ассемблер в стандартное устройство вывода 13]
директивы 106 на экран
макроопределения 121 в УСА-режимах 151
метки 106 в текстовом режиме 134, 139
модели памяти 112 Вычисления
операторы 120 с плавающей запятой 233
преимущества и недостатки 11 с повышенной точностью 225
процедуры 115 с фиксированной запятой 228
псевдокоманды 108 г
сегменты 110
структура программ 106 Генераторы случайных чисел 238
условное ассемблирование 118 вычитаниями 239
Атрибут символа 136 конгруэнтные 238
Алфавитный указатель
д ОН: (в МИпдоми 95/МТ) 451
Дата и время 172 ЕЕ 536
Дескрипторы 49] ЕХЕ (в 205} 130
сегмента данных или кода 389 РЕ (в У/таомз 95/МТ) 413
Джойстик 371 $5 (в 205} 374
Диалоги 431 Ухо (в МИпдомз 95) 457
Динамик 335 К
Динамические библиотеки 45]
Кластер 385
Директивы ассемблера
в ВО5/МИпаом $ 106 Кодировки 561
в ОМХ 534 Коды команд 567
Директории. 192 Командные параметры 208
Драйверы 374 Команды
Ухо 457 ААА 40
блочные 384 ААО 41
символьные 375 ААМ 40
з АА$ 40
АБС 34
Завершение программы 205
АБО 34
Задача 519
АВОР$ 94
Защита памяти 516
Защита страниц 519 АВО$$ 94
Защищенный режим 488 АМО 41
адресация 388 АМОМР$ 99
модель памяти 490 АМОР$ 99
селекторы 388 АВРЕ 484
средствами ОРМ! 394 ВОЦМО 52
средствами УСР! 391 В$Е 46
Звук ВУВ 46
без программирования ОМА 355 ВУМУАР 30
с программированием ОМА 361 ВТ 45
Звуковые платы 339 ВТС 46
и ВТК 46
Идентификация процессора 60 ВТ$ 46
Инициализация контроллера прерываний 369 САЦ 50
Интерфейс СВМ/ 32
ОРМ! СВО 32
вызов прерываний 397 СС 57
обработчики прерываний 398 СО 58
операции над дескрипторами 395 СН 59
передача управления между СИ$ 484
режимами 396 СМС 57
управление памятью 405 СМО\сс 28
УСРЕ 391 СМР 37
Исключения 245
СМРР$ 97
‚ РУ 67
55Е 105 СМР$ 55
в реальном режиме 249 СМР5$ 98
код ошибки 506 СМРХСНС 38
список и функции 506 СМРХУНСВВ 38
Исполняемые файлы 127 СРУЮ 60
СОЕЕ (в УМХ) 540 СОмМ!5$ 98
СОМ (в 905] 128 СУТ* 98
[604 |
ТТТ А5зетЫег для ОО$, МАпдо\ми5 и ИМХ
С\У/О 32 АМЗАУЕ 81
СУ/ОЕ 32 АМЗТСУУ 79
ОАА 38 АМУТЕМУ 80
РАЗ 39 АМ$ТЬУИ 82
ОЕС 37 ГРАТАМ 77
ОУ 36 ЕРКЕМ 73
ОИУР$ 95 ЕРКЕМТ 73
015$ 95 ЕРТАМ 77
ЕММ$ 90 РЕМЫМТ 73
ЕМТЕВ 52 РВЗТОК 81
ЕОХМТ 77 РАМЕ 81
РАВ 73 РЭСАЁЕ 73
РАОБОР 70 РМ 76
ЕВШ 69 РУМСО$ 76
ЕВУТР 69 РЗОКТ 74
ЕСН$ 73 ГУТ 69
РСШЕХ 79 РУТСМ/ 79
ЕСМО\Усс 70 ГЭТЕМУ 80
ЕСОМ 74 ЕЗТР 69
ЕСОМИ, 75 РУТУУУ 82
ЕСОМР 75 РОВ 71
ЕСОМР 74 РЗЦВР 71
ЕСОМРР 74 РЗУВК 71
ЕСО$ 76 РУОВЕР 71
РОЕСЗТР 79 ЕТЗТ 75
ЕОМ 72 РОСОМ 74
ЕОМР 72 РОСОМГ 75
ЕОМВ 72 РОСОМР 75
РОМАР 72 РОСОМР 74
ЕЕВЕЕ 79 РОСОМРР 74
ЛАОО 70
АМАГ 82
ЕХАМ 75
АСОМ 75
ЕХСН 70
АСОМР 75
ЕХКТОК 81, 103
НОМ 72
ГХЗАМЕ 81, 103
НОМК 72
РАВАСТ 74
НЕО 69
Р/.2Х 78
АМОЕ 71
РУЕ2ХР1 78
НМСУТР 78
НИ 486
НМИ 79
Юм 36
НТ 69 1МИЕ 35
НУТР 69
М 32
Н$ИВ 71 МС 37
АЗИВЮЕ 71 №5 56
ЕО 68 МТ 51
АО* 78 ИМТЗ 52
РОС\/ 80 МТО 52
НОЕМУ 81 ИМУО 485
ЕМУ 71. ИММРС 485
ЕМШР 71 ВЕТ 51
ЕМСЕХ 79 кс 48
АМИМИ 79 ХР 49
ЕМОР 82 ЗЕСХР 49
Алфавитный указатель 1605,
МР 47 ОК 41
1АНЕ 58 ОКР$ 100
[АВ 484 ОЧТ 32
(ОМХС$Е 103 ОЧТ$ 57
12$ 59 РАСК* 84
(ЕА 34 РАООБ* 85
[ЕАУЕ 53 РАМО 88
{Е$ 59 РАМОМ 88
15 59 РАУСВ 100
(СОТ 482 РАУСМ\М/ 100
[5$ 59 РСМР* 88
НОТ 483 РЕХТВУУ 100
ЦОТ 482 РАМУКУУ 100
[М5\/ 483 РМАВОМ/О 87
СК 60 РМАХЗМ/ 101
05$ 56 РМАХОВ 101
ЮОР 49 РМИМЫМУ/ 101
ЮОРЕ 50 РМИМИВ 101
{ООРМЕ 50 РМОУМЪЗКВ 101
[ООРМР 50 РМЦ 87
[ЮОРИ 50 РМУНИМУ 101
(5Ё 485 РОР 31
[$$ 59 РОК 88
ТВ 482 РОРА 31
МАЗКМОУ@ 104 РОРЕ 58
МАХРЗ 96 РВЕГЕТСН* 104
МАХ$$ 96 РЗАОБВУУ 102
МИМРЗ 97 РЗИ* 89
мм$$ 97 РЗВА* 89
МОЕРЗ 95 РЗК* 89
МО!$5 95 РЗУВ* 86
МОУ 28, 483 РИМРСК* 84
МО\УАР$ 93 РОЗН 30
МОУО 83 РИЗНА 31
МОУНЕР$ 93 РУЗНЕ 58
МОУНРЗ 93 РХОК 89
МОУМЬНР$ 93 КСЕ 44
МОМРЗ 93 ЮСРР$ 96
МОУМЗКР$ 94 КСР$$ 96
МОУМТР$ 104 ВСК 44
МОУМТО 104 ®ОМ$К 486
МОУСО 84 КОРМС 487
МО\$ 54 КОТ$С 486
МО\$$ 94 ВЕР 54
МО\У$Х 33 КЕРЕ 54
МОУЦРЗ 93 КЕРМЕ 54
МОУ7Х 33 КЕРМ7 54
МОИ 36 ВЕРУ 54
МЦР$ 95 ВЕТ 51
му$$ 95 ВЕТЕ 51
МЕС 37 ВЕТМ 51
МОР 59 КО 44
МОТ 42 КОК 44
6061 СТ АзбетЫег для 2О$, МУАпдоми$ и УМХ
В5М 486 в ЕХЕ-файл 131
В5ОКТРЗ 96 вИМХ 541
*
®5ОВТ5$ 96 драйверы для РОЗ 374
ЗАНЕ 58 графического приложения 415
ЗАЕ 43 с ресурсами 427
ЗАЕС 59 консольного приложения 416
ЗАВ 43 с использованием расширителей ВО 404
УВВ 35 Конвейеры исполнения команд 471
$СА$ 55 Конвенции передачи параметров
ЗЕТсс 46 С-конвенция 461
$СОТ 482 РАЗСА!-конвенция 460
УНЕ 43 смешанные 463
УНР 44 Конечные автоматы 214
УНК 43 Консольные приложения 416
УНАР 44 Контроллер
ЗНУЕР$ 102. ОМА 359
ЭНУАМ 102 прерываний 366
ОТ 483
ОТ 482 л
ЗМ$\М/ 484 Линейный кадровый буфер (1ЕВ} 155
ЗОКТР$ 95 Линия А20 493
$ОВТ$5 95 Логические операции 18
УТС 57
ТО 58 М
УП 59 Макроопределения 121
УТМХСУК 103 в ОМХ 538
510$ 56 Микрооперации 473
ТВ 483 Младший байт 16
ЗИВ 35 Младший бит 15
ИВР 94 Многозадачность 526
$4855 94 вВО5 298
ЭУЗЕМТЕК 487 Модели памяти 112
ЗУЗЕХИ 487 Модемы 179
ТЕЗТ 42 Мышь 166
иСОМ!$$ 98 Н
402 60
Насыщение 83
ОМРСКНР5 102
Нереальный режим 497
ИМРСКИР$ 102
Нитевая многозадачность 298
УЕВВ 485
\МЕРМУ 485 о
МАТ 82 Обратная польская нотация 234
УУНМУО 485 Окружение РОЗ 208
У/ВМ$Е 486 Операнды 24”
ХАВО 35 Операторы 120
хснс 30 в АТ&Т-ассемблерах 533
ЖАТ 33 Операционные системы
ХОК 42 005 127
ХОКР5 100 Ипих, РгевВЗО, Зо!ат$ 529
идентификация процессора 60 УИпаомз 95/МТ 413
расширение АМО ЗВ 90 Оптимизация
Компиляция / программ
в СОЕЁЕ-формат 540 высокоуровневая :465
в СОМ-файл 128 на среднем уровне 465
в И 452 низкоуровневая :468.`
в Е1Р-формат 539 циклов 466
Алфавитный указатель 1 607,
Организация Префиксы
задержек 174 1ОСК 60
памяти ВЕР 54
модели памяти 112 ВЕРЕ 54
порядок байтов 16 КЕРМЕ 54
сегменты 22 КЕРМИ 54
стек 22 КЕРР 54
Отладочные регистры 480 другие префиксы 571
Привилегировснчые комс-2> 518
п
Процедуры 216
Палитра УСА 328 Процессоры
Память Репнит Рго и Рептит # 472
ХМ$ 197 Реппит и Реппит ММАХ 471
выделение 194 Псевдокоманды определения донных 108
определение максимального блока 194 в ОМХ 534
освобождение 194 Р
Передача параметров
Расширения страничной адресации 510
в блоке параметров 220
Расширенные АЗС!-коды 565
в глобальных переменных 218
Расширители ОО$ 403
в потоке кода 220
Реальный режим 20
в регистрах 218
Регистры
в стеке 218
СВх 478
в языках высокого уровня 460 ОВх 480
отложенным вычислением 218 М$В 481
по возвращаемому значению 217 общего назначения 20
по значению 216 данных
по имени 217 ЕРИ 65
по результату 217 ммх 82
по ссылке 216 сегментные 22
Переключение слова состояния ЕР) 66
банков 155 слова управления ЕРУ 66
задач 521 управления памятью 477
Переменные среды 208 флаги СРИ 23
Повторная входимость Режимы Х 325
в ВОЗ 255 Режимы процессора
в 00$ 254 ВЕМ/ВЕМ 497
Полурезидентные программы 292 \86 527.
Порты защищенный 488
УСА ВАС 328 нереальный 497
\УСА-контроллер СКТ 320 реальный 20
УСА-синхронизатор 324 Резидентные программы 256
клавиатура 305 выгрузка из памяти 276
параллельный 181, 315 без РЭР 259
последовательный 179, 309 мультиплексорное прерывание 263
Предсказание переходов 475 пассивные и активные 256
Прерывания 245 повторная входимость 253
в ОРМГ 397 полурезидентные программы 292
в защищенном режиме 499 спецификация АМ!$ 263
инициализация контроллера 369 с
обработчики прерываний 246 Сегмент состояния задачи 519
отвнешних устройств 249 Сегментная адресация
разрешение и запрещение 59 в защищенном режиме 490
Префикс программного сегмента (РЗР} 202 Сегменты 110
608 ТИВ А$5етЫег для ОО$, МИпдо\м5 и ОМХ
Сектор 384 У
Секции 535 Управление задачами 519
Селекторы 388, 491 Управляющие регистры 478
Символы АЗСИ 18, 559 Управляющие символы АЗСИ 561
Система счисления Уровень вложенности 222
двоичная 14
Условные переходы 212
шестнадцатеричная 16
Устройства
Системные функции
видеосдаптеры УСА 316
№с 538
джойстик 371
ИМХ 540
\т32 414 динамик 335
Системный таймер запись в устройство 186
на уровне 805$ 171 звуковые платы 339
на уровне портов ввода-вывода 331 клавиатура 305
Скан-коды 148 контроллеры
Скорость выполнения команд 570 ОМА 359
Слово 16 прерываний 366
Сообщения (в \\тдо\з} 422 системный таймер 331
Сортировки
Ф
быстрая 242
пузырьковая 242 Файлы
выбором 244 запись 186
Старший байт 16 идентификатор 183
Старший бит 15 открытие 183
Статические ссылки 222 поиск 188
Стековый кадр 222 поиск с длинным именем 189
Страничная адресация 509 создание 183
защита при страничной адресации 519 удаление 187
расширения Репнит Рго 510 Флаги
т
системные 476
Таблица переходов 213 флаги состояния ЕРЦ 66
Таймер центрального процессора 23
на уровне ВОЗ 171 Функции
на уровне портов ввода-вывода 331 в ассемблере 216
Типы данных . системные
АЗ$С!-символы 18 НЬс 538
ММХ 83 мт32 414
упакованные байты 83 вИМХ 540
упакованные двойные слова 83
упакованные слова 83 Ц
учетверенное слово 83 Циклы
байт 15 РОК 215
бит 15 [ООР/ЕМОООР 215
вещественные числа РЕРЕАТ/УМИЕ 215
длинное 64 МИНИЕ 215
короткое 64 Ч
расширенное 64
специальные случаи 64 Часы реального времени
двоично-десятичные числа 38 на уровне ВЮ5 171
двойное слово 16 на уровне портов ввода-вывода 336
Числа
с фиксированной запятой 228
‘с плавающей запятой 233

Вам также может понравиться