?? lion-tutorial15.htm
字號:
<p><b>.code</b> <br>
<b>start:</b> <br>
<b> invoke GetModuleHandle, NULL</b> <br>
<b> mov hInstance,eax</b> <br>
<b> invoke GetCommandLine</b> <br>
<b> mov CommandLine,eax</b> <br>
<b> invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT</b>
<br>
<b> invoke ExitProcess,eax</b>
<p><b>WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD</b>
<br>
<b> LOCAL wc:WNDCLASSEX</b> <br>
<b> LOCAL msg:MSG</b> <br>
<b> mov wc.cbSize,SIZEOF WNDCLASSEX</b> <br>
<b> mov wc.style, CS_HREDRAW or CS_VREDRAW</b>
<br>
<b> mov wc.lpfnWndProc, OFFSET WndProc</b> <br>
<b> mov wc.cbClsExtra,NULL</b> <br>
<b> mov wc.cbWndExtra,NULL</b> <br>
<b> push hInst</b> <br>
<b> pop wc.hInstance</b> <br>
<b> mov wc.hbrBackground,COLOR_WINDOW+1</b> <br>
<b> mov wc.lpszMenuName,OFFSET MenuName</b> <br>
<b> mov wc.lpszClassName,OFFSET ClassName</b>
<br>
<b> invoke LoadIcon,NULL,IDI_APPLICATION</b> <br>
<b> mov wc.hIcon,eax</b> <br>
<b> mov wc.hIconSm,eax</b> <br>
<b> invoke LoadCursor,NULL,IDC_ARROW</b> <br>
<b> mov wc.hCursor,eax</b> <br>
<b> invoke RegisterClassEx, addr wc</b> <br>
<b> invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR
AppName,\</b> <br>
<b> WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\</b>
<br>
<b> CW_USEDEFAULT,300,200,NULL,NULL,\</b>
<br>
<b> hInst,NULL</b>
<br>
<b> mov hwnd,eax</b> <br>
<b> invoke ShowWindow, hwnd,SW_SHOWNORMAL</b> <br>
<b> invoke UpdateWindow, hwnd</b> <br>
<b> .WHILE TRUE</b> <br>
<b> invoke
GetMessage, ADDR msg,NULL,0,0</b> <br>
<b> .BREAK
.IF (!eax)</b> <br>
<b> invoke
TranslateMessage, ADDR msg</b> <br>
<b> invoke
DispatchMessage, ADDR msg</b> <br>
<b> .ENDW</b> <br>
<b> mov eax,msg.wParam</b> <br>
<b> ret</b> <br>
<b>WinMain endp</b>
<p><b>WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM</b> <br>
<b> .IF uMsg==WM_DESTROY</b> <br>
<b> invoke PostQuitMessage,NULL</b>
<br>
<b> .ELSEIF uMsg==WM_COMMAND</b> <br>
<b> mov eax,wParam</b> <br>
<b> .if lParam==0</b> <br>
<b> .if ax==IDM_CREATE_THREAD</b>
<br>
<b>
mov eax,OFFSET ThreadProc</b> <br>
<b>
invoke CreateThread,NULL,NULL,eax,\</b> <br>
<b>
0,\</b> <br>
<b>
ADDR ThreadID</b> <br>
<b>
invoke CloseHandle,eax</b> <br>
<b> .else</b>
<br>
<b>
invoke DestroyWindow,hWnd</b> <br>
<b> .endif</b>
<br>
<b> .endif</b> <br>
<b> .ELSEIF uMsg==WM_FINISH</b> <br>
<b> invoke MessageBox,NULL,ADDR SuccessString,ADDR
AppName,MB_OK</b> <br>
<b> .ELSE</b> <br>
<b> invoke DefWindowProc,hWnd,uMsg,wParam,lParam</b>
<br>
<b> ret</b> <br>
<b> .ENDIF</b> <br>
<b> xor eax,eax</b> <br>
<b> ret</b> <br>
<b>WndProc endp</b>
<p><b>ThreadProc PROC USES ecx Param:DWORD</b> <br>
<b> mov ecx,600000000</b> <br>
<b>Loop1:</b> <br>
<b> add eax,eax</b> <br>
<b> dec ecx</b> <br>
<b> jz Get_out</b> <br>
<b> jmp Loop1</b> <br>
<b>Get_out:</b> <br>
<b> invoke PostMessage,hwnd,WM_FINISH,NULL,NULL</b>
<br>
<b> ret</b> <br>
<b>ThreadProc ENDP</b>
<p><b>end start</b> <br>
<h3> Analysis:</h3>
The main program presents the user with a normal window with a menu. If the user
selects "Create Thread" menu item, the program creates a thread as below:
<p><b> .if ax==IDM_CREATE_THREAD</b>
<br>
<b>
mov eax,OFFSET ThreadProc</b> <br>
<b>
invoke CreateThread,NULL,NULL,eax,\</b> <br>
<b>
NULL,0,\</b> <br>
<b>
ADDR ThreadID</b> <br>
<b>
invoke CloseHandle,eax</b> <br>
<b> </b> <br>
The above function creates a thread that will run a procedure named ThreadProc
concurrently with the primary thread. After the successful call, CreateThread
returns immediately and ThreadProc begins to run. Since we do not use thread
handle, we should close it else there'll be some leakage of memory. Note that
closing the thread handle doesn't terminate the thread. Its only effect is that
we cannot use the thread handle anymore.
<p><b>ThreadProc PROC USES ecx Param:DWORD</b> <br>
<b> mov ecx,600000000</b> <br>
<b>Loop1:</b> <br>
<b> add eax,eax</b> <br>
<b> dec ecx</b> <br>
<b> jz Get_out</b> <br>
<b> jmp Loop1</b> <br>
<b>Get_out:</b> <br>
<b> invoke PostMessage,hwnd,WM_FINISH,NULL,NULL</b>
<br>
<b> ret</b> <br>
<b>ThreadProc ENDP</b>
<p>As you can see, ThreadProc performs a savage calculation which takes quite
a while to finish and when it finishs it posts a WM_FINISH message to the main
window. WM_FINISH is our custom message defined like this:
<ul>
<b>WM_FINISH equ WM_USER+100h</b>
</ul>
You don't have to add WM_USER with 100h but it's safer to do so. <br>
The WM_FINISH message is meaningful only within our program. When the main window
receives the WM_FINISH message, it respons by displaying a message box saying
that the calculation is completed. <br>
You can create several threads in succession by selecting "Create Thread" several
times. <br>
In this example, the communication is one-way in that only the thread can notify
the main window. If you want the main thread to send commands to the worker thread,
you can so as follows:
<ul>
<li> add a menu item saying something like "Kill Thread" in the menu</li>
<li> a global variable which is used as a command flag. TRUE=Stop the thread,
FALSE=continue the thread</li>
<li> Modify ThreadProc to check the value of the command flag in the loop.</li>
</ul>
When the user selects "Kill Thread" menu item, the main program will set the value
TRUE in the command flag. When ThreadProc sees that the value of the command flag
is TRUE, it exits the loop and returns thus ends the thread.
<hr size="1">
<div align="center"> This article come from Iczelion's asm page, Welcom to <a href="http://asm.yeah.net">http://asm.yeah.net</a></div>
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -