Курсовая работа (т): Фиксация времени выполнения программ

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

DCycl: loop DCycl ;итерацийendp start

Текст второй программы:

.386

.model flat,stdcallcasemap:none\masm32\include\windows.inc\masm32\include\user32.inc\masm32\lib\user32.lib\masm32\include\kernel32.inc\masm32\lib\kernel32.lib\masm32\include\winmm.inc\masm32\lib\winmm.lib

;Прототипы некоторых функцийproto :DWORD,:DWORD,:DWORD,:DWORD         ;Гланая процедура

StrConv proto :DWORD       ;Конвертирование числа в строку

Delay proto          ;Задержкаproto

.DATAdb "SimpleWinClass",0        ;Имя класса окнаdb "QueryPerformenceCounter",0 ;Имя окна  db "╘шъёрЎш тЁхьхэш т√яюыэхэш яЁюуЁрьь√.",0        ;Строки текста,   db "QueryPerformenceCounter",0  ;выводимого в окнеS        db "┬Ёхь ёю ёЄрЁЄр Windows",0S db "┬Ёхь ёю ёЄрЁЄр яЁюуЁрьь√",0

Time3S db "┬Ёхь Ўшъыр",0          db " ",0 ;Строка, в которую записывается

;число при конвертированииDWORD 0;         ;Время старта программы  DWORD 0;      ;Время выполнения предыдущего цикла       DWORD 0;          ;Временная переменная.

.DATA?     ; Hеиницилизиpуемые данныеHINSTANCE ?          ; Хэндл нашей пpогpаммыLPSTR ? ; Командная строка

;---------------------------------------------------------------------------

;Кодовый сегмент-

;----------------

.CODE                ; Сегмент кода:GetModuleHandle, NULL         ;Взять хэндл пpогpаммы

mov hInstance,eax

invoke GetCommandLine      ;Взять командную стpоку.CommandLine,eax

;вызвать основную функцию

invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULTExitProcess, eax ; Выйти из пpогpаммы.

;---------------------------------------------------------------------------

;Основной цикл программы-

;------------------------proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORDwc:WNDCLASSEX ;Класс окнаmsg:MSG            ;Сообщениеhwnd:HWND ;Хэндл окнаMyTimer       ;Получаем время старта программы

mov  StartT,eax  ;и запоминаем его        LastT,eax   wc.cbSize,SIZEOF WNDCLASSEX                    ;заполнение стpуктуpы

mov wc.style, CS_HREDRAW or CS_VREDRAW  ;класса окна

mov wc.lpfnWndProc, OFFSET WndProc

mov wc.cbClsExtra,NULL

mov wc.cbWndExtra,NULL hInstance    wc.hInstance         wc.hbrBackground,COLOR_WINDOW+1        wc.lpszMenuName,NULL         wc.lpszClassName,OFFSET ClassNameLoadIcon,NULL,IDI_APPLICATION         wc.hIcon,eax        wc.hIconSm,eaxLoadCursor,NULL,IDC_ARROW         wc.hCursor,eaxRegisterClassEx, addr wc                   ;pегистpация класса окнаCreateWindowEx,NULL,\ClassName,\AppName,\_OVERLAPPEDWINDOW,\_USEDEFAULT,\_USEDEFAULT,\

,\

,\,\,\,\ hwnd,eaxShowWindow, hwnd,CmdShow         ;отобpазить окно

invoke UpdateWindow, hwnd                  ;обновить клиентскую область

.BREAK .IF (!eax) ;выходTranslateMessage, ADDR msg ;трансляцияDispatchMessage, ADDR msg ;сообщенияDelay ;задержкаInvalidateRect, hwnd, 0, TRUE        ;обновление окна

.ENDWeax,msg.wParam ;передаем код окончания

WinMain endp

;-----------------------------

;Оконная процедура-

;------------------proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

LOCAL hdc:HDC ;контекст экрана

LOCAL ps:PAINTSTRUCT  ;структура рисования

LOCAL rect:RECT ;прямоугольник вывода текстаTime:DWORD       ;Текущее времяFStT:DWORD    ;Время со старта программыDeltaT:DWORD ;Время одного цикла

.IF uMsg==WM_DESTROY ;Закрыть окноPostQuitMessage,NULL

.ELSEIF uMsg==WM_PAINT        ;Нарисовать содержимоеBeginPaint,hWnd, ADDR ps      ;получить дескриптор

mov hdc,eax        rect.left,10  ;Устанавливаем область      rect.right,400 ;вывода текста         rect.top,0    rect.bottom,300

;----------------------------

;Выводим простые строки

invoke DrawText, hdc,ADDR Str1,-1, ADDR rect, DT_SINGLELINE         rect.top,16DrawText, hdc,ADDR Str2,-1, ADDR rect, DT_SINGLELINE         rect.top,32DrawText, hdc,ADDR Time1S,-1, ADDR rect, DT_SINGLELINE         rect.top,48DrawText, hdc,ADDR Time2S,-1, ADDR rect, DT_SINGLELINE         rect.top,64DrawText, hdc,ADDR Time3S,-1, ADDR rect, DT_SINGLELINEMyTimer         ;Получаем текущее время    Time,eax

mov  rect.top,32  ;переходим на второй столбец      rect.left,250StrConv, Time         ;конвертируем и выводим время

invoke DrawText, hdc,ADDR OutStr,-1, ADDR rect, DT_SINGLELINE

mov  eax,Time    ;Вычисляем время со старта ebx,StartT  ;для этого вычитаем из времени со eax,ebx                ;старта Windows время старта      FStT,eax    ;программы         rect.top,48StrConv, FStT      ;конвертируем и выводим время

invoke DrawText, hdc,ADDR OutStr,-1, ADDR rect, DT_SINGLELINE

mov  eax,Time    ;Вычисляем длительность одного цикла         ebx,LastT   ;для этого вычитаем из времени со       eax,ebx                ;старта Windows время         FStT,eax         ;предыдущего цикла   rect.top,64

invoke StrConv, FStTDrawText, hdc,ADDR OutStr,-1, ADDR rect, DT_SINGLELINE         eax,Time;   LastT,eax   ;Сохраняем время текущего циклаEndPaint,hWnd, ADDR ps

.ELSEDefWindowProc,hWnd,uMsg,wParam,lParam

.ENDIFeax, eax

WndProc endp

;-------------------------------

;Конвертирование числа в строку-

;-------------------------------proc Chislo:DWORD   ebx, 7                   ;заносим счетчик символов   eax, Chislo ;конвертируемое число         ecx, 8                   ;счетчик итераций:         edx,eax ;копируем текущее число  eax,4          ;Смещаем число edx,15;; Выделяем младшую цифру edx,48 ;Переводим в ASCII  edx,57 ;Если цифра больше 9        NoA  edx,7         ;то корректируем символ:    OutStr[ebx],dl     ;Записываем символ    ebx             ;Смещаем счетчикFCiclendp

;------------------------------

;Процедура задержки-

;-------------------proc                         ;Простой циклecx,4000000            ;на большое количество

DCycl: loop DCycl                 ;итерацийendp

;------------------------------

;Процедура таймера

;------------------procTimeH:DWORDTimeL:DWORDFrecH:DWORDFrecL:DWORDQueryPerformanceFrequency, ADDR FrecLQueryPerformanceCounter, ADDR TimeL      ebx,FrecL   ;Заполняем регистры перед делением   ecx,FrecH   ;Frquency   ebx,10        edx,TimeH ;Время       eax,TimeL

pushad

; деление 64-битного числа в EDX:EAX на 64-битное число в ЕСХ:ЕВХ.

; Частное помещается в EDX:EAX, и остаток - в ESI:EDIebp,64 ; счетчик битesi,esi

xor edi,edi ; остаток = 0:

shl eax,1edx,1edi,1 ; сдвиг на 1 бит влево 128-битного числа

rcl esi,1 ; ESI:EDI:EDX:EAX

cmp esi,ecx ; сравнить старшие двойные словаdividenextedi,ebx ; сравнить младшие двойные слова

jb next:edi,ebxesi,ecx ; ESI:EDI = EBX:ECX

inc eax ; установить младший бит в ЕАХ:ebp ; повторить цикл 64 раза

jne bitloop  Temp,eax   eax,Tempendp

end start

Результаты работы программ:

Рис.

Рис.

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

Вывод

В ходе курсовой работы были разобраны основные методы измерения интервалов времени на PC. Были показаны основные аппаратные и программные реализации решения рассматриваемой задачи. Составлены две программы на языке ассемблера для 32 разрядных микропроцессоров семейства Intel, демонстрирующие методы измерения времени и показывающие отличия методов для Windows. К сожалению операционная система Windows не позволяет измерять время с точностью существенно превышающей 1 миллисекунду, что является внутренним ограничением архитектуры системы.

Источник: https://www.bibliofond.ru/detail.aspx?id=725371