МІНІСТЕРСТВО ОСВІТИ І НАУКИ, МОЛОДІ ТА СПОРТУ УКРАЇНИ
Національний університет «Львівська політехніка»
ІЕПТ ім. В’ячеслава Чорновола
Кафедра загальної екології та
екоінформаційних систем
ЗВІТ
по лабораторній роботі №2
на тему:
“Cтруктури даних для використання системних функцій”
Львів – 2012
Мета – навчитися будувати структури даних для використання функцій Win32 API при програмуванні в операційній системі Windows.
ТЕОРЕТИЧНІ ПОЛОЖЕННЯ
Для використання більш складних функцій API необхідно використовувати спеціальні структури даних. Вся концепція програмування в WINDOWS основана на чіткому впорядкуванні структур даних, пов'язаних із ними програм-функцій та констант-параметрів. Дані, що пов'язані з виконанням одної функції об'єднуються в блок певної довжини (він називається структурою). Елементами таких структур можуть бути інші структури і т.д. Існують структури загального користування, які не пов'язані з конкретною функцією API, а містять довідкову інформацію про систему, файли, користувача, тощо. Дані, що зберігаються в цих структурах постійно змінюються і деколи їх неможливо передбачити. Тому для отримання цих даних не можна користуватися звичайними командами читання з пам’яті типу “mov”. Перед користуванням такою динамічною інформацією необхідно перевірити, чи готова інформація для споживання. Щоб уникнути некоректності при умові паралельного виконання процесів кожне звернення до системної інформації необхідно регіструвати. Тому фактично існує два типа функцій API:
а) функції, які виконують будь-яку дію;
б) функції, які отримують будь-яку інформацію.
ВИКОННАННЯ РОБОТИ
Змінити текст програми таким чином, щоб функція API MessageBoxA виводила на екран вікно з двома кнопками: <OK> та <Cancel>. При натисненні кнопки <OK> програма повинна знову отримати системний час, а при натисненні кнопки <Cancel> - програма завершує роботу. Для цього треба знайти у файлі win119.inc константу MB_OKCANCEL та вказати її як стиль вікна MessageBoxA. Після відповіді користувача треба порівняти регістр EAX з константою IDOK за допомогою асемблерної команди “cmp eax, IDOK”. Якщо значення однакові, то зробити перехід на початок програми по команді “jz Start”.
Код програми
(GetLocalTime)
.386
.model flat,STDCALL
extrn ExitProcess: proc
extrn GetLocalTime: proc
extrn MessageBoxA: proc
extrn _wsprintfA:Proc
.data
Time_title db ' Лабораторна робота №2 ',0
TIME_STRING db 2000 dup (0)
_ESP dd 0
FORMAT_STRING:
db ' Системний час:',0dh,0ah,0dh,0ah
db ' Рiк: %ld',0dh,0ah
db ' Мiсяць: %ld',0dh,0ah
db ' День тижня: %ld',0dh,0ah
db ' Число: %ld',0dh,0ah
db ' Година: %ld',0dh,0ah
db ' Хвилин: %ld',0dh,0ah
db ' Секунд: %ld',0dh,0ah
db ' Мілісекунд: %ld',0dh,0ah
db 0
Time_struc:
wYear dw 0 ; Рік
wMonth dw 0 ; Місяць
wDayOfWeek dw 0 ; День тиждня
wDay dw 0 ; Число
wHour dw 0 ; Година
wMinute dw 0 ; Хвилина
wSecond dw 0 ; Секунда
wMilliseconds dw 0 ; Мілісекунда
;==============================================================
.code
Start: push offset Time_struc
call GetLocalTime
mov _ESP,esp ; Збереження адреси стеку
xor eax,eax ; EAX=0
mov ax,wMilliseconds
push eax
mov ax,wSecond
push eax
mov ax,wMinute
push eax ; наступні параметри з стеку не забираються
mov ax,wHour
push eax
mov ax,wDay
push eax
mov ax,wDayOfWeek
push eax
mov ax,wMonth
push eax
mov ax,wYear
push eax
push offset FORMAT_STRING
push offset TIME_STRING
call _wsprintfA ; Вивід параметрів
mov esp,_ESP ; та очищення стеку
call MessageBoxA, 0, offset TIME_STRING, offset Time_title, 1h
cmp eax,1
jz Start
call ExitProcess, 0
end Start
/
Замінити виклик функції API GetLocalTime на виклик однієї з наступних функцій (змінивши відповідним чином параметри):
GetSystemTime
.386
.model flat,STDCALL
extrn ExitProcess: proc
extrn GetSystemTime: proc
extrn MessageBoxA: proc
extrn _wsprintfA:Proc
.data
Time_title db ' Лабораторна робота №2 студента групи КІ-21 Власюка В.В.',0
TIME_STRING db 2000 dup (0)
_ESP dd 0
FORMAT_STRING:
db ' Системний час:',0dh,0ah,0dh,0ah
db ' Рiк: %ld',0dh,0ah
db ' Мiсяць: %ld',0dh,0ah
db ' День тижня: %ld',0dh,0ah
db ' Число: %ld',0dh,0ah
db ' Година: %ld',0dh,0ah
db ' Хвилин: %ld',0dh,0ah
db ' Секунд: %ld',0dh,0ah
db ' Мілісекунд: %ld',0dh,0ah
db 0
Time_struc:
wYear dw 0 ; Рік
wMonth dw 0 ; Місяць
wDayOfWeek dw 0 ; День тиждня
wDay dw 0 ; Число
wHour dw 0 ; Година
wMinute dw 0 ; Хвилина
wSecond dw 0 ; Секунда
wMilliseconds dw 0 ; Мілісекунда
;==============================================================
.code
Start: push offset Time_struc
call GetSystemTime
mov _ESP,esp ; Збереження адреси стеку
xor eax,eax ; EAX=0
mov ax,wMilliseconds
push eax
mov ax,wSecond
push eax
mov ax,wMinute
push eax ; наступні параметри з стеку не забираються
mov ax,wHour
push eax
mov ax,wDay
push eax
mov ax,wDayOfWeek
push eax
mov ax,wMonth
push eax
mov ax,wYear
push eax
push offset FORMAT_STRING
push offset TIME_STRING
call _wsprintfA ; Вивід параметрів
mov esp,_ESP ; та очищення стеку
call MessageBoxA, 0, offset TIME_STRING, offset Time_title, 1h
cmp eax,1
jz Start
call ExitProcess, 0
end Start
/
GetLogicalDriveStrings
.386
.model flat,STDCALL
extrn GetLogicalDriveStringsA:proc
extrn MessageBoxA:proc
extrn ExitProcess:proc
.data
buffer dd 256
title_message db 'Лабораторна робота №2',0
text_message db 'Logical Drivers: '
disk db 256 dup(0)
.code
Start:
call GetLogicalDriveStringsA, buffer, offset disk
mov esi,offset disk
l1: cmp word ptr[esi],0
jz c1
cmp byte ptr[esi],0
jnz m1
mov byte ptr[esi],' '
m1:
inc esi
jmp l1
c1: call MessageBoxA,0, offset text_message, offset title_message,0
call ExitProcess,0
end Start
/
Висновок. У даній лабораторній роботі треба отримали та розшифрували одну з таких довідкових структур, яка містить інформацію про системний час. Для виклику довільної довідкової функції необхідно було вказати адресу місця в пам'яті, куди записувалась довідкова структура. Цю адресу, як параметр функції, завжди перед викликом функції треба опустити в стек.
В лабораторній роботі необхідно також звернула увагу на те, що в програмі можна використовувати не лише функції API, але і функції різних мов програмування. Для цього необхідно, щоб в системі були присутні відповідні DLL-файли.