模仿win32的Hello,World程序:
.
386
.modelflat,stdcall
option casemap: none
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include文件定义
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
includewindows. inc
includegdi32. inc
includelibgdi32.lib
includeuser32. inc
includelibuser32.lib
includekernel32. inc
includelibkernel32.lib
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstancedd? ; 应用程序句柄
hWinMaindd? ; 窗口句柄
.const
szClassNamedb ' MyClass ' , 0 ; 窗口类名称
szCaptionMaindb ' MyfirstWindow! ' , 0 ; 窗口标题
szTextdb ' Hello,Win32Assembly!! ' , 0 ; 要显示的信息
szButtondb ' button ' , 0
szButtonTextdb ' 点我吧!! ' , 0
szMsgTitledb ' 信息 ' , 0
szErrorMsgdb ' 出错啦!! ' , 0
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 出错处理过程
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ErrorProcproc
invokeMessageBox,NULL,offsetszErrorMsg,offsetszMsgTitle,MB_OK
ret
_ErrorProcendp
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMainprocusesebxediesihWnd,uMsg,wParam,lParam ; 让汇编器保持子程序中使用到的寄存器的正确性
local @stPs: PAINTSTRUCT
local @stRect: RECT
local@hDc
mov eax,uMsg
; ********************************************************************
.ifeax==WM_CREATE
invokeCreateWindowEx,NULL,offsetszButton,offsetszButtonText,/
WS_CHILD or WS_VISIBLE, 100 , 100 , 65 , 50 ,hWnd, 1 ,hInstance,NULL
; ********************************************************************
.elseifeax==WM_PAINT
invokeBeginPaint,hWnd,addr@stPs
mov @hDc,eax
invokeGetClientRect,hWnd,addr@stRect
invokeDrawText,@hDc,addrszText,- 1 ,/ ; 长度设置为-1,表示输出的字符串以'/0'结尾,且由函数自动计算出其长度
addr@stRect,/
DT_SINGLELINE or DT_CENTER or DT_VCENTER
invokeEndPaint,hWnd,addr@stPs
; ********************************************************************
.elseifeax==WM_COMMAND
invokeMessageBox,NULL,offsetszText,offsetszMsgTitle,MB_OK
; ********************************************************************
.elseifeax==WM_CLOSE
invokeDestroyWindow,hWinMain
invokePostQuitMessage,NULL
; ********************************************************************
.else
invokeDefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
; ********************************************************************
xor eax,eax ; eax寄存器清零
ret
_ProcWinMainendp
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; WinMain函数
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMainproc
local @stWndClass: WNDCLASSEX
local @stMsg: MSG
invokeGetModuleHandle,NULL ; 获取应用程序句柄,这在VC里是通过操作系统传递进来的,但是汇编中需要自己去获取
mov hInstance,eax ; 获取到的应用程序句柄在eax中
invokeRtlZeroMemory,addr@stWndClass,sizeof@stWndClass ; 清零
; ********************************************************************
; 注册窗口类
; ********************************************************************
invokeLoadCursor, 0 ,IDC_ARROW ; 加载光标
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeofWNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset_ProcWinMain ; 设置窗口处理函数
; invokeGetStockObject,WHITE_BRUSH
; mov@stWndClass.hbrBackground,eax
mov @stWndClass.hbrBackground,COLOR_WINDOW+ 1
mov @stWndClass.lpszClassName,offsetszClassName
invokeRegisterClassEx,addr@stWndClass ; 注册窗口类
; ********************************************************************
; 建立并显示窗口
; ********************************************************************
invokeCreateWindowEx,WS_EX_CLIENTEDGE,offsetszClassName,offsetszCaptionMain,/
WS_OVERLAPPEDWINDOW,/
100 , 100 , 600 , 400 ,/
NULL,NULL,hInstance,NULL ; 创建窗口,发出一个WM_CREATE消息
mov hWinMain,eax ; 保存窗口句柄
invokeShowWindow,hWinMain,SW_SHOWNORMAL ; 显示窗口
invokeUpdateWindow,hWinMain ; 发出一个WM_PAINT消息
; ********************************************************************
; 第一种消息循环,使用GetMessage,同步的
; ********************************************************************
; .whileTRUE
; invokeGetMessage,addr@stMsg,NULL,0,0
; .break.ifeax==0;stMsg为0,即收到WM_QUIT消息时退出
; invokeTranslateMessage,addr@stMsg
; invokeDispatchMessage,addr@stMsg
; .endw
; ********************************************************************
; 另一种消息循环,使用PeekMessage,异步的
; ********************************************************************
.whileTRUE
invokePeekMessage,addr@stMsg,NULL, 0 , 0 ,PM_REMOVE
.ifeax!= 0
.break.if@stMsg.message==WM_QUIT
invokeTranslateMessage,addr@stMsg
invokeDispatchMessage,addr@stMsg
.else
; 空闲时间,可以做其他处理工作
.endif
.endw
ret
_WinMainendp
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 程序入口点
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invokeExitProcess,NULL
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
endstart
.modelflat,stdcall
option casemap: none
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include文件定义
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
includewindows. inc
includegdi32. inc
includelibgdi32.lib
includeuser32. inc
includelibuser32.lib
includekernel32. inc
includelibkernel32.lib
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstancedd? ; 应用程序句柄
hWinMaindd? ; 窗口句柄
.const
szClassNamedb ' MyClass ' , 0 ; 窗口类名称
szCaptionMaindb ' MyfirstWindow! ' , 0 ; 窗口标题
szTextdb ' Hello,Win32Assembly!! ' , 0 ; 要显示的信息
szButtondb ' button ' , 0
szButtonTextdb ' 点我吧!! ' , 0
szMsgTitledb ' 信息 ' , 0
szErrorMsgdb ' 出错啦!! ' , 0
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 出错处理过程
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ErrorProcproc
invokeMessageBox,NULL,offsetszErrorMsg,offsetszMsgTitle,MB_OK
ret
_ErrorProcendp
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMainprocusesebxediesihWnd,uMsg,wParam,lParam ; 让汇编器保持子程序中使用到的寄存器的正确性
local @stPs: PAINTSTRUCT
local @stRect: RECT
local@hDc
mov eax,uMsg
; ********************************************************************
.ifeax==WM_CREATE
invokeCreateWindowEx,NULL,offsetszButton,offsetszButtonText,/
WS_CHILD or WS_VISIBLE, 100 , 100 , 65 , 50 ,hWnd, 1 ,hInstance,NULL
; ********************************************************************
.elseifeax==WM_PAINT
invokeBeginPaint,hWnd,addr@stPs
mov @hDc,eax
invokeGetClientRect,hWnd,addr@stRect
invokeDrawText,@hDc,addrszText,- 1 ,/ ; 长度设置为-1,表示输出的字符串以'/0'结尾,且由函数自动计算出其长度
addr@stRect,/
DT_SINGLELINE or DT_CENTER or DT_VCENTER
invokeEndPaint,hWnd,addr@stPs
; ********************************************************************
.elseifeax==WM_COMMAND
invokeMessageBox,NULL,offsetszText,offsetszMsgTitle,MB_OK
; ********************************************************************
.elseifeax==WM_CLOSE
invokeDestroyWindow,hWinMain
invokePostQuitMessage,NULL
; ********************************************************************
.else
invokeDefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
; ********************************************************************
xor eax,eax ; eax寄存器清零
ret
_ProcWinMainendp
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; WinMain函数
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMainproc
local @stWndClass: WNDCLASSEX
local @stMsg: MSG
invokeGetModuleHandle,NULL ; 获取应用程序句柄,这在VC里是通过操作系统传递进来的,但是汇编中需要自己去获取
mov hInstance,eax ; 获取到的应用程序句柄在eax中
invokeRtlZeroMemory,addr@stWndClass,sizeof@stWndClass ; 清零
; ********************************************************************
; 注册窗口类
; ********************************************************************
invokeLoadCursor, 0 ,IDC_ARROW ; 加载光标
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeofWNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset_ProcWinMain ; 设置窗口处理函数
; invokeGetStockObject,WHITE_BRUSH
; mov@stWndClass.hbrBackground,eax
mov @stWndClass.hbrBackground,COLOR_WINDOW+ 1
mov @stWndClass.lpszClassName,offsetszClassName
invokeRegisterClassEx,addr@stWndClass ; 注册窗口类
; ********************************************************************
; 建立并显示窗口
; ********************************************************************
invokeCreateWindowEx,WS_EX_CLIENTEDGE,offsetszClassName,offsetszCaptionMain,/
WS_OVERLAPPEDWINDOW,/
100 , 100 , 600 , 400 ,/
NULL,NULL,hInstance,NULL ; 创建窗口,发出一个WM_CREATE消息
mov hWinMain,eax ; 保存窗口句柄
invokeShowWindow,hWinMain,SW_SHOWNORMAL ; 显示窗口
invokeUpdateWindow,hWinMain ; 发出一个WM_PAINT消息
; ********************************************************************
; 第一种消息循环,使用GetMessage,同步的
; ********************************************************************
; .whileTRUE
; invokeGetMessage,addr@stMsg,NULL,0,0
; .break.ifeax==0;stMsg为0,即收到WM_QUIT消息时退出
; invokeTranslateMessage,addr@stMsg
; invokeDispatchMessage,addr@stMsg
; .endw
; ********************************************************************
; 另一种消息循环,使用PeekMessage,异步的
; ********************************************************************
.whileTRUE
invokePeekMessage,addr@stMsg,NULL, 0 , 0 ,PM_REMOVE
.ifeax!= 0
.break.if@stMsg.message==WM_QUIT
invokeTranslateMessage,addr@stMsg
invokeDispatchMessage,addr@stMsg
.else
; 空闲时间,可以做其他处理工作
.endif
.endw
ret
_WinMainendp
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 程序入口点
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invokeExitProcess,NULL
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
endstart
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
运行结果: