Материал: Системное программирование

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Возможный вариант программы, реализующей алгоритм вычислений, представлен ниже.

IDEAL

.386

MODEL MEDIUM

STACK 100h

DATASEG

; Массив для хранения значений отсчетов счетчика

; тактов в моменты срабатывания системного таймера

TimeCounter DD 33 DUP(?)

; Разность между соседними замерами

DeltaT DD 32 DUP(?)

; Среднее значение длительности интервала

AverageTime DD ?

; Предыдущее значение системного таймера

Time DD ?

; Результат вычислений

FreqResultDD?

ENDS

CODESEG

PROC ProcFrequency

; Настроить регистр DS на глобальный сегмент данных

MOV AX, DGROUP

MOV DS, AX

; Настроить сегментный регистр ES на область данных BIOS

MOVAX, 0

MOVES,AX

; Инициализация начальных параметров

MOV BX, 33

MOV DI, OFFSET TimeCounter

; Текущее время, выраженное в 1/18.2 долях секунды

MOV EAX, [ES:046Ch]

MOV [Time], EAX

; Сохранение значений счетчика TSCкаждые 1/18.2 сек

@@t0:CALLWaitTimerStateChange

; Выполнить команду RDTSC

DB0Fh, 31h

; Сохранить значение в массиве

MOV[DI],EAX

; Переход к следующему элементу массива

ADDDI, 4

DECBX

; Число замеров равно 33

JNZ@@t0

; Вычислить длительность каждого интервала в тактах

MOV BX, 32

MOV DI, OFFSET TimeCounter

MOV SI, OFFSET DeltaT

MOV EDX, 0

; Из значения счетчика в момент t+1 вычесть значение в момент t

@@t1:MOV EAX, [DI+4]

SUB EAX, [DI]

MOV[SI],EAX

; Накопление суммы значений

ADDEDX, EAX

; Индексирование массивов

ADDDI, 4

ADD SI, 4

DEC BX

JNZ @@t1

; Вычислить среднюю длительность интервала в тактах

SHREDX, 5

MOV[AverageTime],EDX

; Умножить среднее значение на частоту генератора

MOV EAX, [AverageTime]

MOV EDX, 1193180

MULEDX

; Разделить результат на делитель таймера (65536)

SHRDEAX, EDX, 16

; Вычислить частоту микропроцессора в МГц

XOREDX,EDX

; Разделить результат на 106

MOVEBX, 1000000

DIVEBX

; Сохранить результат вычислений

MOV [FreqResult],EAX

; Выход в MS DOS

MOV AX, 4C00h

INT 21h

ENDP ProcFrequency

; Процедура ожидания очередного изменения значения таймера

PROC WaitTimerStateChange NEAR

MOV EAX, [Time]

; Цикл до тех пор, пока текущее значение времени

; не будет отличаться от ранее сохраненного значения

@@T: CMP EAX, [ES:046Ch]

JE@@T

; Сохранить новое значение времени

MOV EAX,[ES:046Ch]

MOV [Time], EAX

RET

ENDP WaitTimerStateChange

ENDS

END

Пример 3. Разработать подпрограмму, организующую задержку на заданный временной интервал. Минимальный временной интервал может быть меньше периода следования импульсов от системных часов.

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

Самый простой способ организовать задержку – определить пустой цикл. В этом случае может потребоваться достаточно много времени для того, чтобы добиться нужного времени задержки. Однако даже если и удастся определить тре­буемую длительность, нельзя быть уверенным, что программа будет давать нужное время задержки при всех условиях. Длительность цикла может меняться в зависимости от используемого компилятора, скорости процессора и других факторов.

Даже цикл на языке ассемблера может приводить к различным време­нам задержки. Поэтому разумно определять время программной задержки непосредственно по часам. Частота отсчета в 18.2 Гц, используемая в модификации счетчика времени суток, должна вполне удовлетворять большинство потребностей.

Чтобы обеспечить задержку заданной продолжительности, программа должна подсчитать требуемое число импульсов счетчика времени суток. Значение добавляется к считанному текущему значению счетчика. Затем программа постоянно считывает текущее значение счетчика и сравнивает его с запомненным значением. Когда достигается равенство, то считается, что требуемая задержка прошла. Значение счетчика времени суток хранится по адресу 0040:006Ch.

Более высокую дискретность отсчетов, требуемую по условиям задачи, можно достичь, воспользовавшись счетчиком тактовых импульсов TSC. Однако в этом случае требуется предварительная калибровка таймера. Первым шагом алгоритма будет вычисление среднего числа тактов за период системного таймера и расчет продолжительности одного такта (см. задачу 2).

Дело в том, что использование паспортных данных процессора приведет к неточности, т.к. всегда имеется некоторый технологический разброс значений параметра. Лучший выход в данной ситуации – определение значения экспериментальным путем. Далее применим адаптированный для счетчика TSC приведенный выше алгоритм. Описанные алгоритмы организации временных задержек реализуйте самостоятельно на языке ассемблера, используя TASM.

Контрольные вопросы

  1. Приведите общую структуру таймера-счетчика и его назначение.

  2. Перечислите режимы работы таймера-счетчика.

  3. Опишите структуру регистров таймера-счетчика.

11. Программирование контроллера прерываний

11.1. Механизм обработки прерываний

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

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

  • Путем создания системной очереди на обслуживание. Такой подход предполагает некую очередь, в которую выстраиваются запросы на обслуживание от устройств. Микропроцессор периодически просматривает очередь и выполняет обслуживание запросов.

  • На основе механизма прерывания, который позволяет обеспечить наиболее эффективное управление внешними устройствами и программами.

Цифровые устройства, построенные на основе архитектуры IBM PC, используют механизм прерываний. Прерывания приостанавливают выполнение программы для выполнения специальных системных действий. Необходимость прерываний обусловлено двумя причинами: преднамеренный запрос на выполнение операций ввода-вывода на различные внешние устройства и обработка непредвиденных программных ошибок.

Обработка прерываний микропроцессором производится в три этапа:

  • прерывание выполнения текущей программы;

  • переход к выполнению подпрограммы обработки прерывания;

  • возврат управления прерванной программе.

Любая программа, загруженная на выполнение, занимает в памяти отдельное от других программ адресное пространство. Регистры являются разделяемыми ресурсами для микропроцессора, поэтому их содержимое нужно сохранять при переключении задач. Закончив выполнение инструкции, в ходе которого возник запрос на прерывание, в стеке сохраняется содержимое регистра флагов и регистровой пары CS:IP.

В регистре флагов сбрасываются флаги разрешения прерывания IF и трассировки TF. Этим обеспечивается блокировка возникновения новых маскируемых внешних прерываний (см. раздел 2.2) и запрещаются пошаговые прерывания по выполнении каждой инструкции.

Затем в регистровую пару CS:IP загружается адрес подпрограммы обработки прерывания ISR (Interrupt Subroutine), которой и передается управление. Адреса подпрограмм прерываний называют векторами, а их совокупность – таблицей векторов прерываний IVT (Interrupt Vector Table).

Каждый вектор размещается в 4 байтах. Старшее слово адреса содержит значение сегмента CS, младшее – смещение IP. Первые 1024 байта оперативной памяти содержат векторы прерываний. Всего доступно 256 векторов. Вектор для прерывания 0 начинается с ячейки памяти 0000:0000, для прерывания 1 – с ячейки 0000:0004, 2 – с ячейки 0000:0008 и т.д. Каждый элемент таблицы указывает на подпрограмму обработки указанного типа прерывания. В табл. 91 описаны вектора таблицы прерываний.

После выполнения подпрограммы обработки прерывания следует восстановить состояния прерванной программы. Для этого всегда последней командой подпрограммы обработки прерывания указывается машинная команда IRET. По этой команде микропроцессор извлекает из стека последовательно три слова и помещает их, соответственно в регистры IP, CS и регистр флагов.

В результате после выполнения подпрограммы обработки прерываний регистровая пара CS:IP будет содержать адрес следующей команды прерванной программы, а регистр флагов – состояние флагов на момент передачи управления ISR.

Табл. 91. Основные прерывания таблицы векторов.

Номер

Описание

0

Ошибка деления. Вызывается автоматически после выполнения команд DIV или IDIV, если в результате деления происходит переполнение (например, при делении на 0). Обработчик DOS выводит сообщение об ошибке и останавливает выполнение программы. При этом для процессора 8086 адрес возврата указывает на следующую после команды деления команду, а в процессоре 80286 – на первый байт команды, вызвавшей прерывание.

1

Прерывание пошагового режима. Вырабатывается после выполнения

очередной машинной команды, если в слове флагов установлен бит

пошаговой трассировки TF. Используется для отладки.

2

Аппаратное немаскируемое прерывание. Обычно вырабатывается при ошибке

четности в оперативной памяти и при запросе прерывания от сопроцессора.

3

Прерывание для трассировки. Генерируется при выполнении

однобайтовой машинной команды с кодом CCh и обычно используется

отладчиками для установки точки прерывания.

4

Переполнение. Прерывание используется для обработки

ошибок при выполнении арифметических операций.

5

Печать копии экрана. Генерируется при нажатии на клавишу PrtScr.

6

Неопределенный код операции или длина

команды больше 10 байт (для процессора 80286).

7

Особый случай отсутствия математического сопроцессора (процессор 80286).

8

IRQ0 - прерывание таймера, возникает 18,2 раза в секунду.

9

IRQ1 - прерывание от клавиатуры. Генерируется при нажатии и при

отпускании клавиши. Используется для чтения данных от клавиатуры.

A

IRQ2 - каскадирование аппаратных прерываний в машинах класса AT.

B

IRQ3 - прерывание асинхронного порта COM2.

C

IRQ4 - прерывание асинхронного порта COM1.

D

IRQ5 - прерывание от контроллера жесткого диска для XT.

E

IRQ6 - прерывание контроллера флоппи-диска после завершения операции.

F

IRQ7 - прерывание принтера. Генерируется принтером,

когда он готов к выполнению очередной операции.

10

Обслуживание видеоадаптера.

11

Определение конфигурации устройств в системе.

12

Определение размера оперативной памяти в системе.

13

Обслуживание дисковой системы.

14

Последовательный ввод/вывод.

15

Расширенный сервис для AT-компьютеров.

16

Обслуживание клавиатуры.

17

Обслуживание принтера.

18

Запуск BASIC в ПЗУ (если есть).

19

Загрузка операционной системы.

1A

Обслуживание часов.

1B

Обработчик прерывания Ctrl-Break.

1C

Прерывание возникает с частотой 18.2 Гц и вызывается

программно обработчиком прерывания таймера.

1D

Адрес видеотаблицы для контроллера видеоадаптера 6845.

1E

Указатель на таблицу параметров дискеты.

1F

Указатель на графическую таблицу для символов с кодами ASCII 128-255.

20-5F

Зарезервировано для DOS.

60-67

Прерывания, зарезервированные для пользователя.

68-6F

Не используются.

70

IRQ8 - прерывание от часов реального времени.

71

IRQ9 - прерывание от контроллера EGA.

72

IRQ10 - зарезервировано.

73

IRQ11 - зарезервировано.

74

IRQ12 - зарезервировано.

75

IRQ13 - прерывание от математического сопроцессора.

76

IRQ14 - прерывание от контроллера жесткого диска.

77

IRQ15 - зарезервировано.

78-7F

Не используются.

80-85

Зарезервированы для BASIC.

86-F0

Используются интерпретатором BASIC (если есть).

F1-FF

Не используются.

Источник: https://files.student-it.ru/previewfile/284711