第三章 汇编语言基础
本章聚焦 Microsoft MASM 汇编程序的基础组成,目标是:
- 常数、变量的定义方式;
- 数字和字符常量的格式;
- 汇编程序的编写、运行流程;
- 利用 Visual Studio 调试器分析程序,调试的重要性。
汇编语言以 “硬件透明性” 著称:
- 优势:程序员能直接观察 CPU 寄存器、标志位等硬件状态,对程序运行细节完全掌控;
- 代价:需手动处理 数据表示细节(如进制、类型)和 指令格式(如语法、操作数规则),开发层次更贴近硬件。
基本语言元素
第一个汇编程序
汇编程序:AddTwo 解析:
程序功能:计算 5+6,结果存入寄存器:
1: main PROC
2: mov eax,5 ; 将数字5送入eax寄存器
3: add eax,6 ; eax寄存器加6
4:
5: INVOKE ExitProcess,0 ; 程序结束
6: main ENDP
行号 | 代码 | 功能解释 |
---|---|---|
1 | main PROC | 定义名为 main 的过程(程序入口) |
2 | mov eax, 5 | 将数字 5 送入 eax 寄存器 |
3 | add eax, 6 | eax 寄存器的值加 6 (结果为 11 ) |
5 | INVOKE ExitProcess, 0 | 调用系统函数退出程序(参数 0 表示正常退出) |
6 | main ENDP | 结束 main 过程 |
- 寄存器
eax
:- x86 架构的通用寄存器,常用于算术运算(此处作为“累加器”存储中间结果)。
- 指令语法:
mov
是数据传送指令(目的操作数, 源操作数
);add
是加法指令(目的操作数 += 源操作数
);INVOKE
是 MASM 伪指令,用于调用系统函数(需提前引入相关库,本章后续会补充)。
- 程序缺陷:
当前代码 无法直接运行,因为缺少 环境声明(如引入 Windows 系统头文件、定义程序入口点等)。
程序结构:数据段与代码段分离
汇编程序通过 “段标记” 区分 数据存储区 和 指令执行区:
.data
段:专门存放变量(如sum
),属于静态数据区;.code
段:专门存放可执行指令(如mov
、add
),属于代码执行区。
数据段:变量 sum
的定义
1: .data ; 标记数据段开始(存放变量、常量)
2: sum DWORD 0 ; 定义变量 sum:
; - 名称:sum
; - 类型:DWORD(32 位,4 字节,相当于 C 的 unsigned int 或 int)
; - 初始值:0
3:
DWORD
的意义:
汇编中是 “大小关键字”,仅规定变量占 32 位内存,不限制存储内容(可以是整数、地址、二进制数据等),与 C/C++ 的int
不同(后者隐含类型检查)。
类似关键字还有:BYTE
(8 位)、WORD
(16 位)、QWORD
(64 位)等。
代码段:指令执行流程
4: .code ; 标记代码段开始(存放可执行指令)
5: main PROC ; 定义过程 main(程序入口,类似 C 的 main 函数)
6: mov eax,5 ; ① 将 5 送入 eax 寄存器
7: add eax,6 ; ② eax = 5 + 6 = 11
8: mov sum,eax ; ③ 将 eax 的值(11)存入变量 sum
9:
10: INVOKE ExitProcess,0 ; ④ 调用系统函数退出程序(参数 0 表示正常退出)
11: main ENDP ; 结束过程 main
汇编与高级语言的核心差异
类型的“弱约束”:
汇编的DWORD
只规定内存大小,不检查数据含义(比如可以存整数11
,也可以存地址0x0000000B
),完全由程序员控制。
而 C 的int
隐含“整数”的语义,编译器会做类型检查。直接操作硬件:
指令mov eax,5
直接操作 CPU 寄存器eax
,mov sum,eax
直接操作内存变量,体现了汇编 “硬件级可控” 的特点。
程序的进化:从“寄存器存结果”到“变量存结果”
- 前序例子中,加法结果仅存于
eax
寄存器(程序退出后数据丢失); - 本例子通过 定义变量
sum
并执行mov sum,eax
,将结果永久存入内存(数据区),更贴近实际程序的“数据持久化”需求。
综上,这段代码体现了汇编语言 “底层可控、类型弱约束” 的核心特性。
整数变量
整数常量(整数字面量)由三部分构成:
[{+ | -}] digits [ radix ]
{+ | -}
:可选符号(+
或-
,二选一,大括号表示必选其一);digits
:数字序列(必填,如123
、FF
等);[radix]
:可选基数字符(标记进制,方括号表示可选)。
语法符号说明(Microsoft 约定)
- 方括号
[]
:内部内容可选(可写可不写); - 大括号
{}
+|
:内部是互斥选项,必须选其中一个(如{+ | -}
表示选+
或-
); - 斜体
digits
:需替换为具体值(如实际数字12
、AB
等)。
基数字符与对应进制
MASM 通过 后缀字符 标记整数的进制,常用规则如下(表格梳理):
基数字符 | 对应进制 | 示例 | 说明 |
---|---|---|---|
h | 十六进制 | 1Ah 、0A3h | 字母开头需加前置 0 (见下文) |
q / o | 八进制 | 42q 、42o | q 避免与数字 0 混淆 |
d | 十进制 | 26 、26d | 可省略(默认十进制) |
b | 二进制 | 11010011b | 必须显式添加 b |
备注:表格中 r
(编码实数)、t
(十进制备用)、y
(二进制备用)较少使用,优先记常用符号。
示例
常量 | 基数字符 | 进制 | 十进制值计算 | 说明 |
---|---|---|---|---|
26 | 无 | 十进制 | 26 | 默认十进制 |
26d | d | 十进制 | 26 | 显式标记十进制 |
11010011b | b | 二进制 | 1*2⁷+1*2⁶+0+1*2⁴+0+0+1*2¹+1=211 | 必须加 b ,否则当十进制 |
42q | q | 八进制 | 4*8 + 2 = 34 | q 代表八进制 |
42o | o | 八进制 | 4*8 + 2 = 34 | o 也代表八进制 |
1Ah | h | 十六进制 | 1*16 + 10 = 26 | A 是十六进制数字(10) |
0A3h | h | 十六进制 | 0*16² + 10*16 + 3 = 163 | 以字母 A 开头,需加前置 0 (否则汇编器会误判为标识符) |
- 十六进制的特殊处理:
若十六进制数 以字母开头(如Ah
、B3h
),必须加 前置0
(如0Ah
、0B3h
),否则汇编器会将其视为标识符(如变量名),导致语法错误。
整数常量表达式
整型常量表达式是 仅包含整数常量和算术运算符 的表达式,在汇编阶段(编译时)计算,结果必须是 32 位整数(范围:0 ~ FFFFFFFFh
,即无符号 0~2³²⁻¹,或有符号 -2³¹~2³¹⁻¹,取决于上下文)。
算术运算符与优先级
MASM 规定运算符优先级 从高到低 如下(优先级数字越小,执行越早):
优先级 | 运算符 | 名称 | 说明 | 示例 |
---|---|---|---|---|
1 | () | 圆括号 | 强制改变运算顺序 | (4+2)*6 先算括号 |
2 | + (一元)、- (一元) | 一元加、减 | 对单个操作数取符号 | -5 (把 5 变为 -5) |
3 | * 、/ 、MOD | 乘、整数除、取模 | 除法截断小数,模取余数 | 16/5=3 ,25 MOD 3=1 |
4 | + (二元)、- (二元) | 加、减 | 对两个操作数运算 | 5-3 |
示例
表达式的执行顺序 由优先级决定,优先级相同则 从左到右 计算:
4 + 5 * 2
:- 优先级:
*
(3)>+
(4)→ 先算5*2=10
,再算4+10=14
。
- 优先级:
12 - 1 MOD 5
:- 优先级:
MOD
(3)>-
(4)→ 先算1 MOD 5=1
,再算12-1=11
。
- 优先级:
-5 + 2
:- 优先级:
-
(一元,2)>+
(4)→ 先算-5
(一元减),再算-5+2=-3
。
- 优先级:
(4 + 2) * 6
:- 括号强制优先级 → 先算
4+2=6
,再算6*6=36
。
- 括号强制优先级 → 先算
四、有效表达式的值计算(细节拆解)
下表中表达式的计算需结合 整数运算规则(除法截断、模取余):
表达式 | 计算步骤 | 结果 |
---|---|---|
16/5 | 整数除法:16÷5=3.2 → 截断小数,得 3 | 3 |
-(3+4)*(6-1) | ① 括号:3+4=7 ,6-1=5 ;② 一元减:-7 ;③ 乘法:-7*5=-35 | -35 |
-3 + 4*6 - 1 | ① 乘法:4*6=24 ;② 从左到右加减:-3+24=21 ,21-1=20 | 20 |
25 mod 3 | 整数取模:25÷3 商 8 余 1 → 得 1 | 1 |
五、实用建议:用括号明确顺序
汇编器严格遵循优先级,但 人类容易记错规则。因此:
尽量用圆括号包裹运算子表达式,明确执行顺序(如
(a + b) * c
比a + b * c
更直观),减少调试成本。
掌握整型常量表达式的核心是 理解优先级对运算顺序的影响,以及 汇编时计算(编译期确定值) 的特性。这决定了表达式只能用常量(不能用变量),且结果在编译阶段就被替换,是汇编优化的基础。