MASM32中push hInstance与pop wc.hInstance指令作用及替代方案问询
关于Win32汇编中
push hInstance/pop wc.hInstance指令的解释 问题描述
这是我在网上找到的一个基础Win32程序,目前我理解大部分内容,但无法理解以下两行指令的作用:
push hInstance pop wc.hInstance希望有人能解释它们的功能,以及是否存在其他指令可以实现相同的操作。我曾通过谷歌和相关文档了解push、pop指令的基本作用,但无法将其与该程序的上下文结合起来理解。
完整程序代码
.386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc includelib \masm32\lib\user32.lib ; calls to functions in user32.lib and kernel32.lib include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib WinMain proto :DWORD,:DWORD,:DWORD,:DWORD .DATA ; initialized data ClassName db "SimpleWinClass",0 ; the name of our window class AppName db "Our First Window",0 ; the name of our window .DATA? ; Uninitialized data hInstance HINSTANCE ? ; Instance handle of our program CommandLine LPSTR ? .CODE ; Here begins our code start: invoke GetModuleHandle, NULL ; get the instance handle of our program. ; Under Win32, hmodule==hinstance mov hInstance,eax mov hInstance,eax invoke GetCommandLine ; get the command line. You don't have to call this function IF ; your program doesn't process the command line. mov CommandLine,eax invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT ; call the main function invoke ExitProcess, eax ; quit our program. The exit code is returned in eax from WinMain. WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX ; create local variables on stack LOCAL msg:MSG LOCAL hwnd:HWND mov wc.cbSize,SIZEOF WNDCLASSEX ; fill values in members of wc mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInstance pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc ; register our window class invoke CreateWindowEx,NULL,\ ADDR ClassName,\ ADDR AppName,\ WS_OVERLAPPEDWINDOW,\ CW_USEDEFAULT,\ CW_USEDEFAULT,\ CW_USEDEFAULT,\ CW_USEDEFAULT,\ NULL,\ NULL,\ hInst,\ NULL mov hwnd,eax invoke ShowWindow, hwnd,CmdShow ; display our window on desktop invoke UpdateWindow, hwnd ; refresh the client area .WHILE TRUE ; Enter message loop invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ; return exit code in eax ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY ; if the user closes our window invoke PostQuitMessage,NULL ; quit our application .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ; Default message processing ret .ENDIF xor eax,eax ret WndProc endp end start
指令功能与等价实现
功能解释
这两行指令的核心是把全局变量hInstance的值赋值给WNDCLASSEX结构体实例wc的hInstance成员。
x86汇编的mov指令不支持直接的内存到内存数据传输(不能直接写mov wc.hInstance, hInstance),必须借助寄存器中转。而push+pop的组合是另一种实现方式:
push hInstance:将全局变量hInstance中的值压入栈内存pop wc.hInstance:把栈顶的值弹出,写入到wc.hInstance对应的内存地址中
等价实现方式
有几种更直观的写法,效果完全一致:
- 寄存器中转写法(最常用):
mov eax, hInstance mov wc.hInstance, eax - MASM伪指令简化:
MASM汇编器支持直接写mov wc.hInstance, hInstance,它会自动在编译时转换成寄存器中转的指令,本质和上面的写法相同。
上下文意义
在Win32窗口程序中,WNDCLASSEX的hInstance成员必须设置为当前程序的实例句柄,用来将窗口类与当前进程绑定。这里的hInstance是程序启动时通过GetModuleHandle获取的全局实例句柄,赋值给结构体后,才能通过RegisterClassEx成功注册窗口类,为后续创建窗口做准备。
内容的提问来源于stack exchange,提问作者Mohamed Tarek
相关产品推荐
相关产品推荐

