第一个程序:环境搭建与 Hello World

学习汇编需要实际动手写代码、运行、调试。这一篇讲如何搭建环境、编译、运行汇编程序。

环境选择

8086 汇编是 16 位实模式程序,现代 Windows/Linux/macOS 不能直接运行,需要通过 DOS 模拟器。

推荐方案:DOSBox + MASM(经典组合,王爽教材使用的就是这个环境)。

方式一:VS Code 插件(推荐,最方便)

  1. 在 VS Code 中安装 MASM/TASM 插件
  2. 新建一个文件夹作为项目目录,用 VS Code 打开
  3. Ctrl+Shift+P,搜索 “Open Settings (JSON)“,打开项目的 settings.json
  4. 粘贴以下配置:
{
  "masmtasm.ASM.emulator": "msdos player",
  "masmtasm.dosbox.run": "exit",
  "masmtasm.ASM.assembler": "MASM-v5.00",
  "masmtasm.ASM.actions": {
    "MASM-v5.00": {
      "baseBundle": "/MASM-v5.00.jsdos",
      "before": [
        "set PATH=C:\\MASM"
      ],
      "run": [
        "masm ${file};",
        "link ${filename};",
        ">${filename}"
      ],
      "debug": [
        "masm ${file};",
        "link ${filename}.OBJ;",
        ">debug ${filename}.exe"
      ],
      "support": ["jsdos", "dosbox", "dosboxX", "msdos player"]
    }
  }
}
  1. 新建 .asm 文件,右键选择 “Run ASM” 运行,或 “Debug ASM” 调试

方式二:DOSBox + MASM(手动配置)

  1. 下载安装 DOSBox 和 MASM 编译工具包
  2. 创建工作目录,如 D:\DOS\MASM\test
  3. 将 MASM 的编译工具(masm.exe、link.exe、debug.exe 等)放到该目录
  4. 运行 DOSBox,输入以下命令挂载目录:
mount c D:\DOS\MASM
c:
path c:\
  1. 为了避免每次启动都输入,可以配置 DOSBox 的自动执行:
    • 找到 DOSBox 0.74-3 Options.bat,双击打开配置文件
    • 拉到最底部的 [autoexec] 部分,添加上述 mount 和 path 命令
    • 保存后每次启动 DOSBox 就自动挂载好了

常见问题

路径问题

  • 路径中不要包含中文或空格,否则 DOSBox 可能找不到文件
  • 如果 VS Code 提示找不到 DOSBox,在插件设置中手动指定 dosbox.exe 的路径
  • 修改设置后必须重启 VS Code 才生效

最小可运行程序

assume cs:code

code segment
start:
    ; 这里写你的代码
    mov ax, 4c00H    ; 程序退出,AH=4CH 是DOS退出功能号
    int 21H          ; 调用 DOS 系统中断
code ends

end start

编译运行流程

源文件(.asm) → masm编译 → 目标文件(.obj) → link链接 → 可执行文件(.exe) → 运行/调试

在 DOSBox 中手动编译运行:

masm test.asm;      ; 编译(; 表示跳过中间提问,用默认值)
link test.obj;      ; 链接
test.exe            ; 运行
debug test.exe      ; 用 debug 调试

debug 调试命令

debug 是 DOS 自带的调试工具,学习汇编一定要会用:

命令功能示例
r查看/修改寄存器值r 查看所有,r ax 修改 AX
d查看内存内容(Dump)d 1000:0 查看段地址1000偏移0处的内存
e修改内存内容(Edit)e 1000:0 01 02 03 写入数据
u反汇编(Unassemble)u 将内存内容翻译成汇编指令
t单步执行(Trace)t 执行一条指令,进入中断内部
p单步执行(不进入中断)p 遇到 int 21H 时用这个,不会进入中断
g连续执行(Go)g 执行到程序结束,g 0012 执行到偏移0012处
a写入汇编指令(Assemble)a 1000:0 直接在内存中输入汇编指令
q退出 debugq

t 和 p 的区别

  • t(Trace):单步进入,遇到 int 21Hcall 会进入子程序内部
  • p(Proceed):单步跳过,遇到中断或子程序会一次执行完,不会进去 一般调试时大部分用 t,遇到 int 21H 这种系统中断用 p

程序退出

每个程序都必须正确退出返回 DOS,否则 CPU 会继续执行后面的内存内容导致崩溃:

mov ax, 4c00H    ; AH = 4CH(DOS退出功能号),AL = 00H(返回码,0表示正常)
int 21H          ; 调用 21H 号 DOS 中断

不要忘记退出!

如果没有这两行,CPU 执行完你的代码后会继续往下跑,把后面内存中的数据当成指令执行,大概率死机或崩溃。

写一个能看到效果的程序

直接操作显存显示字符(详见 显存部分):

assume cs:code

code segment
start:
    mov ax, 0B800H
    mov es, ax          ; ES 指向显存段地址 B800H
    mov bx, 0           ; 偏移地址从0开始(屏幕左上角)

    ; 在屏幕中央显示一个字符 'A',白底黑字
    mov byte ptr es:[bx],   'A'      ; 字符
    mov byte ptr es:[bx+1], 70H      ; 属性:白底(7)黑字(0),0表示不闪烁

    mov ax, 4c00H
    int 21H
code ends

end start

debug 查看显存的注意事项

在 DOSBox 中用 d B800:0 看显存时,数据会不停变化——因为 DOSBox 本身也在用显存显示你输入的内容,这不是你的程序有问题。

相关