
- •1 Дослідження структури виконуваного файлу ре - формату
- •1.1 Мета роботи
- •1.2 Основні відомості
- •1.3 Самостійна підготовка
- •1.4 Порядок виконання роботи
- •2.3 Самостійна підготовка
- •2.4 Порядок виконання роботи
- •3.3 Самостійна підготовка
- •3.4 Порядок виконання роботи
- •4 Синхронізація потоків у режимі ядра
- •4.1 Мета роботи
- •4.2 Основні відомості
- •4.3 Самостійна підготовка
- •4.4 Порядок виконання роботи
- •Перелік посилань
- •Дотаток а Текст програми read_pe.Asm
- •Дотаток б Текст програми thread1.Asm
- •Дотаток в Текст програми synchr1.Asm
- •Дотаток г Текст програми synchr3.Asm
Дотаток в Текст програми synchr1.Asm
;------------------------------------------------------------------------
synchr1.asm - Win32 консольна программа
;для створення і закриття дочернего потоку.
;------------------------------------------------------------------------
.486
.model flat,STDCALL ;модель пам'яті flat,
;STDCALL - передача параметрів в стилі С (справа наліво),
;процедура, що викликається чистить за собою стек
%NOINCL ;заборонити вивід тексту файлів включення
include WindowConA.inc
;Объявлення зовнішніми функцій Win32 (ASCII),
; що використовуються у програмі:
extrn AllocConsole:PROC
extrn SetConsoleTitleA:PROC
extrn SetConsoleCursorPosition:PROC
extrn ReadFile:PROC
extrn CloseHandle:PROC
extrn ExitProcess:PROC
extrn MoveFileA:PROC
extrn CreateFileA:PROC
extrn GetStdHandle:PROC
extrn WriteConsoleA:PROC
extrn ReadConsoleA:PROC
extrn WriteFile:PROC
extrn GetLastError:PROC
extrn CreateThread:PROC
extrn ExitProcess:PROC
extrn SwitchToThread:PROC
extrn Sleep:PROC
extrn InitializeCriticalSection:PROC
extrn EnterCriticalSection:PROC
extrn LeaveCriticalSection:PROC
;Макрокос установки курсора у задану позицію
Set_cursor macro cursor,posx,posy,descr,lbl
mov cursor.xx,posx
push eax
mov ax,posy
mov cursor.yy,ax
pop eax
push cursor
push descr
call SetConsoleCursorPosition
cmp eax, 0
jz lbl ;якщо невдача
endm
;Макрос затримки виконання програми
delay macro time
local labl
push ecx
mov ecx,time
labl:
loop labl
pop ecx
endm
;структура для установки положення курсору в консолі:
COORD struc
xx dw 0
yy dw 0
COORD ends
.data
fnam db "outputfile.dat" ; ім’я файла для запису
g_cs CRITICAL_SECTION <> ; екземпляр структури
con COORD <>
dummy dd 0 ;фіктивний аргумент функції потоку
pThreadID dd 0
hThread dd 0 ;дескриптор потоку
@hFile dd 0 ;дескриптор файлу
dOut dd 0 ;дескриптор виводу консолі
dIn dd 0 ;дескриптор вводу консолі
numwrit0 dd 1000 ;число повторень виводу у файл рядка
;з батьківського потоку
numwrit1 dd 1000 ;число повторень виводу у файл рядка
;з дочірнього потоку
str_out0 db "Output from parent thread",13,0
len_out0=$-str_out0
str_out1 db "Output from child thread",13,0
len_out1=$-str_out1
NumWri dd 0
string1 db "Thread creation",13,0
len1= $-string1
string2 db "Press <Enter> to terminate parent thread",13,0
len2= $-string2
string3 db "Child thread begins operation",13,0
len3=$-string3
title_text db "Synchronisation test",0
numrow dw 1
time_delay dd 100000 ;Параметр, що визначає затримку
.code
start proc
;точка входу до програми:
;запит консоли
call AllocConsole
;перевіріти успіх запиту консолі
test ax,ax
jz exit ;якщо невдача
;Виведення заголовку консолі
push offset title_text
call SetConsoleTitleA
;------отримати стандартний дескриптор виводу--------------------------
push STD_OUTPUT_HANDLE
call GetStdHandle
mov dOut,eax ;у dOut-дескриптор виводу консолі
cmp eax, 0
jz exit ;якщо невдача
;-------отримати стандартний дескриптор введення------------------------
push STD_INPUT_HANDLE
call GetStdHandle
mov dIn,eax ;у dIn-дескриптор введення консолі
cmp eax, 0
jz exit ;якщо невдача
;-------відчиняємо файл (CreateFileA)-----------------------------------
push 0
push NULL ;атрибути (вони ігноруються)
push OPEN_ALWAYS ;відчинити або створити файл
push 0 ;захист файлу не потрібний
push FILE_SHARE_WRITE ;дозволено сумісне
;використання файлу (за записом)
push GENERIC_WRITE ;дозволено записувати у файл
push offset fnam ;ім'я файла
call CreateFileA
cmp eax,0ffffffffh
je exit ;якщо невдача
mov @hFile,eax ;дескриптор файла
;-------вивести повідомлення--------------------------------------------
Set_cursor con,1,numrow,dOut,exit
inc numrow
push 0
push offset NumWri ;кількість виведених на екран символів
push len1 ;довжина рядку для виводу на екран
push offset string1 ;адреса рядку для виводу на екран
push dOut
call WriteConsoleA
cmp eax,0
jz exit ;якщо невдача
inc numrow
;-----------Створення дочірнього потоку----------------------------------
push offset pThreadID
push NULL
push offset dummy
push offset ThreadProc
push NULL
push NULL
call CreateThread
cmp eax,NULL
je exit ;якщо невдача
mov hThread,eax
;-----------Закрыття описувача дочірнього потоку-----------------------
push hThread
call CloseHandle
;------------ініціалізація об'єкту "критична секція"------------------
push offset g_cs ;покажчик на структуру
call InitializeCriticalSection
;------------Переключення на другий потік------------------------------
push NULL
call Sleep
;-------Вхід до критичної секції--------------------------------------
push offset g_cs
call EnterCriticalSection
;-------Запис у файл--------------------------------------------------
mov ecx,numwrit0
cmp ecx,0
je exit
cycl0:
push ecx
push NULL ;синхронне введення
push offset NumWri ;покажчик на буфер з кількістю
; записаних байтів
push len_out0 ;число байтів для виводу
push offset str_out0 ;покажчик на рядок для запису
push @hFile ;дескриптор відчиненого файлу
call WriteFile
cmp eax,NULL
je exit ;якщо невдача
pop ecx
loop cycl0
;-------Вихід з критичної секції--------------------------------------
push offset g_cs
call LeaveCriticalSection
;-------вивести повідомлення------------------------------------------
Set_cursor con,1,numrow,dOut,exit
inc numrow
push 0
push offset NumWri ;кількість виведених на екран
; символів
push len2 ;довжина рядку для виводу на екран
push offset string2 ;адреса рядку для виводу на екран
push dOut
call WriteConsoleA
cmp eax,0
jz exit ;якщо невдача
inc numrow
;-------очикування переводу каретки для виходу---------------------------
push 0
push offset NumWri ;кількість введених символів
push len1 ;розмір буферу введення
push offset string1
push dIn
call ReadConsoleA
cmp eax, 0
jz exit ;якщо невдача
exit:
;------------Закриття файла (CloseHandle)--------------------------------
push @hFile
call CloseHandle
;------------Вихід з програми--------------------------------------------
;підготовка виклику VOID ExitProcess(UINT uExitCode)
push 0
call ExitProcess
start endp
;--------------Процедура потоку----------------------------------------
ThreadProc proc
arg param:DWORD
uses ebx,edi,esi
;-------вивести повідомлення--------------------------------------------
Set_cursor con,1,numrow,dOut,exit_proc
inc numrow
push 0
push offset NumWri ;кількість виведених на екран
; символів
push len3 ;довжина рядку для виводу на екран
push offset string3 ;адреса рядку для виводу на екран
push dOut
call WriteConsoleA
;-------Вхід до критичної секції--------------------------------------
push offset g_cs
call EnterCriticalSection
;-------Запис у файл--------------------------------------------------
mov ecx,numwrit1
jecxz exit_proc
cycl1:
push ecx
push NULL ;синхронне введення
push offset NumWri ;покажчик на буфер з кількістю
; записаних байтів
push len_out1 ;число байтів для виводу
push offset str_out1 ;покажчик на рядок для запису
push @hFile ;дескриптор відчиненого файлу
call WriteFile
cmp eax,NULL
je exit_proc ;якщо невдача
pop ecx
delay time_delay
loop cycl1
;-------Вихід з критичної секції--------------------------------------
push offset g_cs
call LeaveCriticalSection
exit_proc:
ret
ThreadProc endp
end start