模仿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
.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
运行结果: