Главная » Ассемблер, Железо » Использование счетчика тактов в качестве таймера

0

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

В литературе описана работа только с двумя самыми старыми типами таймеров: системным таймером и часами реального времени CMOS. Таймеры обоих типов не лишены определенных недостатков: • часы CMOS не позволяют измерять короткие интервалы времени и не всегда корректно вырабатывают прерывание;

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

Между тем современные процессоры типа Intel х86 содержат в своем составе гораздо более простое, точное и эффективное средство измерения времени — счетчик тактов (Time Stamp Counter). Указанный счетчик введен в состав процессоров: начиная с изделий класса Pentium, он присутствует во всех последующих модификациях процессоров Intel (и скопированных с них изделиях-клонах производства других фирм). Счетчик тактов входит в состав блока мониторинга производительности процессора вместе с несколькими другими специализированными счетчиками. Однако на данный момент из всех регистров блока мониторинга только счетчик тактов можно использовать без риска возникновения несовместимости с последующими моделями процессоров (структура счетчика проста и потому стабильна).

Счетчик тактов является 64-разрядным. Минимальный и максимальный измеряемые интервалы времени зависят от внутренней тактовой частоты процессора. Максимальный измеряемый период времени выбран с очень большим запасом — интервал 2е4 тактов даже при частоте 1 ГГц будет соответствовать периоду приблизительно в 585 лет.

Минимальный измеряемый интервал при внутренней частоте 100 МГц составляет 10 не, а при частоте 1 ГГц — 1 не. Поскольку этот интервал зависит от внутренней тактовой частоты процессора, необходимо провести калибровку таймера, построенного на базе счетчика тактов, по системным часам или часам CMOS. Системные часы (так же, как и часы CMOS) имеют свой собственный встроенный кварцевый генератор, они не зависят от частоты системной шины и внутренней частоты процессора, то есть выдают правильные показания даже в случае разгона системы.

Доступ к счетчику тактов контролируется флагом TSD в управляющем регистре CR4 процессора (если флаг сброшен, команда выполняется при любом уровне привилегий выполняемой программы, а если установлен — то только при уровне 0). Счетчик обнуляется в момент сброса процессора, после чего начинает подсчет тактов, прошедших с момента сброса. Прочитать содержимое счетчика тактов можно, используя команду RDTSC. После ее выполнения в регистре EDX будет размешена старшая часть, а в регистре ЕАХ — младшая часть значения, которое счетчик тактов содержал в момент выполнения команды. Таким образом, реализация программного таймера существенно упрощается — можно сразу выполнить операцию деления на 32-разрядный делитель (однако в этом случае значение делителя должно быть достаточно велико, чтобы не происходило переполнения, то есть частное не должно содержать более 32 двоичных разрядов).

Программа ProcFrequency, приведенная в листинге 2.7, использует счетчик тактов для измерения реальной внутренней тактовой частоты процессора. Вначале измеряется длительность (в тактах процессора) шестнадцати временных интервалов между отсчетами системного таймера, после чего вычисляется средняя длительность интервала. Полученное усредненное значение умножается на частоту тактового генератора системного таймера (1 193 180 Гц), а затем делится на коэффициент пересчета системного таймера (65 536). Результат нужно разделить на константу 1 ООО ООО, чтобы получить значение внутренней частоты процессора в мегагерцах. При выводе на экран полученного значения частоты используется процедура перевода целых чисел из двоичного кода в десятичный из листинга 2.5. Вспомогательная процедура WaitPimerStateChange выполняет Цикл опроса ячейки памяти области данных BIOS, которую системный таймер использует в качестве счетчика тактов (процедура ожидает изменения значения данного счетчика).

Листинг 2.7. Использование счетчика тактов для определения внутренней тактовой частоты процессора

IDEAL

Р386

LOCALS

MODEL MEDIUM

: Подключить файл мнемонических обозначений

; кодов управляющих клавиш и цветовых кодов

Include "listl_03.inc"

; Подключить файл иакросов

Include "listl_04.inc"

SEGMENT sseg para stack ‘STACK’

DB 400h DUP(?)

ENDS

Листинг 2.7 (продолжение) DATASEG

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

; Значение счетчика тактов в коиент времени tO TOCount DD ?

; Текстовые сообщения Text

DB LIGHTGREEN,0.20

DB "Определение тактовой частоты процессора",О

DB LIGHTGREEN,1,2В,"при понощи команды RDTSC",0

DB LIGHTMAGENTA.12.20

DB "Тактовая частота процессора (МГц):",О

DB LIGHTGREEN,24.35,"Ждите …",0 AnyK

DB YELLOW,24.29,"Нажмите любую клавишу",О ENDS

C0DESEG

• А1 А А’ A А А’А А А"А’ А’ А’ А A’ A’ А АА А А1 А’ А’ А А’ А’ ‘А’ А’ А Аг

;* Основной модуль программы *

• А’А’Аг"А’А А’А А’А’А’А’АгА" А А А’А А А А’А’А А’А’А’А’ А А’А’

PROC ProcFrequency

mov AX.DGROUP

mov DS, AX

mov [CS:Mai nDataSeg],AX : Установить текстовый режим и очистить экран

mov АХ ,3 int 10h

; Скрыть курсор – убрать за нижнюю границу экрана

mov [ScreenString],25

mov [ScreenCol umn],0 call SetCursorPosition

; Вывести текстовые сообщения на экран

MShowColorText 4,Text

; Использовать для вывода чисел белый цвет, черный фон

mov [TextColorAndBackground],WHITE

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

mov АХ,О

mov ES.AX

; Ожидание изиенения состояния тайнера

mov EAX,[ES:046Ch]

mov [Time],ЕАХ call WaitTimerStateChange

; Запомнить начальное значение счетчика тактов

DB 0Fh,31h ;команда RDTSC

mov [TOCount].ЕАХ

; Ожидать прохождения шестнадцати интервалов

mov СХ.16 @Pti: call WaitTimerStateChange

loop @Pti

; Запомнить начальное значение счетчика тактов

DB 0Fh,31h ;команда RDTSC : Вычислить среднюю длительность интервала sub ЕАХ.[TOCount] shr ЕАХ,4 ;деление на 16

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

; Умножить среднюю длительность интервала на

; частоту тактового генератора таймера

mov EDX,1193180 mul EDX

; Разделить результат на коэффициент

; пересчета системного таймера (65536) shrd ЕАХ,EDX,16

; Вычислить частоту в МГц (разделить на 1000000) xor EDX.EDX

mov EBX.1000000 div EBX

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

mov [Data_Int32],ЕАХ

mov [ScreenStnng],12

mov [ScreenColumn],55 call Int32_to_Stnng call ShowDataString

; Ожидать нажатия любой клавиши MShowColorString AnyK call GetChar

; Переустановить текстовый режим и очистить экран

mov АХ,3 int 10h

; Выход в DOS

mov AH,4Ch int 21h ENDP ProcFrequency

;* ОЖИДАНИЕ ОЧЕРЕДНОГО ИЗМЕНЕНИЯ ЗНАЧЕНИЯ ТАЙМЕРА *

PROC WaitTimerStateChange near

mov ЕАХ,[Time] PPT: cmp EAX,[ES:046Ch]

je PPT

mov EAX,[ES:046Ch]

mov [Time],EAX ret

ENDP WaitTimerStateChange ENDS

; Подключить процедуры вывода данных на экран

Include "listl_02.inc"

; Подключить процедуры перевода чисел

Include "list2 05.inc"

END

ВНИМАНИЕ

При выполнении компоновки примеров из данного раздела необходимо разрешить использование привилегированных команд процессора i386, то есть команду TLINK нужно запускать с ключом /3.

Например, ассемблирование и компоновка листинга 2.3 выполняются при помощи следующих команд:

tasm lst_2_03.asm tlink lst_2_03/3

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

ПРИМЕЧАНИЕ

Для запуска всех приведенных в данном разделе примеров, кроме последнего, достаточно иметь процессор уровня i486DX. Пример из листинга 2.7 может быть запущен только на процессоре класса Pentium, поскольку более ранние модификации не имели встроенного счетчика тактов.

Источник: Кулаков В. К90 Программирование на аппаратном уровне: специальный справочник (+дискета). 2-е издание. — СПб.: Питер, 2003. — 847 е.: ил.

По теме:

  • Комментарии