模仿win32的Hello,World程序:
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
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 'My first Window !',0 ;窗口标题
szText db ' Hello,Win32 Assembly!!',0 ;要显示的信息
szButton db 'button',0
szButtonText db '点我吧!!',0
szMsgTitle db '信息',0
szErrorMsg db '出错啦!!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 出错处理过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ErrorProc proc
invoke MessageBox,NULL,offset szErrorMsg,offset szMsgTitle,MB_OK
ret
_ErrorProc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam ;让汇编器保持子程序中使用到的寄存器的正确性
local @stPs:PAINTSTRUCT
local @stRect:RECT
local @hDc
mov eax,uMsg
;********************************************************************
.if eax == WM_CREATE
invoke CreateWindowEx,NULL,offset szButton,offset szButtonText,\
WS_CHILD or WS_VISIBLE,100,100,65,50,hWnd,1,hInstance,NULL
;********************************************************************
.elseif eax == WM_PAINT
invoke BeginPaint,hWnd,addr @stPs
mov @hDc,eax
invoke GetClientRect,hWnd,addr @stRect
invoke DrawText,@hDc,addr szText,-1,\ ;长度设置为-1,表示输出的字符串以'\0'结尾,且由函数自动计算出其长度
addr @stRect,\
DT_SINGLELINE or DT_CENTER or DT_VCENTER
invoke EndPaint,hWnd,addr @stPs
;********************************************************************
.elseif eax == WM_COMMAND
invoke MessageBox,NULL,offset szText,offset szMsgTitle,MB_OK
;********************************************************************
.elseif eax == WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax ;eax寄存器清零
ret
_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;WinMain函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
invoke GetModuleHandle,NULL ;获取应用程序句柄,这在VC里是通过操作系统传递进来的,但是汇编中需要自己去获取
mov hInstance,eax ;获取到的应用程序句柄在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 _ProcWinMain ;设置窗口处理函数
;invoke GetStockObject,WHITE_BRUSH
;mov @stWndClass.hbrBackground,eax
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 ;创建窗口,发出一个WM_CREATE消息
mov hWinMain,eax ;保存窗口句柄
invoke ShowWindow,hWinMain,SW_SHOWNORMAL ;显示窗口
invoke UpdateWindow,hWinMain ;发出一个WM_PAINT消息
;********************************************************************
; 第一种消息循环,使用GetMessage,同步的
;********************************************************************
;.while TRUE
;invoke GetMessage,addr @stMsg,NULL,0,0
;.break .if eax == 0 ;stMsg为0,即收到WM_QUIT消息时退出
;invoke TranslateMessage,addr @stMsg
;invoke DispatchMessage,addr @stMsg
;.endw
;********************************************************************
;另一种消息循环,使用PeekMessage,异步的
;********************************************************************
.while TRUE
invoke PeekMessage,addr @stMsg,NULL,0,0,PM_REMOVE
.if eax != 0
.break .if @stMsg.message == WM_QUIT
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.else
;空闲时间,可以做其他处理工作
.endif
.endw
ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;程序入口点
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
运行结果:
2008030702.jpg
本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/03/07/1094952.html,如需转载请自行联系原作者