Win32汇编学习笔记(四)

前面几篇文章中都没有使用到菜单,对话框等资源,这次就演练如何在应用程序中加入这些资源。我们就以将VC6.0默认生成的Win32程序移植为32位汇编为例。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

首先用VC6.0生成一个默认Win32版的Hello,World程序,将Hello.rcdemo.ico,small.ico都拷贝到项目目录下,去掉VC6.0相关的部分,最后Hello.rc修改如下:

None.gif //MicrosoftVisualC++generatedresourcescript.
None.gif//
None.gif#include"resource.h"
None.gif
None.gif#defineIDR_MAINFRAME128
None.gif#defineIDD_DEMO_DIALOG102
None.gif#defineIDD_ABOUTBOX103
None.gif#defineIDS_APP_TITLE103
None.gif
None.gif#defineIDM_ABOUT104
None.gif#defineIDM_EXIT105
None.gif#defineIDS_HELLO106
None.gif#defineIDI_DEMO107
None.gif#defineIDI_SMALL108
None.gif#defineIDC_DEMO109
None.gif
None.gif#defineIDC_MYICON2
None.gif#defineIDC_STATIC-1
None.gif
None.gif/
None.gif//
None.gif//Icon
None.gif//
None.gif//IconwithlowestIDvalueplacedfirsttoensureapplicationicon
None.gif//remainsconsistentonallsystems.
None.gif
None.gifIDI_DEMOICONDISCARDABLE"demo.ICO"
None.gifIDI_SMALLICONDISCARDABLE"SMALL.ICO"
None.gif/
None.gif//
None.gif//Menu
None.gif//
None.gifIDC_DEMOMENUDISCARDABLE
None.gifBEGIN
None.gifPOPUP"
&File "
None.gifBEGIN
None.gifMENUITEM"E
&xit ",IDM_EXIT
None.gifEND
None.gifPOPUP"
&Help "
None.gifBEGIN
None.gifMENUITEM"
&About dot.gif",IDM_ABOUT
None.gifEND
None.gifEND
None.gif/
None.gif//
None.gif//Accelerator
None.gif//
None.gifIDC_DEMOACCELERATORSMOVEABLEPURE
None.gifBEGIN
None.gif"?",IDM_ABOUT,ASCII,ALT
None.gif"/",IDM_ABOUT,ASCII,ALT
None.gifEND
None.gif/
None.gif//
None.gif//Dialog
None.gif//
None.gifIDD_ABOUTBOXDIALOGDISCARDABLE22,17,230,75
None.gifSTYLEDS_MODALFRAME|WS_CAPTION|WS_SYSMENU
None.gifCAPTION"About"
None.gifFONT8,"System"
None.gifBEGIN
None.gifICONIDI_DEMO,IDC_MYICON,14,9,16,16
None.gifLTEXT"HelloApp1.0",IDC_STATIC,49,10,119,8,SS_NOPREFIX
None.gifLTEXT"Copyright(C)2008",IDC_STATIC,49,20,119,8
None.gifDEFPUSHBUTTON"OK",IDOK,195,6,30,11,WS_GROUP
None.gifEND
None.gif
None.gif/
None.gif//
None.gif//StringTable
None.gif//
None.gif
None.gifSTRINGTABLEDISCARDABLE
None.gifBEGIN
None.gifIDC_DEMO"DEMO"
None.gifIDS_APP_TITLE"demo"
None.gifIDS_HELLO"HelloWorld!"
None.gifEND
None.gif/
None.gif

然后创建一个MakFile文件,内容如下:

None.gif NAME = Hello
None.gifOBJS
= $( NAME ). obj
None.gifRES
= $( NAME ). res
None.gif
None.gif
$( NAME ). exe: $( OBJS ) $( RES )
None.gifLink
/ SUBSYSTEM :WINDOWS $( OBJS ) $( RES )
None.gif
$( RES ) : $( NAME ). rc
None.gifrc
$( NAME ). rc
None.gif
. asm . obj:
None.gifml
/ c / coff $( NAME ). asm
None.gif

最后仿照VC++代码编写汇编代码如下:

None.gif . 386
None.gif.modelflat,stdcall
None.gifoption
casemap: none
None.gif
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif;
Include文件定义
None.gif;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>includewindows.inc
None.gif
includegdi32. inc
None.gifincludelibgdi32.lib
None.gifincludeuser32.
inc
None.gifincludelibuser32.lib
None.gifincludekernel32.
inc
None.gifincludelibkernel32.lib
None.gif
None.gif
None.gifIDR_MAINFRAMEequ
128
None.gifIDD_DEMO_DIALOGequ
102
None.gifIDD_ABOUTBOXequ
103
None.gifIDS_APP_TITLEequ
103
None.gifIDM_ABOUTequ
104
None.gifIDM_EXITequ
105
None.gifIDS_HELLOequ
106
None.gifIDI_DEMOequ
107
None.gifIDI_SMALLequ
108
None.gifIDC_DEMOequ
109
None.gifIDC_MYICONequ
2
None.gifIDC_STATICequ-
1
None.gif
None.gif
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif;
数据段
None.gif;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif
.data?
None.gifhInstancedd?
; 应用程序句柄
None.gif
hWinMaindd? ; 窗口句柄
None.gif
szCaptionMaindb 1024 dup(?)
None.gifszTextdb
1024 dup(?)
None.gif
None.gif.const
None.gifszClassNamedb
' MyClass ' , 0 ; 窗口类名称
None.gif

None.gif
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif;
代码段
None.gif;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif
.code
None.gif
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif;
About对话框处理函数
None.gif;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif
_Aboutprocusesebxediesi,hDlg,uMsg,wParam,lParam
None.gif
mov eax,uMsg
None.gif.ifeax==WM_COMMAND
None.gif
mov eax,wParam
None.gif
movzx eax,ax
None.gif.ifeax==IDOK
None.gifinvokeEndDialog,hDlg,eax
None.gif
; invokeMessageBox,NULL,addrszText,addrszCaptionMain,MB_OK
None.gif
.endif
None.gif.elseifeax==WM_INITDIALOG
None.gif
mov eax, 1
None.gif
ret
None.gif.endif
None.gif
xor eax,eax ; 这句非常重要,清零eax,相当于返回false
None.gif
ret
None.gif_Aboutendp
None.gif
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif;
窗口过程
None.gif;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif

None.gif_ProcWinMainprocusesebxediesihWnd,uMsg,wParam,lParam
; 让汇编器保持子程序中使用到的寄存器的正确性
None.gif
local @stPs: PAINTSTRUCT
None.giflocal
@stRect: RECT
None.giflocal@hDc
None.gif
None.gif
mov eax,uMsg
None.gif
; *************************************************************
None.gif
.ifeax==WM_PAINT
None.gifinvokeBeginPaint,hWnd,addr@stPs
None.gif
mov @hDc,eax
None.gif
None.gifinvokeGetClientRect,hWnd,addr@stRect
None.gifinvokeDrawText,@hDc,addrszText,-
1 ,/ ; 长度设置为-1,表示输出的字符串以'/0'结尾,且由函数自动计算出其长度
None.gif
addr@stRect,/
None.gifDT_SINGLELINE
or DT_CENTER or DT_VCENTER
None.gifinvokeEndPaint,hWnd,addr@stPs
None.gif
; *************************************************************
None.gif
.elseifeax==WM_COMMAND
None.gif
mov eax,wParam
None.gif
movzx eax,ax
None.gif.ifeax==IDM_EXIT
None.gifinvokeDestroyWindow,hWinMain
None.gifinvokePostQuitMessage,NULL
None.gif.elseifeax==IDM_ABOUT
None.gifinvokeDialogBoxParam,hInstance,IDD_ABOUTBOX,hWnd,_About,NULL
None.gif.endif
None.gif
None.gif
; *************************************************************
None.gif
.elseifeax==WM_CLOSE
None.gifinvokeDestroyWindow,hWinMain
None.gifinvokePostQuitMessage,NULL
None.gif
; *************************************************************
None.gif
.else
None.gifinvokeDefWindowProc,hWnd,uMsg,wParam,lParam
None.gif
ret
None.gif.endif
None.gif
; *************************************************************
None.gif
xor eax,eax ; eax寄存器清零
None.gif
ret
None.gif
None.gif_ProcWinMainendp
None.gif
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif;
WinMain函数
None.gif;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif

None.gif_WinMainproc
None.giflocal
@stWndClass: WNDCLASSEX
None.giflocal
@stMsg: MSG
None.gif
None.gifinvokeGetModuleHandle,NULL
; 获取应用程序句柄,这在VC里是通过操作系统传递进来的,但是汇编中需要自己去获取
None.gif
mov hInstance,eax ; 获取到的应用程序句柄在eax中
None.gif
invokeRtlZeroMemory,addr@stWndClass,sizeof@stWndClass ; 清零
None.gif;
*************************************************************
None.gif;
注册窗口类
None.gif;
*************************************************************
None.gif
invokeLoadCursor, 0 ,IDC_ARROW ; 加载光标
None.gif
mov @stWndClass.hCursor,eax
None.gifinvokeLoadIcon,hInstance,offsetIDI_DEMO
None.gif
mov @stWndClass.hIcon,eax
None.gifinvokeLoadString,hInstance,IDS_APP_TITLE,addrszCaptionMain,sizeofszCaptionMain
None.gifinvokeLoadString,hInstance,IDS_HELLO,addrszText,sizeofszText
None.gif
push hInstance
None.gif
pop @stWndClass.hInstance
None.gif
mov @stWndClass.cbSize,sizeofWNDCLASSEX
None.gif
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
None.gif
None.gif
mov @stWndClass.lpfnWndProc,offset_ProcWinMain ; 设置窗口处理函数
None.gif
; invokeGetStockObject,WHITE_BRUSH
None.gif
; mov@stWndClass.hbrBackground,eax
None.gif
mov @stWndClass.hbrBackground,COLOR_WINDOW+ 1
None.gif
mov @stWndClass.lpszClassName,offsetszClassName
None.gif
mov @stWndClass.lpszMenuName,offsetIDC_DEMO
None.gifinvokeRegisterClassEx,addr@stWndClass
; 注册窗口类
None.gif;
*************************************************************
None.gif;
建立并显示窗口
None.gif;
*************************************************************
None.gif
invokeCreateWindowEx,WS_EX_CLIENTEDGE,offsetszClassName,addrszCaptionMain,/
None.gifWS_OVERLAPPEDWINDOW,/
None.gif
100 , 100 , 600 , 400 ,/
None.gifNULL,NULL,hInstance,NULL
; 创建窗口,发出一个WM_CREATE消息
None.gif
mov hWinMain,eax ; 保存窗口句柄
None.gif
invokeShowWindow,hWinMain,SW_SHOWNORMAL ; 显示窗口
None.gif
invokeUpdateWindow,hWinMain ; 发出一个WM_PAINT消息
None.gif;
*************************************************************
None.gif;
第一种消息循环,使用GetMessage,同步的
None.gif;
*************************************************************
None.gif
; .whileTRUE
None.gif
; invokeGetMessage,addr@stMsg,NULL,0,0
None.gif
; .break.ifeax==0;stMsg为0,即收到WM_QUIT消息时退出
None.gif
; invokeTranslateMessage,addr@stMsg
None.gif
; invokeDispatchMessage,addr@stMsg
None.gif
; .endw
None.gif;
*************************************************************
None.gif;
另一种消息循环,使用PeekMessage,异步的
None.gif;
*************************************************************
None.gif
.whileTRUE
None.gifinvokePeekMessage,addr@stMsg,NULL,
0 , 0 ,PM_REMOVE
None.gif.ifeax!=
0
None.gif.break.if@stMsg.message==WM_QUIT
None.gifinvokeTranslateMessage,addr@stMsg
None.gifinvokeDispatchMessage,addr@stMsg
None.gif.else
None.gif
; 空闲时间,可以做其他处理工作
None.gif
.endif
None.gif.endw
None.gif
ret
None.gif_WinMainendp
None.gif
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif;
程序入口点
None.gif;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif
start:
None.gif
call _WinMain
None.gifinvokeExitProcess,NULL
None.gif
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif
endstart
None.gif

nmake编译后运行如下图:

2008030801.jpg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值