⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lion-tut-c14.htm

📁 内有一些代码
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<HTML>
<head>
<link rel="stylesheet" href="../../asm.css">

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Iczelion's win32 asm tutorial</title>
</head>

<body bgcolor="#FFFFFF" background="../../images/back01.jpg">
<P align=center><FONT color=#0000ff size=4>第十四课 进程</FONT></P>
<HR SIZE=1>
本课中我们将学习:什么是进程?如何产生和终止一个进程? 
<H3><FONT color=#ff0000>初步知识:</FONT></H3>进程是什么?下面是我从WIN32 API指南中节选的解释: 
<BLOCKQUOTE>“一个进程是一个正在执行的应用程序,它包含有:私有的虚拟地址空间、代码、数据和其它的操作系统资源,譬如进程可以存取的管道、文件和同步对象等等。”</BLOCKQUOTE>
<P>从上面的定义中您可以看到,一个进程拥有几个对象:地址空间、执行模块和其它该执行程序打开或创建的任何对象或资源。至少,一个进程必须包含可执行模块、私有的地址空间和一个以上的线程。什么是线程呢?一个线程实际上是一个执行单元。当WINDOWS产生一个进程时,它自动为该进程产生一个主线程。该线程通常从模块的第一条指令处开始执行。如果进程需要更多的线程,它可以随后显式地产生。<BR>当WINDWOS 
接收到产生进程的消息时,它会为进程生成私有内存地址空间,接着把可执行文件映射到该空间。在WIN32下为进程产生了主进程后,您还可以调用函数CreateProcess来为您的进程产生更多的线程。</P>
<P>CreateProcess的原型如下:</P>
<P><B>CreateProcess proto lpApplicationName:DWORD,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
lpCommandLine:DWORD,\<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
lpProcessAttributes:DWORD,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
lpThreadAttributes:DWORD,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
bInheritHandles:DWORD,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
dwCreationFlags:DWORD,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
lpEnvironment:DWORD,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
lpCurrentDirectory:DWORD,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
lpStartupInfo:DWORD,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
lpProcessInformation:DWORD</B> 
<P>不要被这么多的参数吓倒,其实您可以忽略其中的大多数的参数(让它们有缺省值)。 
<P>lpApplicationName --&gt; 
可执行文件的名称(含或不含路径)。如果该参数为NULL,那必须在参数lpCommandLine中传递文件名称。<BR>lpCommandLine --&gt; 
传递给欲执行的文件的命令行参数。如果lpApplicationName为NULL,那必须在该参数中指定,譬如:"notepad.exe readme.txt" 
。<BR>lpProcessAttributes 和 lpthreadAttributes --&gt; 
指定进程和主线程的安全属性。您可以把它们都设成为NULL,这样就设置了缺省的安全属性。<BR>bInheritHandles --&gt; 
标志位。用来设置新进程是否继承创建进程所有的打开句柄。<BR>dwCreationFlags --&gt; 
有几个标志可以在此处设置以决定欲创建进程的行为,譬如:您可能想创建进程后并不想让它立刻运行,这样在它真正运行前可以作一些检查和修改工作。您还可以在此处设置新进程中的所有线程的优先级,通常我们把它设置为NORMAL_PRIORITY_CLASS。<BR>lpEnvironment 
--&gt; 
指向环境块的指针,一般地环境块包含几个环境字符串。如果该参数为NULL,那么新进程继承创建进程的环境块。<BR>lpCurrentDirectory 
--&gt; 指向当前目录以及为子进程设置的“当前目录”的路径。如果为NULL, 则继承创建进程的“当前目录”路径。<BR>lpStartupInfo 
--&gt; 
指向新进程的启动结构体STARTUPINFO的指针。STARTUPINFO告诉WINDOWS如何显示新进程的外观。该参数有许多的成员变量,如果您不想新进程有什么的特别之处,可以调用GetStartupInfo函数来用创建进程的启动参数来填充STARTUPINFO结构体变量。<BR>lpProcessInformation 
--&gt; 指向结构体PROCESS_INFORMATION的指针,该结构体变量包含了一些标识该进程唯一性的一些成员变量: 
<BLOCKQUOTE><B>PROCESS_INFORMATION STRUCT</B> <BR><B>&nbsp;&nbsp;&nbsp; 
  hProcess&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HANDLE 
  ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 
  handle to the child process</B> <BR><B>&nbsp;&nbsp;&nbsp; 
  hThread&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  HANDLE 
  ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 
  handle to the primary thread of the child process</B> 
  <BR><B>&nbsp;&nbsp;&nbsp; dwProcessId&nbsp;&nbsp;&nbsp;&nbsp; DWORD 
  ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ID 
  of the child process</B> <BR><B>&nbsp;&nbsp;&nbsp; 
  dwThreadId&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD 
  ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ID of 
  the primary thread of the child process</B> <BR><B>PROCESS_INFORMATION 
ENDS</B></BLOCKQUOTE>
<P>进程句柄和进程ID是两个不同的概念。进程ID好似一个唯一值,而进程句柄是调用相关的WINDOWS API 
后得到的一个返回值。不能用进程句柄来标识一个进程的唯一性,因为这个值并不唯一。在调用CreateProcess产生新进程后,该进程就被创建,而且CerateProcess函数立即返回。您可以调用函数GetExitCodeProcess来检验进程是否结束。该函数的原型如下: 

<P><B>GetExitCodeProcess proto hProcess:DWORD, lpExitCode:DWORD</B> 
<P>如果调用成功,lpExitCode中包含了所查询进程的状态码。如果等于STILL_ACTIVE就表明该进程依旧存在。 
您可以调用函数TerminateProcess来强制终止一个进程。该函数的原型如下: 
<P><B>TerminateProcess proto hProcess:DWORD, uExitCode:DWORD</B> 
<P>您可以指定任意一个退出值。用该函数结束一个进程并不好,因为该进程加载的动态连接库并不会得到进程正退出的消息。<BR>&nbsp; 
<H3><FONT color=#ff0000>例子:</FONT></H3>在下面的例子中,当用户选择菜单项“crate 
process”时我们创建一个新进程。它会去执行“"msgbox.exe”。如果用户想要终止新进程,可以选择菜单项“terminate 
process”。这时,应用程序检查欲终止的进程是否仍存在,若存在则调用TerminateProcess函数来终止它。 
<P><B>.386</B> <BR><B>.model flat,stdcall</B> <BR><B>option casemap:none</B> 
<BR><B>WinMain proto :DWORD,:DWORD,:DWORD,:DWORD</B> <BR><B>include 
\masm32\include\windows.inc</B> <BR><B>include \masm32\include\user32.inc</B> 
<BR><B>include \masm32\include\kernel32.inc</B> <BR><B>includelib 
\masm32\lib\user32.lib</B> <BR><B>includelib \masm32\lib\kernel32.lib</B> 
<P><B>.const</B> <BR><B>IDM_CREATE_PROCESS equ 1</B> <BR><B>IDM_TERMINATE equ 
2</B> <BR><B>IDM_EXIT equ 3</B> 
<P><B>.data</B> <BR><B>ClassName db "Win32ASMProcessClass",0</B> 
<BR><B>AppName&nbsp; db "Win32 ASM Process Example",0</B> <BR><B>MenuName db 
"FirstMenu",0</B> <BR><B>processInfo PROCESS_INFORMATION &lt;&gt;</B> 
<BR><B>programname db "msgbox.exe",0</B> 
<P><B>.data?</B> <BR><B>hInstance HINSTANCE ?</B> <BR><B>CommandLine LPSTR ?</B> 
<BR><B>hMenu HANDLE ?</B> <BR><B>ExitCode DWORD 
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
; contains the process exitcode status from GetExitCodeProcess call.</B> 
<P><B>.code</B> <BR><B>start:</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke GetModuleHandle, 
NULL</B> <BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp; 
hInstance,eax</B> <BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
GetCommandLine</B> <BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov 
CommandLine,eax</B> <BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke ExitProcess,eax</B> 
<P><B>WinMain proc 
hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD</B> 
<BR><B>&nbsp;&nbsp;&nbsp; LOCAL wc:WNDCLASSEX</B> <BR><B>&nbsp;&nbsp;&nbsp; 
LOCAL msg:MSG</B> <BR><B>&nbsp;&nbsp;&nbsp; LOCAL hwnd:HWND</B> 
<BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbSize,SIZEOF WNDCLASSEX</B> 
<BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.style, CS_HREDRAW or CS_VREDRAW</B> 
<BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpfnWndProc, OFFSET WndProc</B> 
<BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbClsExtra,NULL</B> 
<BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbWndExtra,NULL</B> 
<BR><B>&nbsp;&nbsp;&nbsp; push&nbsp; hInst</B> <BR><B>&nbsp;&nbsp;&nbsp; 
pop&nbsp;&nbsp; wc.hInstance</B> <BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
wc.hbrBackground,COLOR_WINDOW+1</B> <BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
wc.lpszMenuName,OFFSET MenuName</B> <BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
wc.lpszClassName,OFFSET ClassName</B> <BR><B>&nbsp;&nbsp;&nbsp; invoke 
LoadIcon,NULL,IDI_APPLICATION</B> <BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
wc.hIcon,eax</B> <BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hIconSm,eax</B> 
<BR><B>&nbsp;&nbsp;&nbsp; invoke LoadCursor,NULL,IDC_ARROW</B> 
<BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hCursor,eax</B> 
<BR><B>&nbsp;&nbsp;&nbsp; invoke RegisterClassEx, addr wc</B> 
<BR><B>&nbsp;&nbsp;&nbsp; invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR 
ClassName,ADDR AppName,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
CW_USEDEFAULT,300,200,NULL,NULL,\</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
hInst,NULL</B> <BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; hwnd,eax</B> 
<BR><B>&nbsp;&nbsp;&nbsp; invoke ShowWindow, hwnd,SW_SHOWNORMAL</B> 
<BR><B>&nbsp;&nbsp;&nbsp; invoke UpdateWindow, hwnd</B> 
<BR><B>&nbsp;&nbsp;&nbsp; invoke GetMenu,hwnd</B> <BR><B>&nbsp;&nbsp;&nbsp; 
mov&nbsp; hMenu,eax</B> <BR><B>&nbsp;&nbsp;&nbsp; .WHILE TRUE</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
invoke GetMessage, ADDR msg,NULL,0,0</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
.BREAK .IF (!eax)</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
invoke TranslateMessage, ADDR msg</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
invoke DispatchMessage, ADDR msg</B> <BR><B>&nbsp;&nbsp;&nbsp; .ENDW</B> 
<BR><B>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp; eax,msg.wParam</B> 
<BR><B>&nbsp;&nbsp;&nbsp; ret</B> <BR><B>WinMain endp</B> 
<P><B>WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM</B> 
<BR><B>&nbsp;&nbsp;&nbsp; LOCAL startInfo:STARTUPINFO</B> 
<BR><B>&nbsp;&nbsp;&nbsp; .IF uMsg==WM_DESTROY</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
PostQuitMessage,NULL</B> <BR><B>&nbsp;&nbsp;&nbsp; .ELSEIF 
uMsg==WM_INITMENUPOPUP</B> <BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
invoke GetExitCodeProcess,processInfo.hProcess,ADDR ExitCode</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if eax==TRUE</B> 
<BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if 
ExitCode==STILL_ACTIVE</B> 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -