🚀 汇编语言入门与实战(适用于 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
| 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
、栈平衡是否出错
- 注意数组访问地址是否越界