news 2026/10/15 21:18:11

汇编语言|常用伪指令(ARM 汇编入门)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
汇编语言|常用伪指令(ARM 汇编入门)

前言 汇编语言分为指令语句和伪指令语句。

  1. 指令语句:汇编后生成 CPU 可以直接执行的机器目标代码,由 CPU 运行。
  2. 伪指令语句:不会产生任何机器码,CPU 不会执行伪指令。伪指令是给汇编器、链接器使用的控制命令,用来完成段划分、内存分配、符号别名定义、多文件之间互相调用等编译相关工作。

ARM 汇编书写硬性规范

  1. CPU 指令助记符,例如MOV、ADD、SUB、LDR、STR、BL、BX属于保留关键字,绝对不能作为自定义标号,就算加上冒号也会编译报错。
  2. 自定义标号后面必须加冒号:虽然 ARM 汇编语法允许省略冒号,但省略后极易把标号误认为指令,作业、考试一律书写冒号。
  3. CPU 指令、伪指令(AREA、ENTRY、EQU、DCD、SPACE等)后面不能加冒号。
  4. 尽量不要使用伪指令名称作为自定义标号,部分汇编器虽然可以编译通过,但可读性差,存在歧义风险。
  5. ARM 汇编符号区分大小写。

1. EQU 等值赋值伪指令

格式

标号 EQU 操作数

功能:给数字或者内存地址定义别名,本质是文本替换,不占用任何内存单元,整个源文件内该标号的值固定不变。

;示例1:给内存地址0x1000设置别名 AREA_ADDR EQU 1000H ;示例2:定义程序使用的数值常量 MAX_NUM EQU 50 MASK EQU 0x0F ;代码中直接使用别名,汇编器自动替换成对应数值 MOV R0,#AREA_ADDR ;等价于 MOV R0,#0x1000 MOV R1,#MAX_NUM ;等价于 MOV R1,#50

2. AREA 段定义伪指令(ARM 汇编专属)

格式

AREA 段名,属性1,属性2……

功能:把程序划分成多个独立模块,称为 “段”。有的段存放执行代码,有的段存放变量数据;同时可以设置段的读写权限、内存对齐、是否初始化。

表格

属性说明
CODE存放 CPU 执行指令,默认属性为READONLY只读
DATA存放变量与数据,默认属性为READWRITE可读可写
READONLY内存只允许读取,不可修改
READWRITE内存可读,允许修改写入
NOINIT程序启动时,该段内存不做初始化
ALIGN=n内存对齐字节 = \(2^n\);例如ALIGN=3代表 8 字节对齐
;定义只读代码段,存放程序指令 AREA CODE_SEG, CODE, READONLY ENTRY START: MOV R0,#0 ;定义可读可写数据段,存放运行时会修改的变量 AREA DATA_SEG, DATA, READWRITE DATA_BUF SPACE 100

3. ENTRY 程序入口伪指令

格式

ENTRY

功能:告诉链接器,CPU 上电复位后,从此标记位置开始执行程序。

注意:ENTRY 仅作为标记,不生成机器码;一个工程至少要有一个ENTRY,必须写在CODE代码段内部。

AREA MY_CODE,CODE,READONLY ENTRY ;伪指令,标记程序入口,无冒号 START: MOV R1,#1 ADD R2,R1,#2 END

4. ORG 地址定位伪指令(51、x86 汇编常用,ARM 很少使用)

格式

ORG 绝对地址

功能:修改汇编位置计数器,指定后续代码、数据存放的起始内存地址;直到遇见下一条ORG指令,地址才会重新改变。

ORG 8000H ;下面所有内容,从内存0x8000地址开始存放 ADD R1,#1 MOV R2,#2 ORG 0x2000 ;切换存储起始地址,后续数据存放在0x2000之后 DATA_BUF1: DB 0x11,0x22

5. DB / DW 数据定义伪指令

  • DB:定义1 字节(8bit)数据,可以存放数字、ASCII 字符。 格式:[标号:] DB 字节常数 | 字符 | 表达式
  • DW:定义16 位字(2 字节)数据,用法与 DB 完全相同。
ORG 8000H DATA1: DB 43H,09H,08H ;连续保存3个1字节数据 DATA2: DB 07H MY_STR: DB 'A','B','C',0 ;定义ASCII字符串,末尾0作为字符串结束标记 WORD_BUF: DW 0x1234,0x5678 ;DW,每一项占用2字节内存

⚠️注意:不要使用STR:作为标号,STR是 ARM 存储指令,属于保留关键字。

6. DCD / DCDU 32 位字分配伪指令(ARM 汇编)

格式

标号 DCD / DCDU 表达式列表
  • DCD:分配连续 32 位(4 字节)内存单元,严格 4 字节字对齐。
  • DCDU:分配 32 位内存单元,不强制字对齐。

表达式既可以写数字,也可以写标号,用来保存标号对应的内存地址,中断向量表大量使用该伪指令。

DATA_TEST: DCD 4,5,6 ;分配3个4字节空间,分别存入4、5、6 ;向量表 VECTOR_TABLE: DCD 0x20000000 DCD Reset_Handler ;存储标号Reset_Handler的内存地址 UNALIGN_DATA: DCDU 0x1111,0x2222

7. SPACE 内存空间分配伪指令

格式

标号 SPACE 字节数

简写符号%等价于 SPACE(单位:字节)

功能:划出一块连续内存区域,分配的内存全部初始化为 0;多用于缓冲区、栈空间。

DATA_SPACE: SPACE 1000 ;分配1000字节内存,全部清零 STACK_BUF: SPACE 256 ;分配256字节栈内存 BUF2: % 64 ;简写写法,分配64字节并清零

8. PRESERVE8 堆栈 8 字节对齐伪指令(ARM 汇编)

格式

PRESERVE8 {FALSE}

功能:通知链接器当前文件堆栈是否保持 8 字节对齐。

汇编语言和 C 语言互相调用时,必须开启该伪指令;如果不满足 8 字节对齐,程序运行会发生异常崩溃。

PRESERVE8 ;开启堆栈8字节对齐,C与汇编混编必备 ;PRESERVE8 {FALSE} ;关闭堆栈8字节对齐

9. EXPORT、EXTRN、IMPORT 多文件模块伪指令

应用场景

实际项目代码量很大,不会把全部代码写在一个汇编文件里。 举例:

  • 文件A.s:写了一个子程序_STARTUP
  • 文件B.s:需要调用A.s里面已经写好的_STARTUP子程序

两个.s文件是独立的,单独汇编的时候,互相看不到对方内部定义的标号。 需要依靠EXPORT、EXTRN/IMPORT,打通多个汇编文件之间的符号访问。

EXPORT:将本文件的标号对外公开

在 A.s 中,使用 EXPORT 把内部标号公开,其他汇编文件才可以访问调用该标号;如果不写 EXPORT,标号只在当前文件内部有效,外部不可见。

文件:A.s

;A.s完整内容 AREA CODE,CODE,READONLY EXPORT _STARTUP ;对外公开标号_STARTUP,允许别的文件访问 _STARTUP: ;A.s内部自定义的子程序入口标号 MOV R0,#0 BX LR ;子程序执行完毕,返回调用处

EXTRN:声明标号来自外部其他文件

B.s 想要调用 A.s 的_STARTUP,但是 B.s 没有定义_STARTUP。

汇编编译 B.s 时,汇编器会报 “找不到符号” 错误。

使用EXTRN告诉汇编器:这个标号不是本文件定义的,定义在别的文件,等链接阶段再去找真实地址。

文件:B.s

;B.s完整内容 AREA CODE,CODE,READONLY EXTRN _STARTUP:CODE ;声明:_STARTUP是外部的代码标号,不在本文件定义 ENTRY START: BL _STARTUP ;BL指令:调用子程序,调用A.s中的_STARTUP MOV R1,#2 END

完整工作步骤

  1. A.s:编写子程序_STARTUP:,使用EXPORT _STARTUP对外公开符号。
  2. B.s:使用EXTRN _STARTUP:CODE声明该标号属于外部。
  3. 汇编器分别编译 A.s、B.s,生成A.o、B.o两个目标文件。
  4. 链接器把 A.o 与 B.o 合并。链接器发现 B 要调用_STARTUP,就到 A.o 里面找到_STARTUP真实内存地址,填入 B 的机器码中。

IMPORT 外部符号导入(ARM 常用)

IMPORT功能和 EXTRN 接近,ARM 汇编更习惯使用 IMPORT。 语法:IMPORT 标号 {[WEAK]}

  • [WEAK]弱符号:就算整个工程找不到这个标号的定义,链接器也不会报错。
AREA INIT,CODE,READONLY IMPORT Main ;Main函数写在C语言文件,汇编中声明这是外部标号 ENTRY START: B Main ;跳转到C语言的Main函数 IMPORT Err_Handler [WEAK] B Err_Handler

10. CODE16 / CODE32 指令集声明伪指令

格式

CODE16 CODE32
  • CODE32:告诉汇编器,后续代码编译为 32 位 ARM 指令。
  • CODE16:告诉汇编器,后续代码编译为 16 位 Thumb 指令。

⚠️重要提醒:该伪指令仅仅控制汇编器如何编译源代码,不能改变 CPU 硬件运行状态;真正切换 ARM/Thumb 处理器模式,需要使用BX指令。

AREA MIX_CODE,CODE,READONLY CODE32 ;后续编译32位ARM指令 ARM_FUNC: MOV R0,#1 CODE16 ;后续编译16位Thumb指令 THUMB_FUNC: MOVS R1,#2

11. PROC / ENDP 过程(子程序)伪指令

格式

子程序名 PROC 指令 RET ENDP

功能:用来定义汇编子程序;PROC标记子程序开始,ENDP标记子程序结束,二者必须成对出现;使用BL指令调用子程序。

ADD_SUB PROC ;子程序开始,子程序名字ADD_SUB ADD R0,R0,R1 RET ;RET:子程序返回 ENDP ;子程序结束 BL ADD_SUB ;调用上面定义好的子程序

12. END 源程序结束伪指令

格式

END

功能:标记当前这一个汇编源文件编译到此结束。

注意:一个.s源文件,只能写一条 END,写在文件的末尾;END 之后书写的全部代码,汇编器直接忽略,不会参与编译。

AREA TEST,CODE,READONLY ENTRY START: MOV R0,#1 END ;本汇编源文件到此结束

综合完整示例(ARM 简易启动框架)

PRESERVE8 AREA DEMO_CODE,CODE,READONLY EXPORT Reset_Handler IMPORT Main ENTRY Reset_Handler PROC LDR SP,=0x20001000 ;设置栈指针 B Main ;跳转到C语言main函数 ENDP AREA DEMO_DATA,DATA,READWRITE BUFF: SPACE 64 ;分配64字节清零缓冲区 CONST_BYTES: DB 0x01,0x02,0x03 END

附录:标号使用小结

✅合法标号示例:START:、MY_STR:、DATA_BUF:

❌禁止作为标号:MOV:、LDR:、STR:(CPU 指令,属于保留关键字)

标号可以单独占一行,但是冒号不要省略冒号:

START: MOV R0,#1

补充区分:

  • 51 单片机汇编没有LDR、STR指令,所以STR:作为标号是合法;
  • ARM32 汇编中 LDR、STR 是硬件指令,严禁用作标号,两套汇编规则不要混淆。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 21:14:28

Python数据统计实战指南:从数据清洗到推断统计全流程解析

我接触Python数据统计也有六七年了,从最早用Excel透视表做报表,到后来被几百万行数据逼着转投Python阵营,再到现在把统计分析和业务决策绑在一起做数据驱动。这一路下来最大的感触是:很多人其实不是不会用Python,而是不…

作者头像 李华
网站建设 2026/10/15 21:12:03

C++几何建模实战:从Point类到矩形构造的类设计指南

1. 从坐标点到矩形:一个看似简单的类设计任务刚入行那会儿,如果有人让我写一个"点构线、线构矩形"的程序,我大概率会直接甩出三个类,每个类里塞几个成员变量,再补上构造函数和打印函数,编译通过就…

作者头像 李华
网站建设 2026/10/15 21:09:54

光学仿真软件选型指南:面板与激光雷达场景差异

很多刚入行的朋友问过我同一个问题:做光学仿真,到底该选哪款软件?我通常会回一句——你先告诉我,你是在做显示面板,还是在做激光雷达。这两个领域都叫"光学仿真",但底层逻辑、参考坐标系、评价指…

作者头像 李华
网站建设 2026/10/15 21:09:33

MySQL索引与性能优化基础:从B+树原理到EXPLAIN实战

MySQL 基础教程 - 第八章:索引与性能优化基础做了这么多年 MySQL 相关的开发和调优,我越来越觉得索引这东西,知道怎么建和真正理解为什么这么建,完全是两码事。很多初学者对索引的印象就停留在“查询慢了加个索引就好”&#xff0…

作者头像 李华
网站建设 2026/10/15 21:09:24

C#实现三菱PLC串口通信:MC协议3E帧解析与读写实战

简介:本资源是一套基于C#实现串口与三菱PLC通信的完整工程实践方案,面向工业自动化领域的初/中级开发者、自控工程师及高校机电类专业学生,解决PLC底层数据交互中单点/批量布尔量、Word/Dword数值读写、心跳监测与多线程稳定通信等核心问题。…

作者头像 李华
网站建设 2026/10/15 21:09:20

PointTrack:用5个几何点重构多目标跟踪与分割

1. MOTS不是“多目标跟踪分割”的简单拼接,而是用点来重构整个视觉理解范式你可能已经见过不少Multi-Object Tracking and Segmentation(MOTS)的论文标题,也大概知道它是在视频里一边框出多个运动物体、一边把它们像素级抠出来的任…

作者头像 李华