在ARM架构(尤其是Cortex-M系列MCU)的汇编中,伪指令(Pseudo-Instructions)是由汇编器解释的特殊指令,用于定义数据、符号、代码结构或控制汇编过程。以下是常用的ARM汇编伪指令分类及说明:
一、数据定义伪指令
用于定义数据常量、变量或缓冲区,不生成机器码,仅在汇编时分配内存。
伪指令 | 功能 | 语法示例 |
---|---|---|
DCB |
定义字节数据(Byte,1字节),可存储字符或数值。 | MyData DCB 0x10, 'A', 0xFF |
DCD /DCWU |
定义字数据(Word,4字节,小端模式),DCWU 用于无符号字。 |
MyWord DCD 0x12345678 |
DCW /DCWH |
定义半字数据(Half-Word,2字节,小端模式),DCWH 用于无符号半字。 |
MyHalfWord DCW 0x1234 |
SPACE |
分配一段未初始化的内存空间(以字节为单位)。 | Buffer SPACE 100 (分配100字节) |
EQU |
定义符号常量(等价于C语言的#define )。 |
COUNT EQU 100 |
LTORG |
声明一个文字池(Literal Pool),用于存储常量表达式。 | LTORG (通常放在代码段末尾) |
二、符号定义伪指令
用于声明全局/局部符号、变量或标签。
伪指令 | 功能 | 语法示例 |
---|---|---|
GBLA |
定义全局算术变量(初始值为0)。 | GBLA MyGlobalVar |
GBLL |
定义全局逻辑变量(初始值为FALSE )。 |
GBLL MyFlag |
LCLA |
定义局部算术变量(当前代码块内有效)。 | LCLA My localVar |
LCLS |
定义局部符号(避免符号冲突)。 | LCLS MyLabel |
EXPORT |
导出符号,供其他文件使用(等价于GLOBAL )。 |
EXPORT MyFunction |
EXTERN /IMPORT |
声明外部符号(来自其他文件)。 | EXTERN Main (调用外部函数Main) |
三、段定义伪指令
用于组织代码段(Code Section)和数据段(Data Section)。
伪指令 | 功能 | 语法示例 |
---|---|---|
AREA |
定义代码段或数据段,指定段名、属性(如CODE , DATA )。 |
AREA MyCode, CODE, READONLY |
ENTRY |
指定程序入口点(一个汇编文件最多一个ENTRY )。 |
ENTRY (通常放在第一个执行的代码前) |
END |
标记汇编文件结束,必须放在文件末尾。 | END |
ALIGN |
按指定字节数对齐(如4字节对齐,确保字访问效率)。 | ALIGN 4 (当前地址对齐到4字节边界) |
ORG |
指定后续指令或数据的起始地址(Origin)。 | ORG 0x08000000 (从0x08000000开始) |
四、流程控制伪指令
用于条件汇编(非运行时流程控制,而是汇编时的代码生成控制)。
伪指令 | 功能 | 语法示例 |
---|---|---|
IF , ELSE , ENDIF |
条件汇编,根据逻辑表达式决定是否包含代码块。 | IF :DEF: DEBUG<br> DEBUG_CODE<br>ELSE<br> RELEASE_CODE<br>ENDIF |
WHILE , WEND |
循环汇编,重复生成代码直到条件不满足。 | WHILE Count < 10<br> DCD Count<br> Count SETA Count + 1<br>WEND |
SET{A/L} |
给算术/逻辑变量赋值(SETA 赋数值,SETL 赋逻辑值)。 |
MyVar SETA 100 |
五、汇编控制伪指令
用于包含文件、调试或控制汇编器行为。
伪指令 | 功能 | 语法示例 |
---|---|---|
INCLUDE |
包含头文件(如寄存器定义)。 | INCLUDE "stm32f4xx.h" |
ASSERT |
汇编时检查条件,不满足则报错。 | ASSERT Count > 0 (Count必须>0) |
INFO |
汇编时输出信息(调试用)。 | INFO "Compiling for Cortex-M4" |
TTL |
定义汇编文件标题(可选)。 | TTL MyProgram.s |
六、特殊伪指令(与指令同名但功能不同)
这些伪指令借用指令名称,但由汇编器处理,用于生成特定操作。
伪指令 | 功能 | 语法示例 |
---|---|---|
LDR |
加载32位立即数或地址到寄存器(当立即数无法用MOV 表示时使用)。 |
LDR R0, =0x12345678 (给R0赋0x12345678) |
NOP |
生成空操作(实际生成MOV R0, R0 或类似指令)。 |
NOP |
ADR |
加载相对地址到寄存器(计算PC相对偏移,生成更紧凑的代码)。 | ADR R1, MyLabel (R1=MyLabel的地址) |
ADDR |
计算符号地址与偏移量的和(用于复杂地址计算)。 | ADDR R2, PC, #4 (R2=PC+4) |
七、Cortex-M系列MCU常用场景
中断向量表定义
AREA VectorTable, DATA, NOINIT, ALIGN=2 EXPORT __Vectors __Vectors DCD 0x20001000 ; 栈顶地址 DCD Reset_Handler ; 复位中断向量 DCD NMI_Handler ; 非屏蔽中断向量 ; 其他中断向量...
常量与寄存器定义
NVIC_INT_CTRL EQU 0xE000ED04 ; NVIC中断控制寄存器地址
条件编译(调试与发布版本)
GBLL DEBUG_MODE DEBUG_MODE SETL TRUE ; 调试模式开启 IF DEBUG_MODE AREA DebugData, DATA, READWRITE DebugBuffer SPACE 1024 ENDIF
注意事项
- 汇编器差异:不同工具链(如GNU AS、ARM ADS、Keil MDK)的伪指令语法可能略有不同(例如
GLOBAL
等价于EXPORT
,EXTERN
等价于IMPORT
)。 - 大小写敏感:ARM汇编通常区分大小写,伪指令一般为小写(如
area
无效,需用AREA
)。 - 参考文档:具体使用时需参考工具链文档(如GNU AS手册或ARM官方文档)。
通过合理使用伪指令,可以高效组织代码结构、定义数据和符号,这是编写MCU底层驱动(如启动文件、中断处理)的基础。