一个最简单程序 ,打印输出 Hello World
; 第一个汇编程序 HelloWorld.asm ; 注释一行
.386
.model flat, stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
szCaption db '这是一个新的开始!', 0
szMsg db 'Hello World!', 0
.code
start:
invoke MessageBox, NULL, addr szMsg, addr szCaption, MB_OK
invoke ExitProcess, NULL
end start
解释:
.386
.model flat, stdcall
.386 和 .model 都是是汇编伪指令, .386 表示使用 386 指令集,是 Win32 程序的最低需求. 类似的还有 .8086 .286 .386p .486 .486p .586 .586p .mmx 等,其中的 p 表示可以使用一些特权指令,.model 用于定义工作模式 flat 是内存模式,类似还有: tiny small medium compact large huge,Win32 程序只能选择 flat,stdcall 是语言模式,类似的还有: c syscall basic fortran pascal,使用 Win32 API 必须选择 stdcall
option casemap:none
表示区分大小写
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
user32.inc 和 kernel32.inc 中分别包含着对应 DLL 的函数、常量、结构的声明 windows.inc 包含着 Win32 程序用到的常量、结构的声明,比如下面用到的 MB_OK 常量就是在其中声明,程序在编译时,见到 include (伪)指令就会把它指定的 inc 文件(或 asm) 文件复制到当前位置,.inc 文件主要包含函数或常量的声明
lib 文件包含了动态库函数的地址信息和静态库的函数代码,程序在链接阶段会提取这些信息或代码 对 DLL(动态库),程序运行时会根据这些地址信息去调用 DLL 中的相应的函数
.data
szCaption db ‘Hi’, 0 ; 定义了字符串szCaption变量,赋初始值为 Hi ,0表示字符串的结束,db是变量的大小
szMsg db ‘Hello World!’, 0
.data 说明这是程序的数据段,下面的 .code 表示代码段,后面还会接触到 .const(常量段),.data?(变量段)等
.code
start:
invoke MessageBox, NULL, addr szMsg, addr szCaption, MB_OK
invoke ExitProcess, NULL
end start
这里的start 是随便命名的标号, 用于表示程序段的开始和结束
这段程序用到了两个 API 函数: MessageBox(显示消息框)、ExitProcess(退出程序),这两个函数分别来自 user32.dll 和 kernel32.dll
invoke 是调用函数或子过程的伪指令
addr 是取地址的伪指令,这里也可以换做 offset
最后:
在当前工作路径下进行编译链接来生成可执行的.exe文件
ml -c -coff HelloWorld.asm 生成HelloWorld.obj文件
link -subsystem:windows HelloWorld.obj 生成HelloWorld.exe文件