
- •140010, Г. Люберцы, Московской обл., Октябрьский пр-т, 403.
- •Глава 1. Архитектура реального режима
- •1.1. Память и процессор
- •Глава 1
- •Глава 1
- •1.2. Распределение адресного пространства
- •Глава 1
- •1.3. Регистры процессора
- •Глава 1
- •Глава 1
- •9 7H Шестнадцатернчное обозначение числа
- •Глава 1
- •1.4. Сегментная структура программ
- •Глава 1
- •Глава 1
- •Глава 1
- •1.5. Стек
- •Глава 1
- •1.6. Система прерываний
- •Глава 1
- •Глава I
- •1.7. Система ввода-вывода
- •Глава I
- •Глава 1
- •Глава 2. Основы программирования
- •2.1. Подготовка и отладка программы
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •2.2. Представление данных
- •Глава 2
- •Глава 2
- •2.3. Описание данных
- •Глава 2
- •Глава 2
- •2.4. Структуры и записи
- •Глава 2
- •Глава 2
- •2.5. Способы адресации
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •2.7. Вызовы подпрограмм
- •Глава 2
- •2.8. Макросредства ассемблера
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 3. Команды и алгоритмы
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •3.2. Циклы и условные переходы
- •Глава 3
- •Глава 3
- •3.3. Обработка строк
- •Глава 3
- •3.4. Использование подпрограмм
- •Глава 3
- •Глава 3
- •3.5. Двоично-десятичные числа
- •Глава 3
- •Глава 3
- •3.6. Программирование аппаратных средств
- •Глава 3
- •37Ah Порт управлсш!я
- •Глава 3
- •Глава 3
- •Глава 4. Расширенные возможности
- •4.1. Архитектурные особенности
- •Глава 4
- •4.2. Дополнительные режимы адресации
- •Глава 4
- •4.3. Использование средств 32-разрядных процессоров в программировании
- •Глава 4
- •Глава 4
- •Глава 4
- •4.4. Основы защищенного режима
- •Глава 4
- •Глава 4
- •Глава 4
- •Глава 4
- •Idiv Деление целых чисел со знаком
- •Imul Умножение целых чисел со знаком
- •In Ввод из порта
- •Inc Инкремент (увеличение на 1)
- •Int Программное прерывание
- •Into Прерывание по переполнению
- •Iret Возврат из прерывания
- •1 Lods Загрузка операнда из строки : lodsb Загрузка байта из строки lodsw Загрузка слова из строки
- •Операнд
- •Xadd память, регистр
- •Xchg Обмен данными между операндами
- •Xlat Табличная трансляция
- •Xor Логическое исключающее или
- •Содержание
3.5. Двоично-десятичные числа
В гл. 2 уже говорилось о двоично-десятичных числах — специальном формате хранения данных, используемом в ряде технических приложе-;-ний. Часто эти числа называют BCD-числами (от binary-coded decimal, 'двоично-кодированные десятичные числа). Для обработки BCD-чисел (сло-^жения, вычитания, умножения и деления) в МП 86 предусмотрены специальные команды. Рассмотрим этот вопрос на комплексном примере • обработки показаний КМОП-часов реального времени.
140 Главаз
Как известно, в современных компьютеров имеются два независимых таймера. Один из них («часы реального времени») включен в состав микросхемы с очень низким потреблением тока, питается от батарейки или аккумулятора, находящегося на системной плате, и работает даже на выключенной из сети машине. В этом таймере хранится и автоматически наращивается текущее календарное время (год, месяц, день, час, минута и секунда).
После включения компьютера вступает в работу другой таймер, который обычно называют системным. Датчиком сигналов времени для него служит кварцевый генератор, работающий на частоте 1,19318 МГц; сигналы от которого, после пересчета в отношении 65536:1, поступают в контроллер прерываний и инициируют прерывания через вектор 8 с частотой 18,2065 Гц. Эти прерывания активизируют программу BIOS, периодически выполняющую инкремент содержимого четырехбайтовой ячейки памяти с текущим временем, находящейся по адресу 46Ch. После включения машины программы BIOS считывают из часов реального времени текущее время суток, преобразуют его в число тактов системного таймера (т.е. в число интервалов по 1/18,2065 с) и записывают в ячейку текущего времени. Далее содержимое этой ячейки наращивается уже системным таймером, работающим в режиме прерываний.
Для определения текущего времени прикладная программа может вызвать соответствующие функции прерывания 21h DOS (конкретно, с номером 2Ah для получения даты и 2Ch для получения времени суток), а может прочитать время непосредственно из часов реального времени с помощью прерывания lAli BIOS. При этом прерывание lAli позволяет, помимо чтения текущего времени (функция 02h) и текущей даты (функция 04h), выполнять и целый ряд других функций, среди которых мы отметим только возможность установить «будильник», т.е. записать в микросхему часов значение календарного времени, когда часы должны выдать сигнал аппаратного прерывания. Этот сигнал через вектор 70h инициирует обработчик прерываний, входящий в состав BIOS, который проверяет, возникло ли данное прерывание в результате достижения времени установки будильника (часы реального времени могут инициировать прерывания и по других причинам), тестирует заодно батарейное питание микросхемы, а затем посылает в оба контроллера прерываний команды конца прерываний и завершается командой iret. Однако по ходу своего выполнения обработчик прерывания 70U выполняет команду int 4Ah, которая передает управление на обработчик этого прерывания, тоже входящий в состав BIOS. Системный обработчик прерывания 4Ali ничего особенно полезного не делает, в сущности представляя собой просто программу-заглушку. Однако программист имеет возможность записать в вектор 4Ali адрес прикладного обработчика прерываний, который будет активизироваться прерыванием будильника. Функции прикладного обработчика определяет программист.
В примере 3-9 устанавливается прикладной обработчик прерывания 4AU, который сам по себе вызваться никогда не будет, так как по умолчанию будильник часов реального не работает. Если, однако, прочитать си-
Команды и алгоритмы 141
схемное время с помощью функции 02U прерывания 1АИ, прибавить к нем>' некоторую величину, например, 1 секунду, и установить будильник на это время {с помощью функции 06h прерывания lAli), то через одну секунду будет активизирован наш обработчик. В примере 3-9 этот процесс сделан бесконечным: в обработчике прерываний будильника снова выполняется чтение времени,'прибавление к нему 1 секунды и установка будильника на новое время. В результате наш обработчик будет вызываться каждую секунду до завершения всей программы.
Помимо служебной функции установки будильника на следующую секунду, обработчик прерываний выполняет и полезную работу: он выводит текущее время в определенное место экрана. Поскольку обработчик активизируется каждую секунду, выводимое значение времени будет обновляться каждую секунду.
Как уже говорилось, в часах реального времени значение времени хранится в упакованных двоично-десятичных чисел. При выполнении арифметических операций с числами BCD (а нашем случае операции заключаются в прибаштении 1) необходимо использовать предназначенные для этого команды процессора. В примере проиллюстрировано использование одной из этих команд, конкретно, команды daa.
Для того, чтобы вывести на экран значение времени, его надо преобразовать в последовательность кодов ASCII. Процедура преобразования упакованных двоично-десятичных чисел в строку символов также вклю-в рассматриваемый пример. .
;Пример 3-9. Чтение и обработка показаний часов
;реального времени
.586 ;Будут использоваться дополнительные команды
assume CS:code,DS:data
code segment use!6
main proc
mov AX.data ;Настроим DS наш
mov DS,AX ;сегмент данных
;Сохраним исходный вектор 4Ah
mov AX,354Ah
int 2 In
mov word ptr old_4a,BX
mov word ptr old_4a+2,ES ;Установим наш обработчик прерывания 4Ah
mov AX,254Ah
push DS ;Сохраним DS
push CS ;Настроим DS на сегмент
pop DS ;команд
mov DX,offset new_4a;DS:DX->new_4a
int 21h
pop DS восстановим DS
;Установим будильник
142