Ivan_32
25.03.2009, 04:14
Немного теории:
Многие программист С++/Delphi часто задавались вопросом определения частоты процессор, это может понадобится например для выскоточных пауз независимых от частоты процессора(для того и нужно определить частоту что б сделать нужно количество команд, которое будет выполнятся на всех процессорах одинаково количество времени).
У процессора много разных интересных железных штук есть и вот одна из них это TSC - TimeStampCounter. Счетчик сумарно выполненых тактов с последнего ресета процессора. Он представляет собой Квад-слово или 8 байт. Внимание:Нижние четыре байта - прямой источник псевдо-случайных чисел в большинстве алгоритмов рандома! Прочесть значение этих 8 байт можно командой RDTSC. У этой команды нет ни аргументо и даже ложить в регистры ничего не надо, перед вызовом. Вызываем и в регстрах EDX:EAX(Верхние 4 байта в EDX, нижние 4 байта в EAX) оказывается текущее значение TSC.
На заметку: счетчик этот так же позволяет посчитать сумарное количество секунд аптайма компьютера. Иными словами - сколько он находился без перезагрузки. TSC/Частота проца = время аптайма.
Пример реализации:
rdtsc ;Считываем текущее значение TSC.
mov [timerLo],eax ;Помещаем текущее значение TSC
mov [timerHi],edx ;в переменные.
invoke Sleep,100 ;Ждем 100 милисекунд.
rdtsc ;Опять считываем уже новое значение TSC.
sub eax,[timerLo] ;Вычитаем из него предыдущее.
sbb edx,[timerHi] ;значение.
mov ecx,10 ;интервал 100 милисекунд - надо умножить
mul ecx ;на 10 что бы получить сколько происходит
; тактов за секунду. 1000 милисек = 1 сек.
timerLo и timerHi это DWORD-ы. Синтаксис FASM.
Вот таким простым образом мы узнали частоту процессора. Погрешности конечно могут быть и даже будут, но они несущественные.
Как ни странно но определить марку и модель процессора еще проще чем частоту. Всю информацию нам предоставит команда CPUID.
В EAX нужно поместить код нужных данных(все они вшиты в ROM процессора.). Нас интересует функция 80000002h 80000003h и 80000004h. Эта команда возвращает данные во все регистры общего назначения - EAX EBX ECX EDX, причем именно в такой последовательности.
Пример реализации:
mov eax,80000002h
cpuid
mov dword[brand+0],eax
mov dword[brand+4],ebx
mov dword[brand+8],ecx
mov dword[brand+12],edx
mov eax,80000003h
cpuid
mov dword[brand+16],eax
mov dword[brand+20],ebx
mov dword[brand+24],ecx
mov dword[brand+28],edx
mov eax,80000004h
cpuid
mov dword[brand+32],eax
mov dword[brand+36],ebx
mov dword[brand+40],ecx
mov dword[brand+44],edx
brand - это массив байт заданный вот так:
brand db 80 dup(0)
Все три функции(80000002h , 80000003h и 80000004h) возвращают разные части одной общей строки в которой содержится основная информация о процессоре. Для примера вот мое тестовое приложение:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Приложу весь проект:
Dump.ru ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
Многие программист С++/Delphi часто задавались вопросом определения частоты процессор, это может понадобится например для выскоточных пауз независимых от частоты процессора(для того и нужно определить частоту что б сделать нужно количество команд, которое будет выполнятся на всех процессорах одинаково количество времени).
У процессора много разных интересных железных штук есть и вот одна из них это TSC - TimeStampCounter. Счетчик сумарно выполненых тактов с последнего ресета процессора. Он представляет собой Квад-слово или 8 байт. Внимание:Нижние четыре байта - прямой источник псевдо-случайных чисел в большинстве алгоритмов рандома! Прочесть значение этих 8 байт можно командой RDTSC. У этой команды нет ни аргументо и даже ложить в регистры ничего не надо, перед вызовом. Вызываем и в регстрах EDX:EAX(Верхние 4 байта в EDX, нижние 4 байта в EAX) оказывается текущее значение TSC.
На заметку: счетчик этот так же позволяет посчитать сумарное количество секунд аптайма компьютера. Иными словами - сколько он находился без перезагрузки. TSC/Частота проца = время аптайма.
Пример реализации:
rdtsc ;Считываем текущее значение TSC.
mov [timerLo],eax ;Помещаем текущее значение TSC
mov [timerHi],edx ;в переменные.
invoke Sleep,100 ;Ждем 100 милисекунд.
rdtsc ;Опять считываем уже новое значение TSC.
sub eax,[timerLo] ;Вычитаем из него предыдущее.
sbb edx,[timerHi] ;значение.
mov ecx,10 ;интервал 100 милисекунд - надо умножить
mul ecx ;на 10 что бы получить сколько происходит
; тактов за секунду. 1000 милисек = 1 сек.
timerLo и timerHi это DWORD-ы. Синтаксис FASM.
Вот таким простым образом мы узнали частоту процессора. Погрешности конечно могут быть и даже будут, но они несущественные.
Как ни странно но определить марку и модель процессора еще проще чем частоту. Всю информацию нам предоставит команда CPUID.
В EAX нужно поместить код нужных данных(все они вшиты в ROM процессора.). Нас интересует функция 80000002h 80000003h и 80000004h. Эта команда возвращает данные во все регистры общего назначения - EAX EBX ECX EDX, причем именно в такой последовательности.
Пример реализации:
mov eax,80000002h
cpuid
mov dword[brand+0],eax
mov dword[brand+4],ebx
mov dword[brand+8],ecx
mov dword[brand+12],edx
mov eax,80000003h
cpuid
mov dword[brand+16],eax
mov dword[brand+20],ebx
mov dword[brand+24],ecx
mov dword[brand+28],edx
mov eax,80000004h
cpuid
mov dword[brand+32],eax
mov dword[brand+36],ebx
mov dword[brand+40],ecx
mov dword[brand+44],edx
brand - это массив байт заданный вот так:
brand db 80 dup(0)
Все три функции(80000002h , 80000003h и 80000004h) возвращают разные части одной общей строки в которой содержится основная информация о процессоре. Для примера вот мое тестовое приложение:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Приложу весь проект:
Dump.ru ([Ссылки могут видеть только зарегистрированные и активированные пользователи])