🚀 汇编语言入门与实战(适用于 MASM + Irvine32)

高手文章:32位汇编语言程序设计基础知识 | Firefly

32位汇编指令速查表(MASM / x86) | Firefly

📖 第一章:什么是汇编语言?

汇编语言(Assembly Language)是一种面向机器结构简洁接近底层硬件的编程语言。

✅ 特点:

  • 每条汇编指令几乎一一对应一条机器指令(CPU 可执行)
  • 执行效率高,能直接控制硬件
  • 学习曲线较陡,但能深入理解计算机内部机制
  • 适合做性能优化、系统开发、嵌入式、驱动、病毒分析等

✅ 编写汇编程序所需工具:

工具 说明
MASM 微软宏汇编器(Microsoft Assembler)
Irvine32 教学用函数库,封装了输入输出、字符串、数字等操作

📁 第二章:汇编程序的基本结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
include irvine32.inc      ; 引入函数库,支持 call writeint 等

.data ; 数据段,声明变量
msg byte "Hello, World!", 0

.code ; 代码段,编写程序逻辑
main proc
mov edx, offset msg ; 加载字符串地址到 edx
call writestring ; 调用写字符串的函数
call crlf ; 输出换行
exit ; 正确退出程序
main endp

end main ; 指定程序入口为 main

🧠 小贴士:

  • .data 是“数据段”,用来存变量
  • .code 是“代码段”,程序主逻辑写在这里
  • proc/endp:定义一个过程(类似函数)
  • exit 是 Irvine32 的宏,不能使用 call exit

🧱 第三章:通用寄存器详解(32位)

寄存器 名称 常见用途
EAX Accumulator 累加器,通用计算、函数返回值
EBX Base 基址寄存器,通用变量保存
ECX Counter 计数器,loop 等指令自动减
EDX Data 数据传输、乘除法使用
ESI Source Index 源索引,数组读取时常用
EDI Destination Index 目标索引
EBP Base Pointer 基址指针,函数参数访问
ESP Stack Pointer 栈顶指针,系统自动维护

📌 哪些寄存器要保护?有规定!

这是汇编函数的约定俗成规则(Calling Convention)

寄存器 是否必须保护 说明
EAX, ECX, EDX ❌ 不要求保存 调用者要自己保存
EBX, ESI, EDI, EBP ✅ 必须保存 被调用者必须负责还原
ESP 🚫 永远不能乱动 控制栈的指针

🧾 第四章:变量与数据段定义

1
2
3
4
.data
num1 dword 100 ; 32位整型,初值100
arr dword 10, 20, 30 ; 定义数组
msg byte "Hi!", 0 ; 定义字符串,以0结束

✅ 关键指令与关键字:

  • dword(Double Word):4字节整型(32位)
  • byte:1字节数据
  • offset:获取变量地址(指针)

🔧 第五章:常用指令详解

📤 数据传送类

1
2
3
4
mov eax, 10          ; 将常数10放入eax
mov ebx, eax ; 把eax的值复制到ebx
mov eax, [arr] ; 取arr[0]的值放入eax
mov [arr+4], ebx ; 将ebx的值放入arr[1]

➕ 算术运算

1
2
3
4
5
add eax, 5           ; eax += 5
sub ebx, 2 ; ebx -= 2
inc ecx ; ecx++
dec ecx ; ecx--
imul eax, ebx ; eax *= ebx(有符号乘法)

⚖ 比较与跳转

1
2
3
4
5
cmp eax, ebx         ; 比较两数
je equal ; 相等则跳转
jne not_equal ; 不相等跳转
jg greater ; eax > ebx 跳转
jl less ; eax < ebx 跳转

🔁 第六章:循环结构

输出 1 到 5 的循环:

1
2
3
4
5
6
7
8
mov ecx, 5           ; 循环5次
mov eax, 1

loop_start:
call writeint
call crlf
inc eax
loop loop_start ; ecx自动减1,不为0则跳转

📞 第七章:过程调用与参数传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
main proc
push 7
call printNumber
exit
main endp

printNumber proc
push ebp
mov ebp, esp
mov eax, [ebp+8] ; 获取参数
call writeint
call crlf
pop ebp
ret 4 ; 弹出参数(1个参数=4字节)
printNumber endp

📌 第八章:数组操作基础

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.data
arr dword 1, 2, 3, 4

.code
mov esi, offset arr
mov ecx, 4
mov ebx, 0

loop_arr:
mov eax, [esi + ebx*4]
call writeint
call crlf
inc ebx
loop loop_arr
  • esi 是数组的起始地址
  • [esi + ebx*4] 表示访问第 ebx 个元素

🛑 第九章:正确退出程序

✅ 正确做法:

1
exit    ; 宏,自动结束程序

🚫 错误用法:

1
call exit    ; ❌ 不能调用 exit,这会出错

📤 第十章:Irvine32 输入输出函数

功能 指令
输出整数 mov eax, num + call writeint
输入整数 call readint(返回值存入 eax)
输出字符串 mov edx, offset msg + call writestring
换行 call crlf

📌 第十一章:调试技巧与建议

✅ 使用 Debugger(如 WinDbg / OllyDbg / VS 调试器)

  • 设置断点、单步执行,观察寄存器变化
  • Registers 面板观察 EAX/ECX 等值
  • Memory 面板查看 .data 中的数据变化

✅ 小技巧

  • 遇到异常退出,检查 call exit、栈平衡是否出错
  • 注意数组访问地址是否越界