当前位置:中国易下载软件教材中心文章中心编程语言汇编语言 → 汇编语言教学(16)

汇编语言教学(16)

减小字体 增大字体 作者:佚名  来源:不详  发布时间:2007-8-21 1:03:59
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
喜欢这些内容嘛,请告诉你身边的朋友,易下载中心-QQ资源-itnetcn.com一起享受这份乐趣,本站内容来源互联网
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

第十六课 事件对象NW7海岸线网络安全资讯站
本课中我们将要学习事件对象以及如何在多线程编程中如何使用同步对象。 NW7海岸线网络安全资讯站
理论:NW7海岸线网络安全资讯站
上一课中我们演示了如何用WINDOWS消息在不同的线程之间进行通讯。另外的两种,即:使用全局变量和事件对象,将在本课中讲解。 NW7海岸线网络安全资讯站
事件对象就像一个开关:它只有两种状态---开和关。当一个事件处于”开”状态,我们称其为”有信号”否则称为”无信号”。您可以在一个线程的执行函数中创建一个事件对象,然后观察它的状态,如果是”无信号”就让该线程睡眠,这样该线程占用的CPU时间就比较少。 NW7海岸线网络安全资讯站
产生事件对象的函数如下: NW7海岸线网络安全资讯站
CreateEvent proto lpEventAttributes:DWORD,\ NW7海岸线网络安全资讯站
bManualReset:DWORD,\ NW7海岸线网络安全资讯站
bInitialState:DWORD,\ NW7海岸线网络安全资讯站
lpName:DWORD NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
lpEventAttribute--> 如果是NULL值,产生的事件对象有缺省的安全属性。NW7海岸线网络安全资讯站
bManualReset--> 如果想在每次调用WaitForSingleObject 后让WINDOWS为您自动地把事件地状态恢复为”无信号”状态,必须把该参数设为FALSE,否则,您必须每次调用ResetEvent函数来清除事件的信号。NW7海岸线网络安全资讯站
bInitialState--> 刚刚产生事件对象时的状态。如果设为TRUE是”有信号”,否则是”无信号”。NW7海岸线网络安全资讯站
lpName --> 事件对象的名称。您在OpenEvent函数中可能使用。 NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
如果CreateEvent调用成功的话,会返回新生成的对象的句柄,否则返回NULL。NW7海岸线网络安全资讯站
这里有两个API函数用来修改事件对象的信号状态:SetEvent和ResetEvent。前者把事件对象设为”有信号”状态,而后者正好相反。NW7海岸线网络安全资讯站
在事件对象生成后,必须调用WaitForSingleObject来让线程进入等待状态,该函数的语法如下: NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
WaitForSingleObject proto hObject:DWORD, dwTimeout:DWORD NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
hObject -->指向同步对象的指针。事件对象其实是同步对象的一种。NW7海岸线网络安全资讯站
dwTimeout --> 等待同步对象变成”有信号”前等待的时间,以毫秒计。当等待的时间超过该值后无信号同步对象仍处于”无信号”状态,线程不再等待,WaitForSingleObject函数会返回。如果想要线程一直等待,请把该参数设为INFINITE(该值等于0xffffffff)。 NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
例子:NW7海岸线网络安全资讯站
下面的例子显示了一个窗口,当用户选择了菜单项”run thread”后,线程开始简单的计数运算。结束后弹出一个对话框通知用户。在整个的计数期间,您可以选择菜单项”stop thread”来随时终止线程。 NW7海岸线网络安全资讯站
.386 NW7海岸线网络安全资讯站
.model flat,stdcall NW7海岸线网络安全资讯站
option casemap:none NW7海岸线网络安全资讯站
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD NW7海岸线网络安全资讯站
include \masm32\include\windows.inc NW7海岸线网络安全资讯站
include \masm32\include\user32.inc NW7海岸线网络安全资讯站
include \masm32\include\kernel32.inc NW7海岸线网络安全资讯站
includelib \masm32\lib\user32.lib NW7海岸线网络安全资讯站
includelib \masm32\lib\kernel32.lib NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
.const NW7海岸线网络安全资讯站
IDM_START_THREAD equ 1 NW7海岸线网络安全资讯站
IDM_STOP_THREAD equ 2 NW7海岸线网络安全资讯站
IDM_EXIT equ 3 NW7海岸线网络安全资讯站
WM_FINISH equ WM_USER+100h NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
.data NW7海岸线网络安全资讯站
ClassName db "Win32ASMEventClass",0 NW7海岸线网络安全资讯站
AppName db "Win32 ASM Event Example",0 NW7海岸线网络安全资讯站
MenuName db "FirstMenu",0 NW7海岸线网络安全资讯站
SuccessString db "The calculation is completed!",0 NW7海岸线网络安全资讯站
StopString db "The thread is stopped",0 NW7海岸线网络安全资讯站
EventStop BOOL FALSE NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
.data? NW7海岸线网络安全资讯站
hInstance HINSTANCE ? NW7海岸线网络安全资讯站
CommandLine LPSTR ? NW7海岸线网络安全资讯站
hwnd HANDLE ? NW7海岸线网络安全资讯站
hMenu HANDLE ? NW7海岸线网络安全资讯站
ThreadID DWORD ? NW7海岸线网络安全资讯站
ExitCode DWORD ? NW7海岸线网络安全资讯站
hEventStart HANDLE ? NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
.code NW7海岸线网络安全资讯站
start: NW7海岸线网络安全资讯站
invoke GetModuleHandle, NULL NW7海岸线网络安全资讯站
mov hInstance,eax NW7海岸线网络安全资讯站
invoke GetCommandLine NW7海岸线网络安全资讯站
mov CommandLine,eax NW7海岸线网络安全资讯站
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT NW7海岸线网络安全资讯站
invoke ExitProcess,eax NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD NW7海岸线网络安全资讯站
LOCAL wc:WNDCLASSEX NW7海岸线网络安全资讯站
LOCAL msg:MSG NW7海岸线网络安全资讯站
mov wc.cbSize,SIZEOF WNDCLASSEX NW7海岸线网络安全资讯站
mov wc.style, CS_HREDRAW or CS_VREDRAW NW7海岸线网络安全资讯站
mov wc.lpfnWndProc, OFFSET WndProc NW7海岸线网络安全资讯站
mov wc.cbClsExtra,NULL NW7海岸线网络安全资讯站
mov wc.cbWndExtra,NULL NW7海岸线网络安全资讯站
push hInst NW7海岸线网络安全资讯站
pop wc.hInstance NW7海岸线网络安全资讯站
mov wc.hbrBackground,COLOR_WINDOW+1 NW7海岸线网络安全资讯站
mov wc.lpszMenuName,OFFSET MenuName NW7海岸线网络安全资讯站
mov wc.lpszClassName,OFFSET ClassName NW7海岸线网络安全资讯站
invoke LoadIcon,NULL,IDI_APPLICATION NW7海岸线网络安全资讯站
mov wc.hIcon,eax NW7海岸线网络安全资讯站
mov wc.hIconSm,eax NW7海岸线网络安全资讯站
invoke LoadCursor,NULL,IDC_ARROW NW7海岸线网络安全资讯站
mov wc.hCursor,eax NW7海岸线网络安全资讯站
invoke RegisterClassEx, addr wc NW7海岸线网络安全资讯站
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,\ NW7海岸线网络安全资讯站
ADDR AppName,\ NW7海岸线网络安全资讯站
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ NW7海岸线网络安全资讯站
CW_USEDEFAULT,300,200,NULL,NULL,\ NW7海岸线网络安全资讯站
hInst,NULL NW7海岸线网络安全资讯站
mov hwnd,eax NW7海岸线网络安全资讯站
invoke ShowWindow, hwnd,SW_SHOWNORMAL NW7海岸线网络安全资讯站
invoke UpdateWindow, hwnd NW7海岸线网络安全资讯站
invoke GetMenu,hwnd NW7海岸线网络安全资讯站
mov hMenu,eax NW7海岸线网络安全资讯站
.WHILE TRUE NW7海岸线网络安全资讯站
invoke GetMessage, ADDR msg,NULL,0,0 NW7海岸线网络安全资讯站
.BREAK .IF (!eax) NW7海岸线网络安全资讯站
invoke TranslateMessage, ADDR msg NW7海岸线网络安全资讯站
invoke DispatchMessage, ADDR msg NW7海岸线网络安全资讯站
.ENDW NW7海岸线网络安全资讯站
mov eax,msg.wParam NW7海岸线网络安全资讯站
ret NW7海岸线网络安全资讯站
WinMain endp NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM NW7海岸线网络安全资讯站
.IF uMsg==WM_CREATE NW7海岸线网络安全资讯站
invoke CreateEvent,NULL,FALSE,FALSE,NULL NW7海岸线网络安全资讯站
mov hEventStart,eax NW7海岸线网络安全资讯站
mov eax,OFFSET ThreadProc NW7海岸线网络安全资讯站
invoke CreateThread,NULL,NULL,eax,\ NW7海岸线网络安全资讯站
NULL,0,\ NW7海岸线网络安全资讯站
ADDR ThreadID NW7海岸线网络安全资讯站
invoke CloseHandle,eax NW7海岸线网络安全资讯站
.ELSEIF uMsg==WM_DESTROY NW7海岸线网络安全资讯站
invoke PostQuitMessage,NULL NW7海岸线网络安全资讯站
.ELSEIF uMsg==WM_COMMAND NW7海岸线网络安全资讯站
mov eax,wParam NW7海岸线网络安全资讯站
.if lParam==0 NW7海岸线网络安全资讯站
.if ax==IDM_START_THREAD NW7海岸线网络安全资讯站
invoke SetEvent,hEventStart NW7海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_START_THREAD,MF_GRAYED NW7海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_STOP_THREAD,MF_ENABLED NW7海岸线网络安全资讯站
.elseif ax==IDM_STOP_THREAD NW7海岸线网络安全资讯站
mov EventStop,TRUE NW7海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_START_THREAD,MF_ENABLED NW7海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_STOP_THREAD,MF_GRAYED NW7海岸线网络安全资讯站
.else NW7海岸线网络安全资讯站
invoke DestroyWindow,hWnd NW7海岸线网络安全资讯站
.endif NW7海岸线网络安全资讯站
.endif NW7海岸线网络安全资讯站
.ELSEIF uMsg==WM_FINISH NW7海岸线网络安全资讯站
invoke MessageBox,NULL,ADDR SuccessString,ADDR AppName,MB_OK NW7海岸线网络安全资讯站
.ELSE NW7海岸线网络安全资讯站
invoke DefWindowProc,hWnd,uMsg,wParam,lParam NW7海岸线网络安全资讯站
ret NW7海岸线网络安全资讯站
.ENDIF NW7海岸线网络安全资讯站
xor eax,eax NW7海岸线网络安全资讯站
ret NW7海岸线网络安全资讯站
WndProc endp NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
ThreadProc PROC USES ecx Param:DWORD NW7海岸线网络安全资讯站
invoke WaitForSingleObject,hEventStart,INFINITE NW7海岸线网络安全资讯站
mov ecx,600000000 NW7海岸线网络安全资讯站
.WHILE ecx!=0 NW7海岸线网络安全资讯站
.if EventStop!=TRUE NW7海岸线网络安全资讯站
add eax,eax NW7海岸线网络安全资讯站
dec ecx NW7海岸线网络安全资讯站
.else NW7海岸线网络安全资讯站
invoke MessageBox,hwnd,ADDR StopString,ADDR AppName,MB_OK NW7海岸线网络安全资讯站
mov EventStop,FALSE NW7海岸线网络安全资讯站
jmp ThreadProc NW7海岸线网络安全资讯站
.endif NW7海岸线网络安全资讯站
.ENDW NW7海岸线网络安全资讯站
invoke PostMessage,hwnd,WM_FINISH,NULL,NULL NW7海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_START_THREAD,MF_ENABLED NW7海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_STOP_THREAD,MF_GRAYED NW7海岸线网络安全资讯站
jmp ThreadProc NW7海岸线网络安全资讯站
ret NW7海岸线网络安全资讯站
ThreadProc ENDP NW7海岸线网络安全资讯站
end start NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
分析:NW7海岸线网络安全资讯站
本例中,我们演示另一种技巧: NW7海岸线网络安全资讯站
.IF uMsg==WM_CREATE NW7海岸线网络安全资讯站
invoke CreateEvent,NULL,FALSE,FALSE,NULL NW7海岸线网络安全资讯站
mov hEventStart,eax NW7海岸线网络安全资讯站
mov eax,OFFSET ThreadProc NW7海岸线网络安全资讯站
invoke CreateThread,NULL,NULL,eax,\ NW7海岸线网络安全资讯站
NULL,0,\ NW7海岸线网络安全资讯站
ADDR ThreadID NW7海岸线网络安全资讯站
invoke CloseHandle,eax NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
在WM_CREATE 消息的处理中我们生成事件同步对象并创建线程。我们设置了相关的值让同步对象生成时处于”无信号”状态而且在调用了WaitForSingleObject后可以自动把事件对象的状态设为”无信号”。然后我们创建线程。 线程的代码开始执行后立即被阻塞: NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
ThreadProc PROC USES ecx Param:DWORD NW7海岸线网络安全资讯站
invoke WaitForSingleObject,hEventStart,INFINITE NW7海岸线网络安全资讯站
mov ecx,600000000 NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
您可以看到线程的执行体的第一条代码就是调用WaitForSingleObject函数,该函数使得线程阻塞并且一直处于等待事件对象变成”有信号”。这也就是说,我们以开始就让该线程进入了睡眠状态。 当用户选择了菜单项”run thread”后,我们把事件对象得状态变成”有信号”: NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
.if ax==IDM_START_THREAD NW7海岸线网络安全资讯站
invoke SetEvent,hEventStart NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
函数SetEvent可以让同步对象变成”有信号”状态,那么下一次线程得到时间片运行时,WaitForSingleObject函数就会返回,线程余下的代码就可以得到执行了。当用户选择了菜单项”stop thread” 时,我们把全局变量EventStop设为TRUE。 NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
.if EventStop==FALSE NW7海岸线网络安全资讯站
add eax,eax NW7海岸线网络安全资讯站
dec ecx NW7海岸线网络安全资讯站
.else NW7海岸线网络安全资讯站
invoke MessageBox,hwnd,ADDR StopString,ADDR AppName,MB_OK NW7海岸线网络安全资讯站
mov EventStop,FALSE NW7海岸线网络安全资讯站
jmp ThreadProc NW7海岸线网络安全资讯站
.endif NW7海岸线网络安全资讯站
NW7海岸线网络安全资讯站
这样线程得计数工作结束,然后跳转到重新执行WaitForSingleObject函数的地方。注意:我们不用手动清除事件对象的信号,因为在调用CreateEvent函数时把参数bManualReset的值设为了FALSE。NW7海岸线网络安全资讯站