彻底明了WIN32底层工作的工具MASM32

我们用什么工具才能知道windows内核是如何工作,消息是如何处理的呢?

windows的汇编工具MASM32可以让我们非常容易彻底明了WIN32底层工作

窗口程序的核心工作就是3大点,A资源文件的编辑+B窗口的处理主程序+C消息处理程序

 

MASM32官方下载站点:      http://www.masm32.com

在没有使用C++和MFC开发window程序以前,都是用C语言与WIN32的API函数进行 编程

在使用C++和MFC开发window之后,由于MFC类库不能完全封装完所有的API函数,以及MFC的类库的复杂性以及MFC大量内置宏,加大了程序员写程序的工作量

一种比C语言更加简洁的汇编语言MASM32+API函数+各种数据结构的开发环境诞生啦

MASM32是微软专门为WINDOWS量身订做的一种高效方便的汇编开发工具

 

配置和安装MASM32的开发环境

1.从网站下载开发工具,安装到C:或者D:下面的MASM32文件夹中,建议不要改文件夹的名字

2.设置编译环境到windows,用下面的代码建立一个批处理文件为VAR.bat,其中set Masm32Dir=D:/Masm32是指定安装的实际文件夹路径

 

@echo off
rem 请根据 Masm32 软件包的安装目录修改下面的 Masm32Dir 环境变量!
set Masm32Dir=D:/Masm32
set include=%Masm32Dir%/Include;%include%
set lib=%Masm32Dir%/lib;%lib%
set path=%Masm32Dir%/Bin;%Masm32Dir%;%PATH%
set Masm32Dir=
echo on

3.用编辑器写源文件另存为*.asm,可以从源代码样例中找出测试的代码源文件,也可以用本代码的源代码进行编译和链接

4.编译源文件为*.OBJ ,命令行是ml /c /coff *.asm

5.连接目标*.OBJ文件为*.EXE程序 ,命令行是Link /subsystem:windows *.obj

6.输入得到的*.EXE文件名,可以看到程序的窗口界面

 

******************************************************************************************************************

下面通过一个完整的代演示一个windows窗口程序的实现过程和工作方式,请把代码另存为win32.asm

实现一个窗口主要由2个程序过程组成

窗口程序的核心工作就是3大点,A资源文件的编辑+B窗口的处理主程序+C消息处理程序

 

1._Proc()拦截此程序的各种消息,在本代码中只实现窗口重绘消息WM_PAINT和关闭窗口消息WM_CLOSE的处理,其它消息没有处理代码

而GetMessage,sendmessage两个函数都要截到这个窗口的句柄ID,这就是黑客编程最常用的技术
我们在_proc过程对各种消息进行检查,然后指定它们按照作者想要的工作方式进行各种操作,
这就是windows消息处理的核心点

 

2._WinMain()实现装载资源,填充窗口结构,注册,建立,显示,更新窗口,并进行消息循环

;操作流程是
;1.装载各种资源,如鼠标,图标,菜单,对话框,图片等,本例只装光标资源LoadCursor,0,IDC_ARROW
;2.填充窗口结构数据,各部数据依次填入,指定消息处理的函数为上面_Proc过程,见API的结构WNDCLASSEX
;  见代码mov @stWndClass.lpfnWndProc,offset _Proc
;3.注册窗口结构:把上面定制好的窗口结构在WINDOW注册,见API函数RegisterClassEx
;4.创建窗口:在注册窗口后就应该创建,见API函数CreateWindowEx
;5.显示窗口:在创建成功后显示窗口,见API函数ShowWindow
;6.更新窗口:用WM_PAINT消息不断刷新窗口,见API函数UpdateWindow
;  如消息处函数_Proc没有实现WM_PAINT的处理,则按windows缺省处理,如有处理WM_PAINT的代码,
;  本例已经实现窗口刷新的代码,见.if eax == WM_PAINT,代码段,
;  它在实现在窗口中间的客户区显示文字Win32 Assembly, Simple and powerful!
;7.进入窗口的消息循环
;7.1GetMessage()首先从windows消息对列中取有没有自己的消息,如没有就退出
;  其它程序和窗口也可以用API函数postmessage()发要这个窗口处理的消息到windows消息对列
;  也就是说GetMessage()也可以取得由其它程序用postmessage发给自己的消息
;7.2TranslateMessage()如果有消息则把消息标识进行简化转换,它通常负责键盘和鼠标消息的简化
;7.3DispatchMessage()对消息进行分派处理,把消息处理权转给_Proc这个专用的消息处理函数
;此程序又开始进行下一轮的消息循环

;其它程序可以直接用API函数sendmessage()发消息给这个窗口指定的消息处理函数_proc

 

以下源代码用EDITPLUS编辑OK,用MASM32工具编译OK,win32.exe在windows XP运行正常

每次重载编译,都得删除以前的*.OBJ文件和*.EXE文件,否则编译和连接不过去

*********************************************************************************************

;source code filename is win32.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming >
; win32.asm
; 窗口程序的模板代码
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff win32.asm
; Link /subsystem:windows win32.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  .386   ;使用CPU386的指指令集
  .model flat,stdcall ;函数的参数传递为标准调用,左-右
  option casemap:none ;源代码勿略大小写区分
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义,它通常把*.LIB和*.INC包含到此程序中来
; *.inc功能C++的*.H头文件,*.LIB如同C++的DLL,LIB是以C语言实现的API函数做成的静态链接库文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include  windows.inc ;它包含了大量的windows的宏定义和windows常用的数据结构
include  gdi32.inc
includelib gdi32.lib
include  user32.inc
includelib user32.lib
include  kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段 常用于定义程序的全局变量
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  .data?
hInstance dd  ?
hWinMain dd  ?

  .const
szClassName db 'MyClass',0
szCaptionMain db 'win32 Assembly!',0
szText  db 'Win32 Assembly, Simple and powerful !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程_Proc(主要实现对消息的处理,在此程序中只处理了WM_PAINT和WM_CLOSE消息,让它在程序的客户区显示文字)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Proc proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
  local @stPs:PAINTSTRUCT
  local @stRect:RECT
  local @hDc
  mov eax,uMsg 
;通过uMsg移入EAX来判断常用消息,uMsg通常包含windows常用消息,wParam,lParam通常包含键盘和鼠标的消息
;********************************************************************
;对WM_PAINT消息进行处理的消息代码段,负责把文件显示在程序的客户区的中央位置
;显示文字是Win32 Assembly, Simple and powerful !
  .if eax == WM_PAINT
   invoke BeginPaint,hWnd,addr @stPs
   mov @hDc,eax

   invoke GetClientRect,hWnd,addr @stRect
   invoke DrawText,@hDc,addr szText,-1,/
    addr @stRect,/
    DT_SINGLELINE or DT_CENTER or DT_VCENTER

   invoke EndPaint,hWnd,addr @stPs
;********************************************************************
  .elseif eax == WM_CLOSE
   invoke DestroyWindow,hWinMain
   invoke PostQuitMessage,NULL
;********************************************************************
  .else
   invoke DefWindowProc,hWnd,uMsg,wParam,lParam
   ret
  .endif
;********************************************************************
  xor eax,eax
  ret
_Proc endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
  local @stWndClass:WNDCLASSEX
  local @stMsg:MSG

  invoke GetModuleHandle,NULL
  mov hInstance,eax
  invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
;********************************************************************
; 注册窗口类
;********************************************************************
  invoke LoadCursor,0,IDC_ARROW
  mov @stWndClass.hCursor,eax
  push hInstance
  pop @stWndClass.hInstance
  mov @stWndClass.cbSize,sizeof WNDCLASSEX
  mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
  mov @stWndClass.lpfnWndProc,offset _Proc
  mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
  mov @stWndClass.lpszClassName,offset szClassName
  invoke RegisterClassEx,addr @stWndClass
;********************************************************************
; 建立并显示窗口
;********************************************************************
  invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,/
   WS_OVERLAPPEDWINDOW,/
   100,100,600,400,/
   NULL,NULL,hInstance,NULL
  mov hWinMain,eax
  invoke ShowWindow,hWinMain,SW_SHOWNORMAL
  invoke UpdateWindow,hWinMain
;********************************************************************
; 消息循环
;********************************************************************
  .while TRUE
   invoke GetMessage,addr @stMsg,NULL,0,0
   .break .if eax == 0
   invoke TranslateMessage,addr @stMsg
   invoke DispatchMessage,addr @stMsg
  .endw
  ret

_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
  call _WinMain
  invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  end start

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值