Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
metod_lab_ps_2_SPO_ch2_lab_rab (1).doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
341.5 Кб
Скачать

Дотаток в Текст програми 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