1 环境
操作系统:windows 10 2004
工具:VS2019、MASM32
2 如何编译汇编程序
启动 VS2019,点击创建新项目,再点击创建空项目,如下所示:

创建好了之后,先不要急着创建新文件,这时需要先做一个操作,右键项目,在生成依赖中点击生成自定义,如下所示:

在弹出的生成自定义选项中在 masm 前面打上勾,因为后面我们创建的 asm 文件需要 masm 编译器,如下所示:

下面我们就可以创建 asm 文件写汇编代码了,如下所示:

为了更好的阅读我们写的汇编代码,需要安装一个汇编语言的语法高亮插件,点击扩展菜单栏中管理扩展选项,在插件市场中下载,插件名为 AsmDude,如下所示:

安装会要求重启 VS2019,重启后便可以开始愉快编写汇编代码了,最终尝试编译链接,如下所示:

示例代码:
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
.code
main PROC
mov eax, 5
add eax, 6
invoke ExitProcess, 0
main ENDP
END main
如何调试
在需要调试的地方打上断点,按 F5 启动调试,如下所示:

下面来说下 win32 汇编程序。
3 如何编译 win32 汇编程序
win32 汇编程序比上面简单的汇编程序有所不同,因为此类程序必须涉及到 win32 API,所以在编写这类程序时需要用到 MASM32 SDK 工具包,此工具包下载地址:http://www.masm32.com/download.htm,工具包安装也很简单,一路同意 next 即可,安装好目录如下所示:

其中 include 和 lib 这两个文件夹里的文件待会就会用到。include 文件夹里包含了各种 inc 文件,而 inc 文件里包含了 API 函数的声明;lib 文件夹则包含了许多 lib 文件,这此 lib 文件是存放着 API 函数的信息,在链接时需要用到。在 VS2019 中新建一个空项目,生成自定义项中勾上 masm,再新建一个 asm 文件,在文件中输入以下示例代码:
.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 Windows !',0
szText db 'Win32 Assembly, Simple and powerful !',0
; 代码段
.code
_ProcWinMain proc uses ebx edi esi, hWnd, uMsg, wParam, lParam
local @stPs:PAINTSTRUCT
local @stRect:RECT
local @hDc
mov eax,uMsg
.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
_ProcWinMain 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 _ProcWinMain
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
在编译链接前需要做几个设置,首先在项目属性上,在 Microsoft Macro Assembler 中的 Include Paths 选项中,将 MASM32 SDK 安装目录下的 include 路径填在该处,如下所示:

同时将 lib 所在的目录填写在链接器中的附加库目录中,如下所示:

上述一切准备就绪,编译链接,一定会失败,为什么,我们来看下出错提示:

其实这个问题当时也困扰了我好久,在这里我来说明下原因,问题出在 MSVC 的版本,过高的 MSVC,masm 不支持,所以只需把 MSVC 降版本号就可以了,如何降,在项目属性页中高级,MSVC 工具集版本,选择低于 14.26 以下即可,如下所示:

如果看不到这些下拉选项,说明你没安装,这时你需要退出 vs2019,打开 vs installer,在单个组件里选择相应 MSVC 版本然后进行修改即可,除了此问题外,还有一个小问题,是语法高亮插件,此插件会提示你找不到相应的 inc 文件,这种你只要把它忽略就可以,因为这是插件的 BUG,目前已有人在插件的 Github 上提了 issue,待作者改善修复。编译链接后如下所示:

运行如下所示:

Release 版的仅为 4KB 大。
(本文完)
必须 注册 为本站用户, 登录 后才可以发表评论!