经常使用的32位汇编编译器有微软的MASM、Borland的TASM和NASM。html
编译器 | 开发者 | 优势 | 缺点 |
MASM | 微软 | 微软自家软件和系统兼容性好;支持invoke/.if等伪指令将汇编变得和C++差很少 | 就一个编译器,没有资源编译器和连接器,也没有头文件 |
TASM | Borland | 支持伪指令,有资源编译器和连接器 | 没有Windows数据结构和预约义的头文件,如今官方彷佛不维护了 |
NASM | 开源 | 同时支持Windows和Linux | 不支持伪指令,没有Windows数据结构和预约义的头文件 |
不过他们各有本身的不足,通常使用基于MASM的MASM32 SDK作为开发环境;虽然叫masm32 可是直接装在64位操做系统上也是没问题的。编程
下载连接:http://www.masm32.com/download.htmwindows
当前我下载的是v11r版本,将下载的zip包解压后获得的是一个齿轮图标的install.exe文件,双击运行开始安装。安全
选择安装的磁盘(masm32 sdk须要安装在根目录下因此只能选磁盘不能自定义目录)数据结构
后续一路点“肯定”、“Yes”或“OK”就好了,直到下图所示即完成安装。ui
打开:控制面板--系统和安全--系统--高级系统设置--高级--环境变量spa
建立如下环境变量(若是已存在则在其末尾追加,Masm32Dir根据本身安装路径修改):操作系统
Masm32Dir=D:\masm32 include=%Masm32Dir%\Include; lib=%Masm32Dir%\lib; path=%Masm32Dir%\Bin;%Masm32Dir%;
无论什么语言开发,咱们习惯于有一个IDE以方便编写、编译、连接、调试,MASM32 SDK自带有一个IDE----Quick Editor(安装完后在桌面创的那个快捷方式就是),但它实质就只是一个简单的文本编缉器,实际上32位汇编当前就没有什么IDE(RadASM和MASMPlus没用过不过感受也不是咱们认识的那种IDE)。.net
32位汇编开发通常都是用UtralEdit或Notepad++等文本编缉器编写代码文件和资源文件,而后手动敲命令进行编译连接(下节咱们会演示这个过程)。设计
其实没有IDE这样手动也不全是坏事,既然都学汇编了不如索性全手动。
资源文件helloworld.rc:
// 资源文件注释格式为双斜杠 // 包含资源头文件,以能使用头键字 #include <resource.h> // 指定对话框ID,asm文件中要定义同值变量才可引用 #define DLG_HELLOWORLD 1 // 定义对话框结构 DLG_HELLOWORLD DIALOG 350,200,213,164 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Helloworld Program" FONT 11,"宋体" { CTEXT "Win32 Assembly Helloworld Program",-1,50,54,170,21 CONTROL "",-1,"Static",SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE,6,79,203,1 DEFPUSHBUTTON "退出",IDOK,158,86,50,21 }
代码文件helloworld.asm:
; asm文件注释格式为分号 ; 定义程序模式 .386 .model flat,stdcall option casemap :none ; 包含必要头文件,基本每一个win32 汇编程序都须要包含这几个 include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib ; 指定对话框ID,该ID要与rc文件中的ID值相同 ; 理论上,asm文件与rc文件中的控件是经过ID值关联的,控件名并不须要与rc文件相同,不过为了易看通常取同样的 ; 好比这里重点是equ 1,叫不叫DLG_HELLOWORLD无所谓,不过为了易看因此选择与rc文件保持一致 DLG_HELLOWORLD equ 1 ; 数据段 .data? hInstance dd ? ; 代码段 .code ; 对话框处理过程 _ProcDlgHelloworld proc uses ebx edi esi hWnd,wMsg,wParam,lParam mov eax,wMsg .if eax == WM_CLOSE invoke EndDialog,hWnd,NULL .elseif eax == WM_INITDIALOG ;invoke LoadIcon,hInstance,ICO_MAIN ;incoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax .elseif eax == WM_COMMAND mov eax,wParam .if ax == IDOK invoke EndDialog,hWnd,NULL .endif .else mov eax,FALSE ret .endif mov eax,TRUE ret _ProcDlgHelloworld endp start: invoke GetModuleHandle,NULL mov hInstance,eax ; 弹出对话框,对话框与及处理过程在这里绑定 invoke DialogBoxParam,hInstance,DLG_HELLOWORLD,NULL,offset _ProcDlgHelloworld,NULL invoke ExitProcess,NULL ; 指定程序入口点为start标识处 end start
我这里将两个文件保存在了F:\masm32\helloworld目录下,编译运行以下:
rc helloworld.rc ml /c /coff helloworld.asm link /subsystem:windows helloworld.obj helloworld.res helloworld.exe
程序运行界面以下:
所谓借助vc其借助之处有二:一是直接用vc来编写资源文件,二能够借用nmake.exe来进行编译连接。
在前面helloworld中咱们直接手动编写资源文件(helloworld.rc),这种方式因为不是所见即所得在实际编写时为了调整位置和大小,须要反复进行修改编译运行,这是比较麻烦的。咱们可使用vc进行所见即所得的资源文件编缉。
不过VC++编缉.rc文件保存时会自动添加一些VC++的头文件若是继续保存为.rc文件,为了保证使用rc命令编译成.res时能找到全部文件,须要把VC++的%VC_HOME%\VC98\Include目录追加到第3步中的include环境变量中,把%VC_HOME%\VC98\Lib目录追加到第3步中的lib环境变量中;固然也能够在编缉后直接保存成编译好的.res文件,免去rc编译步骤。
能够建一个VC项目来编缉资源文件最后把复制出来用,也能够先编译出一个res文件而后托到vc里编缉。
在前面helloworld程序中,咱们经过rc、ml和link三条命令进行编译连接,每次改动都得反复敲打执行这几条命令这是比较麻烦的。
nmake能够直接根据makefile执行rc、ml和link完成程序编译连接(makefile放于与源代码同级目录下,在makefile目录下执行nmake),若是是一个比较大的须要反复修改的程序建议使用nmake进行编译连接。操做过程以下:
第一步,到%VC_HOME%\VC98\Bin目录下把nmake.exe复制到%Masm32Dir%\Bin目录下。
第二步,编写makefile。
第三步,进行编译运行。
之前边helloworld程序为例,makefile以下:
EXE = helloworld.exe #指定输出文件 OBJS = helloworld.obj #须要的目标文件 RES = helloworld.res #须要的资源文件 LINK_FLAG = /subsystem:windows #链接选项 ML_FLAG = /c /coff #编译选项 $(EXE): $(OBJS) $(RES) Link $(LINK_FLAG) $(OBJS) $(RES) .asm.obj: ml $(ML_FLAG) $< .rc.res: rc $< clean: del *.obj del *.res
编译运行以下(每次修改至关于只须要执行nmake一条命令操做简单多了):
参考: