Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Курсовой проект - RDTSC

.doc
Скачиваний:
84
Добавлен:
02.05.2014
Размер:
47.1 Кб
Скачать

З

3

АДАНИЕ

На языке ассемблера разработать программу определения внутренней тактовой частоты микропроцессора в МГц. Для подсчета количества тактов процессора применить команду RDTSC (код операции 0F31h).

РЕШЕНИЕ.

Команда RDTSC (Read Time Stamp Counter) - инструкция ассемблера для процессоров x86 читающая счетчик TSC и возвращающая в регистрах EDX:EAX 64-битное количество тактов, с момента последнего сброса процессора. Инструкция RDTSC поддерживается на платформе .386 и выше.

Надо решить, какой компилятор ассемблера выбрать для реализации этой задачи. Самые популярные из них: MASM, TASM, FASM, NASM. Данную задачу я буду писать на MASM32, как самом современном компиляторе ассемблера, на котором легко компилировать программы для Windows.

Теперь о структуре программы. Вот «скелет» стандартной программы, которая будет выводить всплывающее окно с каким-либо сообщением. В нашем случае во всплывающем окне будет выводиться сообщение о тактовой частоте процессора. Для вывода этого окна мы будем пользоваться функцией MessageBox:

.386

.model flat, stdcall

option casemap :none

include \MASM32\INCLUDE\windows.inc

include \MASM32\INCLUDE\masm32.inc

include \MASM32\INCLUDE\gdi32.inc

include \MASM32\INCLUDE\user32.inc

include \MASM32\INCLUDE\kernel32.inc

includelib \MASM32\LIB\masm32.lib

includelib \MASM32\LIB\gdi32.lib

includelib \MASM32\LIB\user32.lib

includelib \MASM32\LIB\kernel32.lib

.data

message db "поле сообщения",0 ;переменная с сообщением

mestitle db " заголовок окна ",0 ;переменная с заголовком

.code

start:

invoke MessageBox,0,ADDR message,ADDR mestitle,MB_OK ;выводим сообщение

invoke ExitProcess,0 ;завершаем программу

end start

.386 - это директива ассемблера, определяющая набор инструкций процессора, которые могут быть использованы в программе. По умолчанию транслятор полагает, что программа пишется для процессора 8086 и сопроцессора 8087. Для приложений win32 необходимо указывать либо .386, либо выше (486, 586, 686) - в зависимости от того, собираемся ли мы использовать возможности, предоставляемые процессорами (сопроцессорами) последующих поколений или нет.

.model flat, stdcall. Первый параметр - это модель памяти. Под Windows же у нас есть одна-единственная модель памяти - flat, позволяющая нашей программе благодаря страничной адресации легко и просто работать с 4 Гб виртуальной несегментированной памяти.

  Второй же параметр - stdcall - указывает на так называемое соглашение о вызове процедур. При программировании под win32 на макроассемблере нужно использовать соглашение stdcall.

.data – раздел, где объявляются переменные уже имеющие какое то значение, (инициализированные данные).

.code – раздел, где расположен код программы, то есть последовательность инструкций, которые должен выполнить компьютер.

Include – директива ассемблеру включить в текст программы, текст, хранящийся в указанном файле.

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

Invoke – команда, с помощью которой вызываются все API-функции. API-функции (Application Programming Interface — Интерфейс Программирования Приложений) обычно достаточно универсальны.

4

ОБЩИЙ ТЕКСТ ПРОГРАММЫ

.586

.model flat, stdcall

option casemap :none

include \MASM32\INCLUDE\windows.inc

include \MASM32\INCLUDE\kernel32.inc

include \MASM32\INCLUDE\shell32.inc

include \MASM32\INCLUDE\masm32.inc

include \masm32\include\user32.inc

includelib \MASM32\LIB\kernel32.lib

includelib \MASM32\LIB\shell32.lib

includelib \masm32\lib\user32.lib

.data

capt db "RDTSC",0 ;заголовок окна

digEAX dd ? ;переменная

buf1 dd ? ;символьная строка числа

frmt db "%u",0 ;выводим значение в десятичной системе

.code

start:

rdtsc ;инструкция Read Time-Stamp Counter, в результате выполнения этой инструкции в регистрах EDX:EAX будет содержаться 64-битное количество тактов с момента последнего сброса процессора

mov esi,eax;перешлем эти данные из EAX в ESI для сравнения

mov edi,edx;то же самое

push 1000 ;эти 3 строки обеспечивают

call Sleep ;задержку работы процессора

push 0 ;на 1 секунду

rdtsc ;опять считаем счетчик TSC, в нем будет на то количество тактов больше, сколько процессор успевает выдать за 1 секунду

cmp edx,edi;сравниваем содержимое двух регистров

jb start ;переход на метку start если содержимое esi как число превышает содержимое eax (переход через ноль)

sub eax,esi;из eax вычитаем esi и результат помещаем в eax, таким образом мы узнаем сколько тактов процессор сделал за секунду

sbb edx,edi;то же самое с младшей тетрадой

mov ebx,1000000;переводим из Гц в МГц

div ebx ; делим содержимое EAX на содержимое EBX и результат в EAX

mov digEAX,eax

i

5

nvoke wsprintf,addr buf1,addr frmt,digEAX;переводим число в символы

invoke MessageBox,0,addr buf1,addr capt,0;выводим этот символ в окно сообщения

push 0

call ExitProcess ;вызов процедуры конец процесса,процедура находится в одной из подключаемых библиотек

end start

6