常用 ARM 指令集及汇编
2003 年 12 月 1 日常用 ARM 指令集及 汇 编 Ver,1.0.12
前言
ARM(Advanced RISC Machines)是微处理器行业的一家知名企业,该企业设计了大量高性能、廉价、耗能低的 RISC处理器、相关技术及软件。技术具有性能高、成本低和能耗省的特点,适用于多种领域,比如嵌入控制、消费/教育类多媒体、DSP 和移动式应用等。
ARM将其技术授权给世界上许多著名的半导体,软件和 OEM厂商,每个厂商得到的都是独一无二的 ARM相关技术及服务,利用这种合作关系,ARM很快成为许多全球性 RISC
标准的缔造者。
目前,ARM内核的微处理器正在我国迅速普及和发展,许多朋友已经开始着手学习、
研究和利用这类芯片进行商品化设计,为了帮助广大朋友更快的学习和使用这种先进的技术,广州周立功单片机发展有限公司( http://www.zlgmcu.com)曾面向大众推出了一款 EasyARM试验板,本文的大部分内容来自此款试验板的配套教材- -《A RM微控制器基础》,并且得到周立功正式授权。 本文主要是针对ARM7TDMI(-S)内核,经本人重新排版,
制作成PDF格式,便于大家查阅和使用。
本文仅仅用于大家的学习和研究使用,由于本文的原因造成元器件的损坏,设计方案的缺陷与失败等一切损失,概不负责。
感谢周立功老师为我们提供了丰富 的资源并亲自审阅了本文,感谢 单片机学习网
(http://www.mcustudy.com)为我们提供了交流和学习的空间,感谢我的女友对我这项工作的支持,她自己放弃了大量的业余时间帮我录入和排版。
由于时间仓促,本文难免会存在不当之处,欢迎大家来信( email:mcu8031@163.com)
或在网上(QQ:57523799)批评指正和交流,以便在今后的版本加以更正,也希望大家能把自己在工作中的心得体会和经验拿出来,和众多的同行及爱好者交流,共同提高,一起进步。
宛城布衣
2003年 12月 1日星期一
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 i 页常用 ARM 指令集及 汇 编 Ver,1.0.12
目录
前言,...............................................................................................................................................................i
目录,...............................................................................................................................................................I
ARM7TDMI(-S)指令集及 汇编,...................................................................................................................1
ARM 处理器 寻址方式,.........................................................................................................................2
寄存器寻址,...................................................................................................................................2
立即寻址,.......................................................................................................................................2
寄存器偏移寻址,...........................................................................................................................2
寄存器间接寻址,...........................................................................................................................3
基址寻址,.......................................................................................................................................3
多寄存器寻址,...............................................................................................................................4
堆栈寻址,.......................................................................................................................................4
块拷贝寻址,...................................................................................................................................5
相对寻址,.......................................................................................................................................5
指令集介绍,...........................................................................................................................................7
ARM 指令集,.................................................................................................................................7
指令格式,...............................................................................................................................7
第 2 个操作 数,...............................................................................................................7
# immed_8r,..........................................................................................................7
Rm..........................................................................................................................8
Rm,shift..................................................................................................................8
条件码,...........................................................................................................................9
ARM 存储器 访问指令,......................................................................................................,11
  LDR 和 STR,......................................................................................................,11
  LDM 和 STM.......................................................................................................14
  SWP,....................................................................................................................17
ARM 数据处 理指令,...........................................................................................................19
数据传送指令,.............................................................................................................20
  MOV,...........................................................................................................20
  MVN,...........................................................................................................20
算术逻辑运算指令,.....................................................................................................20
  ADD,............................................................................................................20
  SUB..............................................................................................................21
  RSB,.............................................................................................................21
  ADC,............................................................................................................21
  SBC,.............................................................................................................21
  RSC,.............................................................................................................22
  AND,............................................................................................................22
  ORR..............................................................................................................22
  EOR..............................................................................................................22
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
  BIC,..............................................................................................................23
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 I 页常用 ARM 指令集及 汇 编 Ver,1.0.12
比较指令,.....................................................................................................................23
  CMP,............................................................................................................23
  CMN.............................................................................................................23
  TST...............................................................................................................24
  TEQ..............................................................................................................24
乘法指令,.....................................................................................................................25
  MUL.............................................................................................................25
  MLA.............................................................................................................25
  UMULL........................................................................................................25
  UMLAL........................................................................................................26
  SMULL,.......................................................................................................26
  SMLAL,.......................................................................................................26
ARM 跳转指 令,...................................................................................................................27
  B...........................................................................................................................27
  BL.........................................................................................................................27
  BX,.......................................................................................................................27
ARM 协处理 器指令,...........................................................................................................28
  CDP......................................................................................................................28
  LDC......................................................................................................................29
  STC,.....................................................................................................................29
  MCR.....................................................................................................................30
  MRC.....................................................................................................................30
ARM 杂项指 令,...................................................................................................................31
  SWI,.....................................................................................................................31
  MRS,....................................................................................................................32
  MSR,....................................................................................................................33
ARM 伪指令,.......................................................................................................................34
  ADR,....................................................................................................................35
  ADRL...................................................................................................................35
  LDR......................................................................................................................36
  NOP......................................................................................................................37
Thumb 指令集,............................................................................................................................39
Thumb 指令集与 ARM 指 令集的区别,.............................................................................39
Thumb 存储器访问指令,....................................................................................................40
  LDR 和 STR,.......................................................................................................41
  PUSH 和 POP,.....................................................................................................43
  LDMIA 和 STMIA,.............................................................................................43
Thumb 数据处理指令,........................................................................................................45
数据传送指令,.............................................................................................................46
  MOV,...........................................................................................................46
  MVN,...........................................................................................................46
  NEG..............................................................................................................47
算术逻辑运算指令,.....................................................................................................47
  ADD,............................................................................................................47
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 II 页常用 ARM 指令集及 汇 编 Ver,1.0.12
  SUB..............................................................................................................48
  ADC,............................................................................................................49
  SBC,.............................................................................................................49
  MUL.............................................................................................................50
  AND,............................................................................................................50
  ORR..............................................................................................................50
  EOR..............................................................................................................51
  BIC,..............................................................................................................51
  ASR..............................................................................................................51
  LSL...............................................................................................................52
  LSR,.............................................................................................................52
  ROR..............................................................................................................53
比较指令,.....................................................................................................................53
  CMP,............................................................................................................53
  CMN.............................................................................................................54
  TST...............................................................................................................54
Thumb 跳转指令,........................................................................................................55
  B,..................................................................................................................55
  BL.................................................................................................................55
  BX,...............................................................................................................55
Thumb 杂项指令,........................................................................................................56
  SWI,.............................................................................................................56
Thumb 伪指令,............................................................................................................57
  ADR,............................................................................................................57
  LDR..............................................................................................................57
  NOP..............................................................................................................58
伪指令,.................................................................................................................................................59
符号定义伪指令,.........................................................................................................................59
  GBLA,GBLL,GBLS,.............................................................................................59
  LCLA,LCLL,LCLS................................................................................................60
  SETA,SETL,SETS,................................................................................................61
  RLIST...........................................................................................................................61
  CN,...............................................................................................................................62
  CP.................................................................................................................................62
  DN,SN.......................................................................................................................62
  FN.................................................................................................................................63
数据定义伪指令,.........................................................................................................................63
  LTORG.........................................................................................................................64
  MAP.............................................................................................................................64
  FIELD,.........................................................................................................................65
  SPACE..........................................................................................................................66
  DCB,............................................................................................................................66
  DCD 和 DCDU............................................................................................................67
  DCDO,.........................................................................................................................67
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 III 页常用 ARM 指令集及 汇 编 Ver,1.0.12
  DCFD 和 DCFDU........................................................................................................68
  DCFS 和 DCFSU.........................................................................................................68
  DCI...............................................................................................................................69
  DCQ 和 DCQU............................................................................................................69
  DCW 和 DCWU,.........................................................................................................70
报告伪指令,.................................................................................................................................70
  ASSERT,......................................................................................................................70
  INFO,...........................................................................................................................71
  OPT,.............................................................................................................................71
  TTL 和 SUBT,.............................................................................................................72
汇编控制伪指令,.........................................................................................................................73
  IF,ELSE 和 ENDIF...................................................................................................73
  MACRO 和 MEND,....................................................................................................74
  WHIL 和 WEND,........................................................................................................75
杂项伪指令,.................................................................................................................................76
  ALIGN,........................................................................................................................77
  AREA...........................................................................................................................78
  CODE16 和 CODE32,.................................................................................................79
  END,............................................................................................................................80
  ENTRY.........................................................................................................................80
  EQU,............................................................................................................................81
  EXPORT 和 GLOBAL,...............................................................................................81
  IMPORT 和 EXTERN,................................................................................................82
  GET 和 INCLUDE,.....................................................................................................83
  INCBIN........................................................................................................................83
  KEEP............................................................................................................................83
  NOFP,..........................................................................................................................84
  REQUIRE,...................................................................................................................84
  PEQUIRE8 和 PRESERVE8,......................................................................................84
  RN,...............................................................................................................................84
  ROUT...........................................................................................................................85
ARM 伪指令,...............................................................................................................................86
  ADR,............................................................................................................................86
  ADRL...........................................................................................................................86
  LDR..............................................................................................................................86
  NOP..............................................................................................................................86
  LDFD,..........................................................................................................................86
  LDFS............................................................................................................................87
Thumb 伪指令,............................................................................................................................87
  ADR,............................................................................................................................87
  LDR..............................................................................................................................87
  NOP..............................................................................................................................88
ARM 汇编程 序设计,...........................................................................................................................88
文件格式,.....................................................................................................................................88
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 IV 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM 汇编的 一些规范,...............................................................................................................88
汇编语句格式,.....................................................................................................................88
标号,.....................................................................................................................................89
  基于 PC 的标号,..................................................................................................89
  基于寄存器的标号,.............................................................................................90
  绝对地址,.............................................................................................................90
局部标号,.............................................................................................................................90
符号,.....................................................................................................................................91
常量,.....................................................................................................................................91
  数字常数,.............................................................................................................91
  字符常量,.............................................................................................................92
  布尔常量,.............................................................................................................92
段定义,.................................................................................................................................92
宏定义及其作用,.................................................................................................................93
子程序的调用,.............................................................................................................................94
数据比较跳转,.............................................................................................................................95
循环,.............................................................................................................................................95
数据块复制,.................................................................................................................................95
栈操作,.........................................................................................................................................96
特殊寄存器定义及应用,.............................................................................................................96
散转功能,.....................................................................................................................................97
查表操作,.....................................................................................................................................97
长跳转,.........................................................................................................................................97
对信号量的支持,.........................................................................................................................98
伪指令使用,.................................................................................................................................98
一个完整的例子,.........................................................................................................................98
外围部件控制,.............................................................................................................................99
三级流水线介绍,.........................................................................................................................99
C 与汇编混 合编程,...........................................................................................................................100
内嵌汇编,...................................................................................................................................100
内嵌汇编的指令用法,.......................................................................................................103
内嵌汇编器与 armasm 汇 编器的差异,............................................................................104
内嵌汇编注意事项,...........................................................................................................104
访问全局变量,...........................................................................................................................106
C 与汇编相 互调用,...................................................................................................................107
寄存器的使用规则,...........................................................................................................108
堆栈使用规则,...................................................................................................................108
参数传递规则,...................................................................................................................109
C 程序调用 汇编程序,......................................................................................................,110
汇编程序调用 C 程序,.....................................................................................................,111
ARM 指令集 列表,............................................................................................................................,113
ARM 存储器 访问指令表列表,................................................................................................,113
ARM 数据处 理指令列表,........................................................................................................,114
ARM 乘法指 令列表,................................................................................................................,115
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 V 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM 跳转指 令列表,................................................................................................................,116
ARM 协处理 器指令列表,........................................................................................................,117
ARM 杂项指 令列表,................................................................................................................,118
ARM 伪指令 列表,....................................................................................................................,119
Thumb 指令集列表,..........................................................................................................................120
Thumb 存储器访问指令列表,..................................................................................................120
Thumb 数据处理指令列表,......................................................................................................121
Thumb 跳转指令及软中断指令列表,......................................................................................122
Thumb 伪指令列表,..................................................................................................................123
汇编预定义变量及伪指令,...............................................................................................................124
预定义的寄存器和协处理器名,...............................................................................................124
通用寄存器,.......................................................................................................................124
程序状态寄存器,...............................................................................................................124
浮点数寄存器,...................................................................................................................124
协处理器及协处理器寄存器,...........................................................................................125
内置变量列表,...........................................................................................................................125
伪指令列表,...............................................................................................................................126
指令条件码列表,.......................................................................................................................128
CPSR 和 SPSR 分配图,............................................................................................................................129
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 VI 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM7TDMI(-S)指令集及汇编
ARM处理器是基于精简指令集计算机 (RISC) 原理设计的,指令集和相关译码机制较为简单,ARM7TDMI(-S)具有 32位 ARM指令集和 16位 Thumb指令集,ARM指令集效率高,但是代码密度低,而 Thumb指令集具有更好的代码密度,却仍然保持 ARM的大多数性能上的优势,它是 ARM指令集的子集。 所有 ARM指令都是可以有条件执行的,而 Thumb
指令仅有一条指令具备条件执行功能。 ARM程序和 Thumb程序可相互调用,相互之间的状态切换开销几乎为零。
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 1 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM处理器寻址方式
寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式,ARM
处理器有 9种基本寻址方式。
寄存器寻址
操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值操作。
寄存器寻址指令举例如下,
MOV R1,R2 ;R2 -> R1
SUB R0,R1,R2 ;R1 - R2 -> R0
立即寻址
立即寻址指令中的操作码字段后面的地址码部分就是操作数本身,也就是说,数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数(立即数) 。
立即寻址指令举例如下,
SUBS R0,R0,#1 ;R0 – 1 -> R0
MOV R0,#0xff00 ;0xff00 -> R0
立即数要以“#”为前缀,表示 16进制数值时以“0x”表示。
寄存器偏移寻址
寄存器偏移寻址是 ARM指令集特有的寻址方式,当第 2操作数是寄存器偏移方式时,
第 2个寄存器操作数在与第 1个操作数结合之前,选择进行移位操作。
寄存器偏移寻址方式指令举例如下,
MOV R0,R2,LSL #3 ;R2的值左移 3位,结果放入 R0,即 R0 = R2 * 8
ANDS R1,R1,R2,LSL R3 ;R2的值左移 R3位,然后和 R1相与操作,结果放入 R1
可采用的移位操作如下,
LSL:逻辑左移(Logical Shift Left),寄存器中字的低端空出的位补 0
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 2 页常用 ARM 指令集及 汇 编 Ver,1.0.12
LSR:逻辑右移(Logical Shift Right),寄存器中字的高端空出的位补 0
ASR,算 术 右 移 ( Arithmetic Shift Right),移位过程中保持符号位不变,即如果源操作数为正数,则字的高端空出的位补 0,否则补 1
ROR:循环右移(Rotate Right),由字的低端移出的位填入字的高端空出的位
RRX:带扩展的循环右移(Rotate Right eXtended by 1place),操作数右移一位,
高端空出的位用原 C标志值填充。
各移位操作如下图所示。
0 LSL 移位操作
0 LSR 移位操作
ASR 移位操作
ROR 移位操 作
C RRX 移位操 作
寄存器间接寻址
寄存器间接寻址指令中的地址码给出的是一个通用寄存器编号,所需要的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针。
寄存器间接寻址指令举例如下,
LDR R1,[R2] ;将 R2中的数值作为地址,取出此地址中的数据保存在 R1中
SWP R1,R1,[R2];将如中的数值作为地址,取出此地址中的数值与 R1中的值交换
基址寻址
基址寻址是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 3 页常用 ARM 指令集及 汇 编 Ver,1.0.12
址,基址寻址用于访问基址附近的存储单元,常用于查表,数组操作,功能部件寄存器访问等。
基址寻址指令举例如下,
LDR R2,[R3,#0x0F] ;将 R3 中 的 数值加 0x0F作为地址,取出此地址的数值保存在 R2 中
STR R1,[R0,#-2] ;将 R0 中的数 值减 2 作 为 地址,把 R1中的内容保存到此地址位置
多寄存器寻址
多寄存器寻址就是一次可以传送几个寄存器值,允许一条指令传送 16个寄存器的任何子集或所有寄存器。
多寄存器寻址指令举例如下,
LDMIA R1!,{R2-R7,R12} ;将 R1单元中的数据读出到 R2-R7,R12,R1 自动加 1
STMIA R0!,{R3-R6,R10} ;将 R3-R6,R10 中 的 数据保存到 R0 指向的地址,R0 自 动 加 1
使用多寄存器寻址指令时,寄存器子集的顺序时由小到大的顺序排列,连续的寄存器可用“-”连接,否则,用“,”分隔书写。
堆栈寻址
堆栈是特定顺序进行存取的存储区,操作顺序分为“后进先出”和“先进后出”,
堆栈寻址时隐含的,它使用一个专门的寄存器 (堆栈指针) 指向一块存储区域 (堆栈),
指针所指向的存储单元就是堆栈的栈顶。存储器堆栈可分为两种,
向上生长,向高地址方向生长,称为递增堆栈
向下生长,向低地址方向生长,称为递减堆栈
堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈; 堆栈指针指向下一个要放入的空位置,称为空堆栈。 这样就有 4中类型的堆栈表示递增和递减的满堆栈和空堆栈的各种组合。
满递增,堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数据项的最高地址。指令如 LDMFA,STMFA 等。
空递增,堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空位置。指令如 LDMEA,STMEA 等。
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 4 页常用 ARM 指令集及 汇 编 Ver,1.0.12
满递减,堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址。指令如 LDMFD,STMFD 等。
空递减,堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置。指令如 LDMED,STMED 等。
堆栈寻址指令举例如下,
STMFD SP!,{R1-R7,LR} ; 将 R1~R7,LR 入栈。满递减堆栈。
LDMFD SP!,{R1-R7,LR} ;数据出栈,放入 R1~R7,LR 寄存器。满递减堆栈。
块拷贝寻址
多寄存器传送指令用于一块数据从存储器的某一位置拷贝到另一位置。
块拷贝寻址指令举例如下,
STMIA R0!,{R1-R7} ;将 R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之后增加,增长方向为向上增长。
STMIB R0!,{R1-R7} ;将 R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之前增加,增长方向为向上增长。
STMDA R0!,{R1-R7} ;将 R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之后增加,增长方向为向下增长。
STMDB R0!,{R1-R7} ;将 R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之前增加,增长方向为向下增长。
相对寻址
相对寻址是基址寻址的一种变通,由程序计数器 PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。
相对寻址指令举例如下,
BL ROUTE1 ;调用到 ROUTE1子程序
BEQ LOOP ;条件跳转到 LOOP标号处

LOOP MOV R2,#2
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 5 页常用 ARM 指令集及 汇 编 Ver,1.0.12

ROUTE1

IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 6 页常用 ARM 指令集及 汇 编 Ver,1.0.12
指令集介绍
ARM 指令集
指令格式
基本格式
<opcode>{<cond>}{S} <Rd>,<Rn>{,<opcode2>}
其中,<>内的项是必须的,{}内的项是可选的,如<opcode>是指令助记符,是必须的,而{<cond>}为指令执行条件,是可选的,如果不写则使用默认条件 AL(无条件执行)。
opcode 指令助记符,如 LDR,STR 等
cond 执行条件,如 EQ,NE 等
S 是否影响 CPSR寄存器的值,书写时影响 CPSR,否则不影响
Rd 目标寄存器
Rn 第一个操作数的寄存器
operand2 第二个操作数
指令格式举例如下,
LDR R0,[R1] ;读取 R1地址上的存储器单元内容,执行条件 AL
BEQ DATAEVEN ;跳转指令,执行条件 EQ,即相等跳转到 DATAEVEN
ADDS R1,R1,#1 ;加法指令,R1+1=R1 影响 CPSR寄存器,带有 S
SUBNES R1,R1,#0xD;条件执行减法运算(NE),R1-0xD=>R1,影响 CPSR寄存器,带有 S
第 2 个操作数
在 ARM指令中,灵活的使用第 2个操作数能提高代码效率,第 2个操作数的形式如下,
#immed_8r
常数表达式,该常数必须对应 8位位图,即常数是由一个 8位的常数循环移位偶数
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 7 页常用 ARM 指令集及 汇 编 Ver,1.0.12
位得到。
合法常量,
0x3FC、0、0xF0000000、200,0xF0000001
非法常量,
0x1FE、511、0xFFFF、0x1010、0xF0000010
常数表达式应用举例如下,
MOV R0,#1 ;R0=1
AND R1,R2,#0x0F ;R2与 0x0F,结果保存在 R1
LDR R0,[R1],#-4 ;读取 R1地址上的存储器单元内容,且 R1=R1-4
Rm
寄存器方式,在寄存器方式下操作数即为寄存器的数值。
寄存器方式应用举例,
SUB R1,R1,R2 ;R1-R2=>R1
MOV PC,R0 ;PC=R0,程序跳转到指定地址
LDR R0,[R1],-R2 ; 读取 R1地址上的存储器单元内容并存入 R0,且 R1=R1-R2
Rm,shift
寄存器移位方式。将寄存器的移位结果作为操作数,但 RM值保存不变,移位方法如下,
ASR #n 算术右移 n位(1≤n≤32)
LSL #n 逻辑左移 n位(1≤n≤31)
LSR #n 逻辑左移 n位(1≤n≤32)
ROR #n 循环右移 n位(1≤n≤31)
RRX 带扩展的循环右移 1位
type Rs 其中,type 为 ASR,LSL,和 ROR中的一种;Rs 偏移量寄存器,低 8
位有效,若其值大于或等于 32,则第 2个操作数的结果为 0(ASR,ROR
例外) 。
寄存器偏移方式应用举例,
ADD R1,R1,R1,LSL #3 ;R1=R1*9
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 8 页常用 ARM 指令集及 汇 编 Ver,1.0.12
SUB R1,R1,R2,LSR#2 ;R1=R1-R2*4
R15为处理器的程序计数器 PC,一般不要对其进行操作,而且有些指令是不允许使用 R15,如 UMULL指令。
条件码
使用指令条件码,可实现高效的逻辑操作,提高代码效率。
条件码表
条件码助记符 标志 含义
EQ Z=1 相等
NE Z=0 不相等
CS/HS C=1 无符号数大于或等于
CC/LO C=0 无符号数小于
MI N=1 负数
PL N=0 正数或零
VS V=1 溢出
VC V=0 没有溢出
HI C=1,Z=0 无符号数大于
LS C=0,Z=1 无符号数小于或等于
GE N=V 带符号数大于或等于
LT N!=V 带符号数小于
GT Z=0,N=V 带符号数大于
LE Z=1,N!=V 带符号数小于或等于
AL 任何 无条件执行(指令默认条件)
对于 Thumb 指令集,只有 B 指令具有条件码执行功能,此指令条件码同表 2.1,但如果为无条件执行时,条件码助记符“AL”不能在指令中书写。
条件码应用举例如下,
比较两个值大小,并进行相应加 1处理,C 代码为
if(a>b)a++;
else b++;
对应的 ARM指令如下。其 R0为 a,R1 为 b。
CMP R0,R1 ;R0 与 R1比较
ADDHI R0,R0,#1 ;若 R0>R1,则 R0=R0+1
ADDLS R1,R1,#1 ;若 R0<=R1,则 R1=R1+1
若两个条件均成立,则将这两个数值相加,C 代码为
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 9 页常用 ARM 指令集及 汇 编 Ver,1.0.12
If((a!=10)&&(b!=20)) a=a+b;
对应的 ARM指令如下.其中 R0为 a,R1为 b,
CMP R0,#10 ;比较 R0是否为 10
CMPNE R1,#20 ;若 R0不为 10,则比较 R1是否 20
ADDNE R0,R0,R1 ;若 R0不为 10且 R1不 为 20,指令执行,R0=R0+R1
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 10 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM存储器访问指令
ARM 处理是加载/存储体系结构的典型的 RISC 处理器,对存储器的访问只能使用加载和存储指令实现。 ARM的加载/存储指令是可以实现字,半字、,无符/有符字节操作;
批量加载/存储指令可实现一条指令加载/存储多个寄存器的内容,大大提高效率;SWP
指令是一条寄存器和存储器内容交换的指令,可用于信号量操作等。ARM 处理器是冯.
诺依曼存储结构,程序空间,RAM空间及 IO映射空间统一编址,除对对 RAM操作以外,
对外围 IO、程序数据的访问均要通过加载/存储指令进行。
ARM存储访问指令表
助记符 说明 操作 条件码 位置
LDR Rd,addressing 加载字数据 Rd←[addressing],addressing 索引 LDR{cond}
LDRB Rd,addressing 加载无符字节数据 Rd←[addressing],addressing 索引 LDR{cond}B
LDRT Rd,addressing 以用户模式加载字数据 Rd←[addressing],addressing 索引 LDR{cond}T
LDRBT Rd,addressing 以用户模式加载无符号字数据 Rd←[addressing],addressing 索引 LDR{cond}BT
LDRH Rd,addressing 加载无符半字数据 Rd←[addressing],addressing 索引 LDR{cond}H
LDRSB Rd,addressing 加载有符字节数据 Rd←[addressing],addressing 索引 LDR{cond}SB
LDRSH Rd,addressing 加载有符半字数据 Rd←[addressing],addressing 索引 LDR{cond}SH
STR Rd,addressing 存储字数据 [addressing]←Rd,addressing 索引 STR{cond}
STRB Rd,addressing 存储字节数据 [addressing]←Rd,addressing 索引 STR{cond}B
STRT Rd,addressing 以用户模式存储字数据 [addressing]←Rd,addressing 索引 STR{cond}T
SRTBT Rd,addressing 以用户模式存储字节数据 [addressing]←Rd,addressing 索引 STR{cond}BT
STRH Rd,addressing 存储半字数据 [addressing]←Rd,addressing 索引 STR{cond}H
LDM{mode} Rn{!},reglist 批量(寄存器)加载 reglist←[Rn…],Rn 回存等 LDM{cond}{more}
STM{mode} Rn{!},rtglist 批量(寄存器)存储 [Rn…]← reglist,Rn 回存等 STM{cond}{more}
SWP Rd,Rm,Rn 寄存器和存储器字数据交换 Rd←[Rd],[Rn]←[Rm](Rn≠Rd 或 Rm) SWP{cond}
SWPB Rd,Rm,Rn 寄存器和存储器字节数据交换 Rd←[Rd],[Rn]←[Rm](Rn≠Rd 或 Rm) SWP{cond}B
? LDR 和 STR
加载/存储字和无符号字节指令.使用单一数据传送指令(STR 和 LDR)来装载和存储单一字节或字的数据从/到内存.LDR 指令用于从内存中读取数据放入寄存器中;STR 指令用于将寄存器中的数据保存到内存.指令格式如下,
LDR{cond}{T} Rd,<地址> ;加载指定地址上的数据(字),放入 Rd 中
STR{cond}{T} Rd,<地址> ;存储 数据(字)到 指定地址的存储单元,要 存储的数据在 Rd 中
LDR{cond}B{T} Rd,<地址> ;加载 字节数据,放 入 Rd 中,即 Rd 最低字节有 效,高 24 位 清零
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 11 页常用 ARM 指令集及 汇 编 Ver,1.0.12
STR{cond}B{T} Rd,<地址> ;存储字节数据,要存储的数据在 Rd,最低字节有效
其中,T 为可选后缀,若指令有 T,那么即使处理器是在特权模式下,存储系统也将访问看成是处理器是在用户模式下.T 在用户模式下无效,不能与前索引偏移一起使用 T,
LDR/STR 指令寻址是非常灵活的,由两部分组成,一部分为一个基址寄存器,可以为任一个通用寄存器,另一部分为一个地址偏移量.地址偏移量有以下 3种格式,
(1) 立即数,立即数可以是一个无符号数值,这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值.指令举例如下,
LDR R1,[R0,#0x12] ;将 R0+0x12地址处的数据读出,保存到 R1中(R0 的值不变)
LDR R1,[R0,#-0x12];将 R0-0x12地址处的数据读出,保存到 R1中(R0 的值不变)
LDR R1,[R0] ;将 R0地址处的数据读出,保存到 R1中(零偏移)
(2)寄 存 器,寄存器中的数值可以加到基址寄存 器,也可以从基址寄存器中减去这个数值.指令举例值.指令举例如下,
LDR R1,[R0,R2] ;将 R0+R2地址的数据计读出,保存到 R1中(R0 的值不变)
LDR R1,[R0,-R2] ;将 R0-R2地址处的数据计读出,保存到 R1中(R0 的值不变)
(3)寄存器及移位常数,寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值.指令举例如下,
LDR R1,[R0,R2,LSL #2] ;将 R0+R2*4 地址处的 数据读出,保存到 R1 中 ( R0,R2 的值 不变)
LDR R1,[R0,-R2,LSL #2];将 R0-R2*4地址处的 数据计读出,保存到 R1中 (R0,R2的值不 变 )
从寻址方式的地址计算方法分,加载/存储指令有以下 4种形式,
(1)零偏移,Rn 的值作为传送数据的地址,即地址偏移量为 0.指令举例如下,
LDR Rd,[Rn]
(2)前索引偏移,在数据传送之前,将偏移量加到 Rn中,其结果作为传送数据的存储地址.若使用后缀“!,,则结果写回到 Rn中,且 Rn值不允许为 R15.指令举例如下,
LDR Rd,[Rn,#0x04]!
LDR Rd,[Rn,#-0x04]
(3)程序相对偏移,程序相对偏移是索引形式的另一个版本.汇编器由 PC 寄存器计算偏移量,并将 PC寄存器作为 Rn生成前索引指令.不能使用后缀“!,.指令举例如下,
LDR Rd,label ;label为程序标号,label 必须是在当前指令的±4KB 范围内
(4) 后索引偏移.Rn 的值用做传送数据的存储地址.在数据传送后,将偏移量与 Rn
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 12 页常用 ARM 指令集及 汇 编 Ver,1.0.12
相加,结果写回到 Rn中.Rn 不允许是 R15.指令举例如下,
LDR Rd,[Rn],#0x04
地址对准--大多数情况下,必须保证用于 32位传送的地址是 32位对准的,
加载/存储字和无符号字节指令举例如下,
LDR R2,[R5] ;加载 R5指定地址上的数据(字),放入 R2中
STR R1,[R0,#0x04] ;将 R1的数据存储到 R0+0x04存储单元,R0 值不变
LDRB R3,[R2],#1 ;读取 R2地址上的一字节数据,并保存到 R3中,R2=R3+1
STRB R6,[R7] ;读 R6的数据保存到 R7指定的地址中,只存储一字节数据
加载/存储半字和带符号字节.这类 LDR/STR指令可能加载带符字节\加载带符号半字、加载/存储无符号半字.偏移量格式、寻址方式与加载/存储字和无符号字节指令相同.指令格式如下,
LDR{cond}SB Rd,<地址> ;加载指定地址上的数据(带符号字节),放入 Rd 中
LDR{cond}SH Rd,<地址> ;加载指定地址上的数据(带符号字节),放入 Rd中
LDR{cond}H Rd,<地址> ;加载 半字数据,放 入 Rd中,即 Rd最 低 16位 有效,高 16位清零
STR{cond}H Rd,<地址> ;存储半字数据,要存储的数据在 Rd,最低 16位有效
说明:带符号位半字/字节加载是指带符号位加载扩展到 32 位;无符号位半字加载是指零扩展到 32位,
地址对准--对半字传送的地址必须为偶数.非半字对准的半字加载将使 Rd 内容不可靠,非半字对准的半字存储将使指定地址的 2字节存储内容不可靠,
加载/存储半字和带符号字节指令举例如下,
LDRSB R1[R0,R3] ;将 R0+R3地址上的字节数据读出到 R1,高 24位用符号位扩展
LDRSH R1,[R9] ;将 R9地址上的半字数据读出到 R1,高 16位用符号位扩展
LDRH R6,[R2],#2 ;将 R2 地址上 的半字数据读出到 R6,高 16 位用零 扩展,,R2=R2+1
SHRH R1,[R0,#2]!;将 R1 的数据 保存到 R2+2地址中,只存 储低 2 字 节 数据,R0=R0+2
LDR/STR 指令用于对内存变量的访问,内存缓冲区数据的访问、查表、外围部件的控制操作等等,若使用 LDR指令加载数据到 PC寄存器,则实现程序跳转功能,这样也就实现了程序散转。
变量的访问
NumCount EQU 0x40003000 ;定义变量 NumCount
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 13 页常用 ARM 指令集及 汇 编 Ver,1.0.12

LDR R0,=NumCount ;使用 LDR 伪指令装 载 NumCount的地址到 R0
LDR R1,[R0] ;取出变量值
ADD R1,R1,#1 ;NumCount=NumCount+1
STR R1,[R0] ;保存变量值

GPIO 设置
GPIO-BASE EQU 0Xe0028000 ;定义 GPIO寄存器的基地址

LDR R0,=GPIO-BASE
LDR R1,=0x00FFFF00 ;装载 32位立即数,即设置值
STR R1,[R0,#0x0C] ;IODIR=0x00FFFF00,IODIR 的地址 为 0xE002800C
MOV R1,#0x00F00000
STR R1,[R0,#0x04] ;IOSET=0x00F00000,IOSET 的地址 为 0xE0028004

程序散转

MOV R2,R2,LSL #2 ;功能号乘上 4,以便查表
LDR PC,[PC,R2] ;查表取得对应功能子程序地址,并跳转
NOP
FUN-TAB DCD FUN-SUB0
DCD FUN-SUB1
DCD FUN-SUB2

? LDM 和 STM
批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据.LDM 为加载多个寄存器,STM为存储多个寄存器.允许一条指令传送 16个寄存器的任何子集或所有寄存器.指令格式如下,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 14 页常用 ARM 指令集及 汇 编 Ver,1.0.12
LDM{cond}<模式> Rn{!},reglist{^}
STM{cond}<模式> Rn{!},reglist{^}
LDM /STM的主要用途是现场保护,数据复制,参数传送等。 其模式有 8种,如下:(前面 4种用于数据块的传输,后面 4种是堆栈操作)
(1) IA:每次传送后地址加 4
(2) IB:每次传送前地址加 4
(3) DA:每次传送后地址减 4
(4) DB:每次传送前地址减 4
(5) FD:满递减堆栈
(6) ED:空递增堆栈
(7) FA:满递增堆栈
(8) EA:空递增堆栈
其中,寄存器 Rn为基址寄存器,装有传送数据的初始地址,Rn 不允许为 R15;后缀,!,
表示最后的地址写回到 Rn中;寄存器列表 reglist可包含多于一个寄存器或寄存器范围,
使用“,”分开,如{R1,R2,R6-R9},寄存器排列由小到大排列;,^”后缀不允许在用户模式呈系统模式下使用,若在 LDM指令用寄存器列表中包含有 PC时使用,那么除了正常的多寄存器传送外,将 SPSR拷贝到 CPSR中,这可用于异常处理返回; 使用,^” 后缀进行数据传送且寄存器列表不包含 PC时,加载/存储的是用户模式的寄存器,而不是当前模式的寄存器。
地址对准――这些指令忽略地址的位[1:0]
批量加载/存储指令举例如下,
LDMIA R0!,{R3-R9} ;加载 R0指向的地址上的多字数据,保存到 R3~R9 中,R0值更新
STMIA R1!,{R3-R9} ;将 R3~R9 的数据存储到 R1指向的地址上,R1 值更新
STMFD SP!,{R0-R7,LR} ;现场保存,将 R0~R7、LR 入栈
LDMFD SP!,{R0-R7,PC}^;恢复现场,异常处理返回
在进行数据复制时,先设置好源数据指针,然后使用块拷贝寻址指令 LDMIA/STMIA、
LDMIB/STMIB,LDMDA/STMDA,LDMDB/STMDB 进行读取和存储。 而进行堆栈操作时,则要先设置堆栈指针,一般使用 SP 然后使用堆栈寻址指令 STMFD/LDMFD、STMED。LDMED、
STMFA/LDMFA、STMEA/LDMEA 实现堆栈操作。
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 15 页常用 ARM 指令集及 汇 编 Ver,1.0.12
多寄存器传送指令示意图如图所示,其中 R1为指令执行前的基址寄存器,R1 则为指令执行完后的基址寄存器,
R7
R6
R5 4008H
4004H
4000H
R1’
R1
a)指令 STMIA R1!,{R5-R7}
R7
R6
R5 4008H
4004H
4000H
R1’
R1
b)指令 STMIB R1!,{R5-R7}
R7
R6
R5 4008H
4004H
4000H
R1
R1’
c)指令 STMDA R1!,{R5-R7}
R7
R6 4008H
R5 4004H
4000H
R1
R1’
d)指令 STMDB R1!,{R5-R7}
数据是存储在基址寄存器的地址之上还是之下,地址是在存储第一个值之前还是之后增加还是减少,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 16 页常用 ARM 指令集及 汇 编 Ver,1.0.12
多寄存器传送指令映射
向上生长 向下生长
满 空 满 空
STMIB LDMIB
之前
STMFA LDMED
STMIA LDMIA
增加
之后
STMEA LDMFD
LDMDB STMDB
之前
LDMEA STMFD
LDMDA STMDA
增加
之后
LDMFA STMED
使用 LDM/STM进行数据复制,

LDR R0,=SrcData ;设置源数据地址
LDR R1,=DstData ;设置目标地址
LDMIA R0,{R2-R9} ;加载 8字数据到寄存器 R2~R9
STMIA R1,{R2~R9} ;存储寄存器 R2~R9到目标地址
使用 LDM/STM进行现场寄存器保护,常在子程序中或异常处理使用,
SENDBYTE
STMFD SP!,{R0-R7,LR} ;寄存器入堆

BL DELAY ;调用 DELAY子程序

LDMFD SP!,{R0-R7,PC} ;恢复寄存器,并返回
? SWP
寄存器和存储器交换指令,SWP 指令用于将一个内存单元(该单元地址放在寄存器
Rn 中)的内容读取到一个寄存器 Rd 中,同时将另一个寄存器 Rm 的内容写入到该内存单元中.使用 SWP可实现信号量操作,
指令格式如下,
SWP{cond}{B} Rd,Rm,[Rn]
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 17 页常用 ARM 指令集及 汇 编 Ver,1.0.12
其中,B 为可选后缀,若有 B,则交换字节,否则交换 32位字:Rd 为数据从存储器加载到的寄存器;Rm 的数据用于存储到存储器中,若 Rm与 Rn相同,则为寄存器与存储器内容进行交换;Rn 为要进行数据交换的存储器地址,Rn 不能与 Rd和 Rm相同,
SWP指令举例如下,
SWP R1,R1,[R0] ;将 R1的内容与 R0指向的存储单元的内容进行交换
SWP R1,R2,,[R0] ;将 R0指向的存储单元内容读取一字节数据到 R1中(高
24位清零),并将 R2的内容写入到该内存单元中(最低字节有效)
使用 SWP指令可以方便地进行信号量的操作,
12C_SEM EQU 0x40003000

12C_SEM_WAIT
MOV R0,#0
LDR R0,=12C_SEM
SWP R1,R1,[R0] ;取出信号量,并设置其为 0
CMP R1,#0 ;判断是否有信号
BEQ 12C_SEM_WAIT ;若没有信号,则等待
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 18 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM数据处理指令
数据处理指令大致可分为 3类;数据传送指令(如 MOV,MVN),算术逻辑运算指令
(如 ADD,SUM,AND),比较指令(如 CMP,TST).数据处理指令只能对寄存器的内容进行操作.
所有 ARM 数据处理指令均可选择使用 S 后缀,以影响状态标志.比较指令 CMP,CMN,TST
和 TEQ不需要后缀 S,它们会直接影响状态标志,
ARM数据处理指令
助记符号 说明 操作 条件码位置
MOV Rd,operand2 数据转送 Rd←operand2 MOV {cond}{S}
MVN Rd,operand2 数据非转送 Rd←(operand2) MVN {cond}{S}
ADD Rd,Rn operand2 加法运算指令 Rd←Rn+operand2 ADD {cond}{S}
SUB Rd,Rn operand2 减法运算指令 Rd←Rn-operand2 SUB {cond}{S}
RSB Rd,Rn operand2 逆向减法指令 Rd←operand2-Rn RSB {cond}{S}
ADC Rd,Rn operand2 带进位加法 Rd←Rn+operand2+carry ADC {cond}{S}
SBC Rd,Rn operand2 带进位减法指令 Rd←Rn-operand2-(NOT)Carry SBC {cond}{S}
RSC Rd,Rn operand2 带进位逆向减法指令 Rd←operand2-Rn-(NOT)Carry RSC {cond}{S}
AND Rd,Rn operand2 逻辑与操作指令 Rd←Rn&operand2 AND {cond}{S}
ORR Rd,Rn operand2 逻辑或操作指令 Rd←Rn|operand2 ORR {cond}{S}
EOR Rd,Rn operand2 逻辑异或操作指令 Rd←Rn^operand2 EOR {cond}{S}
BIC Rd,Rn operand2 位清除指令 Rd←Rn&(~operand2) BIC {cond}{S}
CMP Rn,operand2 比较指令 标志 N、Z、C、V←Rn-operand2 CMP {cond}
CMN Rn,operand2 负数比较指令 标志 N、Z、C、V←Rn+operand2 CMN {cond}
TST Rn,operand2 位测试指令 标志 N、Z、C、V←Rn&operand2 TST {cond}
TEQ Rn,operand2 相等测试指令 标志 N、Z、C、V←Rn^operand2 TEQ {cond}
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 19 页常用 ARM 指令集及 汇 编 Ver,1.0.12
数据传送指令
? MOV
数据传送指令.将 8 位 图立即数或寄存器(operant2)传送到目标寄存器 Rd,可用于移位运算等操作.指令格式如下,
MOV{cond}{S} Rd,operand2
MOV指令举例如下,
MOV R1#0x10 ;R1=0x10
MOV R0,R1 ;R0=R1
MOVS R3,R1,LSL #2 ;R3=R1<<2,并影响标志位
MOV PC,LR ;PC=LR,子程序返回
? MVN
数据非传送指令.将 8位图立即数或寄存器(operand2)按位取反后传送到目标寄存器(Rd),因为其具有取反功能,所以可以装载范围更广的立即数.指令格式如下,
MVN{cond}{S} Rd,operand2
MVN指令举例如下,
MVN R1,#0xFF ;R1=0xFFFFFF00
MVN R1,R2 ;将 R2取反,结果存到 R1
算术逻辑运算指令
? ADD
加法运算指令.将 operand2数据与 Rn的值相加,结果保存到 Rd寄存器.指令格式如下,
ADD{cond}{S} Rd,Rn,operand2
ADD指令举例如下,
ADDS R1,R1,#1 ;R1=R1+1
ADD R1,R1,R2 ;R1=R1+R2
ADDS R3,R1,R2,LSL #2 ;R3=R1+R2<<2
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 20 页常用 ARM 指令集及 汇 编 Ver,1.0.12
? SUB
减法运算指令.用寄存器 Rn减去 operand2.结果保存到 Rd中.指令格式如下,
SUB{cond}{S} Rd,Rn,operand2
SUB指令举例如下
SUBS R0,R0,#1 ;R0=R0-1
SUBS R2,R1,R2 ;R2=R1-R2
SUB R6,R7,#0x10 ;R6=R7-0x10
? RSB
逆向减法指令.用寄存器 operand2减法 Rn,结果保存到 Rd中.指令格式如下,
RSB{cond}{S} Rd,Rn,operand2
SUB指令举例如下
RSB R3,R1,#0xFF00 ;R3=0xFF00-R1
RSBS R1,R2,R2,LSL #2 ;R1=R2<<2-R2=R2×3
RSB R0,R1,#0 ;R0=-R1
? ADC
带进位加法指令.将 operand2的数据与 Rn的值相加,再加上 CPSR中的 C条件标志位.结果保存到 Rd寄存器.指令格式如下;
ADC{cond}{S} Rd,Rn,operand2
ADC指令举例如下,
ADDS R0,R0,R2
ADC R1,R1,R3 ;使用 ADC实现 64位加法,(R1、R0)=(R1、R0)+(R3、R2)
? SBC
带进位减法指令。用寄存器 Rn 减去 operand2,再减去 CPSR 中的 C 条件标志位的非(即若 C标志清零,则结果减去 1),结果保存到 Rd中。指令格式如下,
SCB{cond}{S}Rd,Rn,operand2
SBC指令举例如下
SUBS R0,R0,R2
SBC R1,R1,R3 ;使用 SBC实现 64位减法,(R1,R0)-(R3,R2)
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 21 页常用 ARM 指令集及 汇 编 Ver,1.0.12
? RSC
带进位逆向减法指令.用寄存器 operand2减去 Rn,再减去 CPSR中的 C条件标志位,
结果保存到 Rd中.指令格式如下,
RSC{cond}{S} Rd,Rn,operand2
RSC指令举例如下,
RSBS R2,R0,#0
RSC R3,R1,#0 ;使用 RSC指令实现求 64位数值的负数
? AND
逻辑与操作指令.将 operand2 值与寄存器 Rn 的值按位作逻辑与操作,结果保存到
Rd中.指令格式如下,
AND{cond}{S} Rd,Rn,operand2
AND指令举例如下,
ANDS R0,R0,#x01 ;R0=R0&0x01,取出最低位数据
AND R2,R1,R3 ;R2=R1&R3
? ORR
逻辑或操作指令.将 operand2的值与寄存器 Rn的值按位作逻辑或操作,结果保存到
Rd中.指令格式如下,
ORR{cond}{S} Rd,Rn,operand2
ORR指令举例如下,
ORR R0,R0,#x0F ;将 R0的低 4位 置 1
MOV R1,R2,LSR #4
ORR R3,R1,R3,LSL #8 ;使用 ORR指令将近 R2的高 8位数据移入到 R3低8位中
? EOR
逻辑异或操作指令.将 operand2的值与寄存器 Rn的值按位作逻辑异或操作,结果保存到 Rd中.指令格式如下,
EOR{cond}{S}Rd,Rn,operand2
EOR指令举例如下,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 22 页常用 ARM 指令集及 汇 编 Ver,1.0.12
EOR R1,R1,#0x0F ;将 R1的低 4位取反
EOR R2,R1,R0 ;R2=R1^R0
EORS R0,R5,#0x01 ;将 R5和 0x01进行逻辑异或,结果保存到 R0,并影响标志位
? BIC
位清除指令.将寄存器 Rn的值与 operand2的值的反码按位作逻辑与操作,结果保存到 Rd中.指令格式如下,
BIC{cond}{S}Rd,Rn,operand2
BIC指令举例如下,
BIC R1,R1,#0x0F ;将 R1的低 4位清零,其它位不变
BIC R1,R2,R3 ;将拭的反码和 R2相逻辑与,结果保存到 R1
比较指令
? CMP
比较指令.指令使用寄存器 Rn 的值减去 operand2 的值,根据操作的结果理新 CPSR
中的相应条件标志位,以便后面的指令根据相 应的条件标志来判断是否执行.指令格式如下,
CMP{cond} Rn,operand2
CMP指令举例如下,
CMP R1,#10 ;R1与 10比较,设置相关标志位
CMP R1,R2 ;R1与 R2比较,设置相关标志位
CMP指令与 SUBS指令的区别在于 CMP指令不保存运算结果.在进行两个数据大小判断时,常用 CMP指令及相应的条件码来操作,
? CMN
负数比较指令.指令使用寄存器 Rn 与值加上 operand2 的值,根据操作的结果理新
CPSR 中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行,指令格式如下,
CMN{cond} Rn,operand2
CMN R0,#1 ;R0+1,判断 R0是否为 1的补码,若是 Z置位
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 23 页常用 ARM 指令集及 汇 编 Ver,1.0.12
CMN指令与 ADDS指令的区别在于 CMN指令不保存运算结果.CMN 指令可用于负数比较,比如 CMNR0,#1 指令则表示 R0 与-1 比较,若 R0 为-(即 1 的补码),则 Z 置 位,否则 Z
复位,
? TST
位测试指令.指令将寄存器 Rn的值与 operand2的值按位作逻辑与操作,根据操作的结果理新 CPSR 中相应的条件标志位,以便后面指令根据相应的条件标志来判断是否执行.指令格式如下,
TST{cond} Rn,operand2
TST指令举例如下,
TST R0,#0x01 ;判断 R0的最低位是否为 0
TST R1,#0x0F ;判断 R1的低 4位是否为 0
TST指令与 ANDS指令的区别在于 TST4指令不保存运算结果.TST 指令通常于 EQ,NE
条件码配合使用,当所有测试位均为 0时,EQ 有效,而只要有一个测试为不为 0,则 NE有效,
? TEQ
相等测试指令.指令寄存器 Rn的值与 operand2的值按位作逻辑异或操作,根据操作的结果理新 CPSR 中相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行.指令格式如下,
TEQ{cond} Rn,operand2
TEQ指令举例如下,
TEQ R0,R1 ;比较 R0与 R1是否相等(不影响 V位 和 C位)
TST指令与 EORS指令的区别在于 TST指令不保存运算结果.使用 TEQ进行相等测试,
常与 EQNE条件码配合使用,当两个数据相等时,EQ 有效,否则 NE有效,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 24 页常用 ARM 指令集及 汇 编 Ver,1.0.12
乘法指令
ARM7TDMI(-S)具有 32×32 乘法指令,32×32 乘加指令,32×32 结果为 64 位的乘/
乘法指令,
ARM乘法指令
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL RdLo,RdHi,Rm,Rs 64位无符号乘法指令 (RdLo,RdHi)←Rm*Rs UMULL{cond}{S}
UMLAL RdLo,RdHi,Rm,Rs 64位无符号乘加指令 (RdLo,RdHi)←Rm*Rs+(RdLo,RdHi) UMLAL{cond}{S}
SMULL RdLo,RdHi,Rm,Rs 64位有符号乘法指令 (RdLo,RdHi)←Rm*Rs SMULL{cond}{S}
SMLAL RdLo,RdHi,Rm,Rs 64位有符号乘加指令 (RdLo,RdHi)←Rm*Rs+(RdLo,RdHi) SMLAL{cond}{S}
? MUL
32位乘法指令.指令将 Rm和 Rs中的值相乘,结果的低 32位保存到 Rd中.指令格式如下,
MUL{cond}{S} Rd,Rm,Rs
MUL指令举例如下,
MUL R1,R2,R3 ;R1=R2×R3
MULS R0,R3,R7 ;R0=R3×R7,同时设置 CPSR中的 N位 和 Z位
? MLA
32位乘加指令.指令将 Rm和 Rs中的值相乘,再将乘积加上第 3个操作数,结果的低
32位保存到 Rd中.指令格式如下,
MLA{cond}{S} Rd,Rm,Rs,Rn
MLA指令举例如下,
MLA R1,R2,R3,R0 ;R1=R2×R3+10
? UMULL
64位无符号乘法指令.指令将 Rm和 Rs中的值作无符号数相乘,结果的低 32位保存到 RsLo中,而高 32位保存到 RdHi中,.指令格式如下,
UMULL{cond}{S} RdLo,RdHi,Rm,Rs
UMULL指令举例如下,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 25 页常用 ARM 指令集及 汇 编 Ver,1.0.12
UMULL R0,R1,R5,R8 ;(R1、R0)=R5×R8
? UMLAL
64 位无符号乘加指令.指令将 Rm 和 Rs 中的值作无符号数相乘,64 位乘积与
RdHi,RdLo 相加,结果的低 32 位保存到 RdLo 中,而高 32 位保存到 RdHi 中.指令格式如下,
UMLAL{cond}{S} RdLo,RdHi,Rm,Rs
UMLAL指令举例如下,
UMLAL R0,R1,R5,R8 ;(R1,R0)=R5×R8+(R1,R0)
? SMULL
64位有符号乘法指令.指令将 Rm和 Rs中的值作有符号数相乘,结果的低 32位保存到 RdLo中,而高 32位保存到 RdHi中.指令格式如下,
SMULL{cond}{S} RdLo,RdHi,Rm,Rs
SMULL指令举例如下,
SMULL R2,R3,R7,R6 ;(R3,R2)=R7×R6
? SMLAL
64 位有符号乘加指令.指令将 Rm 和 Rs 中的值作有符号数相乘,64 位乘积与
RdHi,RdLo,相加,结果的低 32位保存到 RdLo中,而高 32位保存到 RdHi中.指令格式如下,
SMLAL{cond}{S} RdLo,RdHi,Rm,Rs
SMLAL指令举例如下,
SMLAL R2,R3,R7,R6 ;(R3,R2)=R7×R6+(R3,R2)
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 26 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM跳转指令
在 ARM 中有两种方式可以实现程序的跳转,一种是使用跳转指令直接跳转,另一种则是直接向 PC寄存器赋值实现跳转.跳转指令有跳转指令 B,带链接的跳转指令 BL带状态切换的跳转指令 BX,
跳转指令
助记符 说明 操作 条件码位置
B label 跳转指令 Pc←label B{cond}
BL label 带链接的跳转指令 LR←PC-4,PC←label BL{cond}
BX Rm 带状态切换的跳转指令 PC←label,切换处理状态 BX{cond}
? B
跳转指令.跳转到指定的地址执行程序.指令格式如下;
B{cond} label
跳转指令 B举例如下,
B WAITA ;跳转到 WAITA标号处
B 0x1234 ;跳转到绝对地址 0x1234处
跳转到指令 B限制在当前指令的±32Mb 的范围内,
? BL
带链接的跳转指令.指令将下一条指令的地址拷贝到 R14(即 LR)链接寄存器中,然后跳转到指定地址运行程序.指令格式如下,
BL{cond} label
带链接的跳转指令 BL举例如下,
BL DELAY
跳转指令 B限制在当前指令的±32MB 的范围内.BL 指令用于子程序调用
? BX
带状态切换的跳转指令.跳转到 Rm指定的地址执行程序,若 Rm的位[0]为 1,则跳转
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 27 页常用 ARM 指令集及 汇 编 Ver,1.0.12
时自动将 CPSR中的标志 T置位,即把目标地址的代码解释为 Thumb代码;若 Rm的位[0]
为 0,则跳转时自动将 CPSR中的标志 T复位,即把目标地址的代码解释为 ARM代码.指令格式如下,
BX{cond} Rm
带状态切换的跳转指令 BX举例如下
ADRL R0,ThumbFun+1
BX R0 ;跳转到 R0指定的地址,并根据 R0的最低位来切换处理器状态
ARM协处理器指令
ARM支持协处理器操作,协处理器的控制要通过协处理器命令实现,
ARM协处理器指令
助记符 说明 操作 条件码位置
CDP
coproc,opcodel,CRd,CRn,CRm{,opcode2}
协处理器数据操作指令 取决于协处理器 CDP{cond}
LDC{L} coproc,CRd〈地址〉 协处理器数据读取指令 取决于协处理器 LDC{cond}{L}
STC{L} coproc,CRd,〈地址〉 协处理器数据写入指令 取决于协处理器 STC{cond}{L}
MCR coproc,opcodel,Rd,CRn,{,opcode2}
ARM寄存器到协处理器寄存器的数据传送指令
取决于协处理器 MCR{cond}
MRC coproc,opcodel,Rd,CRn,{,opcode2}
协处理器寄存器到 ARM寄存器到数据传送指令
取决于协处理器 MCR{cond}
? CDP
协处理器数据操作指令.ARM 处理器通过 CDP 指令通知 ARM 协处理器执行特定的操作.该操作由协处理器完成,即对命令的参数的解释与协处理器有关,指令的使用取决于协处理器.若协处理器不能成功地执行该操作,将产生未定义指令异常中断.指令格式如下,
CDP{cond} coproc,opcodel,CRd,CRn,CRm{,opcode2}
其中,coproc 指令操作的协处理器名.标准名为 pn,n为 0~15,
opcodel协处理器的特定操作码
CRd 作为目标寄存器的协处理器寄存器,
CRN 存放第 1个操作数的协处理器寄存器,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 28 页常用 ARM 指令集及 汇 编 Ver,1.0.12
CRm 存放第 2个操作数的协处理器寄存器,
Opcode2 可选的协处理器特定操作码,
CDP 指令举例如下,
CDP p7,0,c0,c2,c3,0 ;协处理器 7操作,操作码为 0,可选操作码为 0
CDP p6,1,c3,c4,c5 ;协处理器操作,操作码为 1
? LDC
协处理器数据读取指令.LDC 指令从某一连续的内存单元将数据读取到协处理器的寄存器中.协处理器数据的数据的传送,由协处理器来控传送的字数.若协处理器不能成功地执行该操作,将产生未定义指令异常中断.指令格式如下;
LDC{cond}{L} coproc,CRd,<地址>
其中,L 可选后缀,指明是长整数传送,
coproc 指令操作的协处理器名.标准名为 pn,n 为 0~15
CRd 作为目标寄存的协处理器寄存器,
<地址> 指定的内存地址
LDC指令举例如下,
LDC p5,c2,[R2,#4];读取 R2+4指向 的内存单元的数据,传送到协处理器 p5的 c2寄存器中
LDC p6,c2,[R1] ;读取是指向的内存单元的数据,传送 到协处理器 p6 的 c2 寄 存 器 中
? STC
协处理器数据写入指令.STC 指令将协处理器的寄存器数据写入到某一连续的内存单元中.进行协处理器数据的数据传送,由协处理器来控制传送的字数.若协处理器不能成功地执行该操作,将产生未定义指令异常中断.指令格式如下;
STC{cond}{L} coproc,CRd,<地址>
其中,
L 可选后缀,指明是长整数传送,
coproc 指令操作的协处理器名.标准名为 pn,n为 0~15
CRd 作为目标寄存的协处理器寄存器,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 29 页常用 ARM 指令集及 汇 编 Ver,1.0.12
<地址> 指定的内存地址
STC指令举例如下,
STC p5,c1,[R0]
STC p5,c1,[Ro,#-0x04]
? MCR
ARM寄存器到协处理器寄存器的数据传送指令.MCR 指令将 ARM处理器的寄存器中的数据传送到协处理器的寄存器中.若协处理器 不能成功地执行该操作,将产生未定义指令异常中断.指令格式如下;
MCR{cond} coproc,opcodel,Rd,CRn,CRm{,opcode2}
其中 coproc 指令操作的协处理器名.标准名为 pn,n为 0~15,
cpcodel 协处理器的特定操作码,
CRD 作为目标寄存器的协处理器寄存器,
CRn 存放第 1个操作数的协处理器寄存器
CRm 存放第 2个操作数的协处理器寄存器,
Opcode2 可选的协处理器特定操作码,
MCR指令举例如下,
MCR p6,2,R7,c1,c2,
MCR P7,0,R1,c3,c2,1,
? MRC
协处理器寄存器到 ARM 寄存器到的数据传送指令.MRC 指令将协处理器寄存器中的数据传送到 ARM 处理器的寄存器中.若协处理器不能成功地执行该操作.将产生未定义异常中断.指令格式如下,
MRC {cond} coproc,opcodel,Rd,CRn,CRm{,opcode2}
其中 coproc 指令操作的协处理器名.标准名为 pn,n,为 0~15
opcodel 协处理器的特定操作码,
CRd 作为目标寄存器的协处理器寄存器,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 30 页常用 ARM 指令集及 汇 编 Ver,1.0.12
CRn 存放第 1个操作数的协处理器寄存器,
CRm 存放第 2个操作数的协处理器寄存器,
opcode2 可选的协处理器特定操作码,
MRC指令举例如下
MRC p5,2,R2,c3,c2
MRC p7,0,R0,c1,c2,1
ARM杂项指令
助记符 说明 操作 条件码位置
SWI immed_24 软中断指令 产生软中断,处理器进入管理模式 SWI{cond}
MRS Rd,psr 读状态寄存器指令 Rd←psr,psr 为 CPSR或 SPSR MRS{cond}
MSR psr_fields,Rd/#immed_8r 写状态寄存器指令 psr_fields←Rd/#immed_8r,p sr为 CPSR 或 SPSR MSR{cond}
? SWI
软中断指令.SWI 指令用于产生软中断,从而实现在用户模式变换到管理模式,CPSR
保存到管理模式的 SPSR中,执行转移到 SWI向量,在其它模式下也可使用 SWI指令,处理同样地切换到管理模式.指令格式如下;
SWI{cond} immed_24
其中 immed_24 24 位立即数,值为 0~16777215之间的整数
SWI指令举例如下,
SWI 0 ;软中断,中断立即数为 0
SWI 0x123456 ;软中断,中断立即数为 0x123456
使用 SWI指令时,通常使用以下两种方法进行传递参数,SWI 异常中断处理程序就可以提供相关的服务,这两种方法均是用户软件协定,SWI 异常中断处理程序要通过读取引起软中断的 SWI指令,以取得 24位立即数,
1.指令 24位的立即数指定了用户请求的服务类型,参数通过用寄存器传递
MOV R0,#34 ;设置了功能号为 34
SWI 12 ;调用 12号软中断
2.指令中的 24位立即数被忽略,用户请求的服务类型由寄存器 R0的值决定,参数通
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 31 页常用 ARM 指令集及 汇 编 Ver,1.0.12
过其它的通用寄存器传递,
MOV R0,#12 ;调用 12号软中断
MOV R1,#34 ;设置子功能号为 34
SWI 0
在 SWI异常中断处理程序中,取出 SWI立即数的步骤为:首先确定引起软中断的 SWI
指令是 ARM指令还时 Thumb指令,这可通过对 SPSR访问得到:然后要取得该 SWI指令的地址,这可通过访问 LR寄存器得到:接着读出指令,分解出立即数,
读出 SWI立即数
T_bit EQU 0x20
SWI_Hander
STMFD SP!,{R0_R3,R12,LR} ;现场保护
MRS R0,SPSR ;读取 SPSR
STMFD SP!,{R0} ;保存 SPSR
TST R0,#T_bit ;测试 T标志位
LDRNEH R0,[LR,#-2] ;若是 Thumb指令,读取指令码(16 位)
BICNE R0,R0,#0xFF00 ;取得 Thumb指令的 8位立即数
LDREQ R0,[LR,#-4] ;若是 ARM指令,读取指令码(32 位)
BICNQ R0,R0,#0xFF00000 ;取得 ARM指令的 24位立即数

LDMFD SP!,{R0-R3,R12,PC}^ ;SWI异常中断返回
? MRS
读状态寄存器指令.在 ARM 处理器中,只有 MRS 指令可以状态寄存器 CPSR 或 SPSR
读出到通用寄存器中.指令格式如下;
MRS{cond} Rd,psr
其中; Rd 目标寄存器.Rd 不允许为 R15,
psr CPSR或 SPSR
SWI指令举例如下
MRS R1,CPSR ;将 CPSR状态寄存器读取,保存到 R1中
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 32 页常用 ARM 指令集及 汇 编 Ver,1.0.12
MRS R2,SPSR ;将 SPSR状态寄存器读取,保存到 R2中
MRS指令读取 CPSR,可用来判断 ALU的状态标志,或 IRQ,FIQ中断是否允许等;在异常处理程序中,读 SPSR 可知道进行异常前的处理器状态等.MRS 与 MSR 配合使用,实现
CPSR 或 SPSR 寄存器的读—修改---写操作,可用来进行处理器模式切换(),允许?禁止
IRQ/FIQ 中断等设置.另外,进程切换或允许异常中断嵌套时,也需要使用 MRS 指令读取
SPSR状态值.保存起来,
使能 IRQ 中断
ENABLE_IRQ
MRS R0,CPSR
BIC R0.R0,#0x80
MSR CPSR_c,R0
MOV PC,LR
禁能 IRQ 中断
DISABLE_IRQ
MRS R0,CPSR
ORR R0,R0,#0x80
MSR CPSR_c,R0
MOV PC,LR
? MSR
写状态寄存器指令.在 ARM 处理器中.只有 MSR 指令可以直接设置状态寄存器 CPSR
或 SPSR.指令格式如下
MSR{cond} psr_fields,#immed_8r
MSR{cond} psr_fields,Rm
其中,psr CPSR 或 SPSR
fields 指定传送的区域.Fields 可 以是以下的一种或多种(字母必须为小写),
c控制域屏蔽字节(psr[7…0])
x扩展域屏蔽字节(psr[15…8])
s状态域屏蔽字节(psr[23.…16])
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 33 页常用 ARM 指令集及 汇 编 Ver,1.0.12
f标志域屏蔽字节(psr[31…24])
immed_8r 要传送到状态寄存器指定域的立即数,8 位,
Rm 要传送到状态寄存器指定域的数据的源寄存器,
MSR指令举例如下
MSR CPSR_c,#0xD3 ;CPSR[7…0]=0xD3,即切换到管理模式,
MSR CPSR_cxsf,R3 ;CPSR=R3
只有在特权模式下才能修改状态寄存器,
程序中不能通过 MSR指令直接修改 CPSR中的 T控制位来实现 ARM状态/Thumb 状态的切换,必须使用 BX指令完成处理器状态的切换(因为 BX指令属转移指令,它会打断流水线状态,实现处理器状态切换).MRS 与 MSR配合使用,实现 CPSR或 SPSR寄存器的读---
修改---写操作,可用来进行处理器模式切换、允许/禁止 IRQ/FIQ中断等设置,,
堆栈指令实始化
INITSTACK
MOV R0,LR ;保存返回地址;设置管理模式堆栈
MSR CPSR_c,#0xD3
LDR SP,StackSvc;设置中断模式堆栈
MSR CPSR_c,#0xD2
LDR SP,StackIrq

ARM伪指令
ARM伪指令不是 ARM指令集中的指令,只是为了编程方便编译器定义了伪指令,使用时可以像其它 ARM指令一样使用,但在编译时这些指令将被等效的 ARM指令代替.ARM 伪指令有四条,分别为 ADR伪指令,ADRL 伪指令,LDR 伪指令,NOP 伪指令,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 34 页常用 ARM 指令集及 汇 编 Ver,1.0.12
? ADR
小范围的地址读取伪指令.ADR 指令将基于 PC 相对偏移的地址值读取到寄存器中.
在汇编编译源程序时,ADR 伪指令被编译器替换成一条合适的指令.通常,编译器用一条
ADD 指令或 SUB 指令来实现该 ADR 伪指令的功能,若不能用一条指令实现,则产生错误,
编译失败,
ADR伪指令格式如下
ADR{cond} register,exper
其中 register 加载的目标寄存器
exper 地址表达式.当地址值是非字地齐时,取值范围-255~255 字节之间;当地址是字对齐时,取值范围-1020~1020 字节之间.
对于基于 PC相对偏移的地址 值时,给定范围是相对当前指令地址后两个字处(因为 ARM7TDMI为三级流水线),
ADR伪指令举例如下;
LOOP MOV R1,#0xF0

ADR R2,LOOP ;将 LOOP的地址放入 R2
ADR R3,LOOP+4
可以用 ADR加载地址,实现查表,

ADR R0,DISP_TAB ;加载转换表地址
LDRB R1,[R0,R2] ;使用 R2作为参数,进行查表

DISP_TAB
DCB 0Xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90
? ADRL
中等范围的地址读取伪指令.ADRL 指令将基于 PC 相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比 ADR伪指令可以读取更大范围的地址。 在汇编编
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 35 页常用 ARM 指令集及 汇 编 Ver,1.0.12
译源程序时,ADRL 伪指令被编译器替换成两个条合适的指令。若不能用两条指令实现
ADRL伪指令功能,则产生错误,编译失败。ADRL 伪指令格式如下,
ADR{cond} register,exper
其中:register 加载的目标寄存器。
expr 地址表达式。当地址值是非字对齐时,取范围-64K~64K 字节之间; 当地址值是字对齐时,取值范围-256K~256K 字节之间。
ADRL伪指令举例如下;
ADRL R0,DATA_BUF

ADRL R1 DATA_BUF+80

DATA_BUF
SPACE 100 ;定义 100字节缓冲区
可以且用 ADRL加载地址,实现程序跳转,中等范围地址的加载

ADR LR,RETURNI ;设置返回地址
ADRL R1 Thumb_Sub+1;取得了 Thumb子程序入口地址,且 R1的0位 置1
BX R1 ;调用 Thumb子程序,并切换处理器状态
RETURNI

CODE16
Thumb_Sub
MOV R1,#10

? LDR
大范围的地址读取伪指令.LDR 伪指令用于加载 32位的立即数或一个地址值到指定寄存器.在汇编编译源程序时,LDR 伪指令被编译器替换成一条合适的指令.若加载的常数未超出 MOV或 MVN的范围,则使用 MOV或 MVN指令代替该 LDR伪指令,否则汇编器将常
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 36 页常用 ARM 指令集及 汇 编 Ver,1.0.12
量放入字池,并使用一条程序相对偏移的 LDR指令从文字池读出常量.LDR 伪指令格式如下;
LDR{cond} register,=expr/label_expr
其中 register 加载的目标寄存器
expr 32位立即数,
label_expr 基于 PC的地址表达式或外部表达式,
LADR 伪指令举例如下,
LDR R0,=0x123456 ;加载 32位立即数 0x12345678
LDR R0,=DATA_BUF+60 ;加载 DATA_BUF地址+60

LTORG ;声明文字池
伪指令 LDR常用于加载芯片外围功能部件的寄存器地址(32 位立即数),以实现各种控制操作
加载 32 位立即数

LDR R0,=IOPIN ;加载 GPIO寄存器 IOPIN的地址
LDR R1,[R0] ;读取 IOPIN寄存器的值

LDR R0,=IOSET
LDR R1,=0x00500500
STR R1,[R0] ;IOSET=0x00500500

从 PC到文字池的偏移量必须小于 4KB
与 ARM指令的 LDR相比,伪指令的 LDR的参数有“=”号
? NOP
空 操 作 伪 指 令,NOP 伪 指 令 在 汇 编 时 将 会 被 代 替 成 ARM 中 的 空 操 作,比 如 可 能 为
MOV,R0,R0指令等,NOP 伪指令格式如下
NOP
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 37 页常用 ARM 指令集及 汇 编 Ver,1.0.12
NOP可用于延时操作,
软件延时

DELAY1
NOP
NOP
NOP
SUBS R1,R1,#1
BNE DELAY1

IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 38 页常用 ARM 指令集及 汇 编 Ver,1.0.12
Thumb 指令集
Thumb指令可以看作是 ARM指令压缩形式的子集,是针对代码密度的问题而提出的,它具有 16 位的代码密度,Thumb 不是一个完整的体系结构,不能指望处理只执行
Thumb指令而不支持 ARM指令集.因此,Thumb 指令只需要支持通用功能,必要时可以借助于完善的 ARM指令集,比如,所有异常自动进入 ARM状态,
在编写 Thumb 指令时,先要使用伪指令 CODE16 声明,而且在 ARM 指令中要使用 BX
指令跳转到 Thumb 指令,以切换处理器状态.编写 ARM 指令时,则可使用伪指令 CODE32
声明,
Thumb指令集与ARM指令集的区别
Thumb指令集没有协处理器指令,信号量指令以及访问 CPSR或 SPSR的指令,没有乘加指令及 64位乘法指令等,且指令的第二操作数受到限制;除了跳转指令 B有条件执行功能外,其它指令均为无条件执行;大多数 Thumb 数据处理指令采用 2 地址格式.Thumb
指令集与 ARM指令的区别一般有如下几点,
? 跳转指令
程序相对转移,特别是条件跳转与 ARM代码下的跳转相比,在范围上有更多的限制,
转向子程序是无条件的转移,
? 数据处理指令
数据处理指令是对通用寄存器进行操作,在大 多数情况下,操作的结果须放入其中一个操作数寄存器中,而不是第 3个寄存器中,
数据处理操作比 ARM状态的更少,访问寄存器 R8~R15受到一定限制,
除 MOV 和 ADD 指令访问 器 R8~R15 外,其它数据处 理指令总是更新 CPSR 中 的 ALU 状 态 标志,
访问寄存器 R8~R15的 Thumb数据处理指令不能更新 CPSR中的 ALU状态标志,
? 单寄存器加载和存储指令
在 Thumb状态下,单寄存器加载和存储指令只能访问寄存器 R0~R7
? 批量寄存器加载和存储指令
LDM和 STM指令可以将任何范围为 R0~R7的寄存器子集加载或存储,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 39 页常用 ARM 指令集及 汇 编 Ver,1.0.12
PUSH和 POP指令使用堆栈指令 R13作为基址实现满递减堆栈.除 R0~R7外,PUSH 指令还可以存储链接寄存器 R14,并且 POP指令可以加载程序指令 PC
Thumb存储器访问指令
Thumb指令集的 LDM和 SRM指令可以将任何范围为 R0~R7的寄存器子集加载或存储.
批量寄存器加载和存储指令只有 LDMIA,STMIA指令,即每次传送先加载/存储数据,然后地址加 4.对堆栈处理只能使用 PUSH指令及 POP指令,
Thumb存储器访问指令
助记符 说明 操作 影响标志
LDR Rd,[Rn,#immed_5×4] 加载字数据 Rd←[Rm,#immed_5×4],Rd,Rn 为 R0~R7 无
LDRH Rd,[Rn,#immed_5×2] 加载无符半字数据 Rd←[Rm,#immed_5×2],Rd,Rn 为 R0~R7 无
LDRB Rd,[Rn,#immed_5×1] 加载无符字节数据 Rd←[Rm,#immed_5×1],Rd,Rn 为 R0~R7 无
STR Rd,[Rn,#immed_5×4] 存储字数据 Rn,#immed_5×4Rd←Rd,Rn 为 R0~R7 无
STRH Rd,[Rn,#immed_5×2] 存储无符半辽数据 Rn,#immed_5×2]Rd←Rd,Rn 为 R0~R7 无
STRB Rd,[Rn#immed_5×1] 存储无符字节数据 Rn,#immed_5×1]Rd←Rd,Rn 为 R0~R7 无
LDR Rd,[Rn,Rm] 加载字数据 Rd←[Rn,Rm],Rd,Rn,Rm 为 R0~R7 无
LDRH Rd,[Rn,Rm] 加载无符半字数据 Rd←[Rn,Rm],Rd,Rn,Rm 为 R0~R7 无
LDRB Rd,[Rn,Rm] 加载无符字节数据 Rd←[Rn,Rm],Rd,Rn,Rm 为 R0~R7 无
LDRSH Rd[Rn,Rm] 加载有符半字数据 Rd←[Rn,Rm],Rd,Rn,Rm 为 R0~R7 无
LDRSB Rd[Rn,Rm] 加载有符字节数据 Rd←[Rn,Rm],Rd,Rn,Rm 为 R0~R7 无
STR Rd,[Rn,Rm] 存储字数据 [Rn,Rm]←Rd,Rd,Rn,Rm 为 R0~R7 无
STRH Rd,[Rn,Rm] 存储无符半字数据 [Rn,Rm]←Rd,Rd,Rn,Rm 为 R0~R7 无
STRB Rd,[Rn,Rm] 存储无符字节数据 [Rn,Rm]←Rd,Rd,Rn,Rm 为 R0~R7 无
LDR Rd,[PC,#immed_8×4] 基于 PC加载字 数据 Rd←{PC,#immed_8×4]Rd 为 R0~R7 无
LDR Rd,label 基于 PC加载字 数据 Rd←[label],Rd 为 R0~R7 无
LDR Rd,[SP,#immed_8×4] 基于 SP加载字 数据 Rd←{SP,#immed_8×4]Rd 为 R0~R7 无
STR Rd,[SP,#immed_8×4] 基于 SP存储字 数据 {SP,#immed_8×4]←Rd,Rd 为 R0~R7 无
LDMIA Rn{!}reglist 批量(寄存器)加载 regist←[Rn…],Rn 回存等(R0~R7) 无
STMIA Rn{!}reglist 批量(寄存器)加载 [Rn…]←reglist,Rn 回存等(R0~R7) 无
PUSH {reglist[,LR]} 寄存器入栈指令 [SP…]←reglist[,LR],SP 回存等(R0~R7,LR) 无
POP {reglist[,PC]} 寄存器入栈指令 reglist[,PC]←[SP…],SP 回存等(R0~R7,PC) 无
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 40 页常用 ARM 指令集及 汇 编 Ver,1.0.12
? LDR 和 STR
立即数偏移的 LDR和 STR指令.存储器的地址以一个寄存器的立即数偏移指明.指令格式如下,
LDR Rd,[Rn,#immed_5×4] ;加载指定地址上的数据(字),放入 Rd 中
STR Rd,[Rn,#immed_5×4] ;存储 数据(字)到 指定地址的存储单元,要 存储数据在 Rd 中
LDRH Rd,[Rn,#immed_5×4] ;加载 半字数据,放 入 Rd 中,即 Rd 低 16 位有 效,高 16 位 清零
STRH Rd,[Rn,#immed_5×4] ;存储半字数据,要存储的数据在 Rd,最低 16 位有效
LDRB Rd,[Rn,#immed_5×4] ;加载 字节数据,放 入 Rd中,即 Rd最低字节有效,高 24位 清零
STRB Rd,[Rn,#immed_5×4] ;存储字节数据,要存储的数据在 Rd,最低字节有效
其中 Rd 加载或存储的寄存器.必须为 R0~R7,
Rn 基址寄存器.必须为 R0~R7,
immed_5×N 偏移量.它是一个无符立即数表达式,其取值为(0~3)×N
立即数偏移的半字和字节加载是无符号的.数据加载到 Rd 的最低有效半字或字节,Rd 的其余位补 0,
地址对准一一字传送时,必须保证传送地址为 32 位对准.半字传送时,必须保证传送地址为 16位对准
立即数偏移的 LDR和 STR指令举例如下;
LDR R0,[R1,#0x4]
STR R3,[R4]
LDRH R5,[R0,#0x02]
STRH R1,[R0,#0x08]
LDRB R3,[R6,#20]
STRB R1,[R0,#31]
寄存器偏移的 LDR和 STR指令.存储器的地址用一个寄存器的基于寄存器偏移来指明.指令格式如下,
LDR Rd,[Rn,Rm] ;加载一个字数据
STR Rd,[Rn,Rm] ;存储一个字数据
LDRH Rd,[Rn,Rm] ;加载一个无符半字数据
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 41 页常用 ARM 指令集及 汇 编 Ver,1.0.12
STRH Rd,[Rn,Rm] ;存储一个无符半字数据
LDRB Rd,[Rn,Rm] ;加载一个无符字节数据
STRB Rd,[Rn,Rm] ;存储一个无符字节数据
LDRSH Rd,[Rn,Rm] ;加载一个有符半字数据
LDRSB Rd,[Rn,Rm] ;存储一个有符半字数据
其中,Rd 加载或存储的寄存器.必须为 R0~R7
Rn 基址寄存器.必须为 R0~R7
Rm 内含偏移量的寄存器.必须为 R0~R7,
寄存器偏移的半字和字节加载可以是有符号或无符号的,数据加载到 Rd 的其余位拷贝符号位,
地址对准—字传送时,必须保证传送地址为 32 位对准.半字传送时,必须保证传送地址为 16位对准,
寄存器偏移的 LDR和 STR指令举例如下;
LDR R3,[R1,R0]
STR R1,[R0,R2]
LDRH R6,[R0,R1]
STRH R0,[R4,R5]
LDRB R2,[R5,R1]
STRB R1,[R3,R2]
LDRSH R7,[R6,R3]
LDRSB R5,[R7,R2]
PC 或 SP 相 对偏移的 LDR 和 STR 指令.用 PC 或 SP 寄 存器中的值的立即数偏移来指明存储器的地址.指令格式如下,
LDR Rd,[PC,#immed_8×4]
LDR Rd,label
LDR Rd,[SP,#immed_8×4]
STR Rd,[SP,#immed_8×4]
其中,Rd 加载或存储的寄存器.必须为 R0~R7
immed_8×4] 偏移量.它是一个无符立即数表达式,其取值为(0~255)×4
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 42 页常用 ARM 指令集及 汇 编 Ver,1.0.12
label 程序相对偏移表达式.label 必须在当 前指令之后 IK 字节范围内,
地址对准—地址必须是 4的整数倍,
PC或 SP相对偏移的 LDR和 STR指令举例如下;
LDR R0,[PC,#0x08] ;读取 PC+0x08地址上的字数据,保存到 R0中
LDR R7,LOCALDAT ;读取 LOCALDAT地址上的字数据,保存到 R7中
LDR R3,[SP,#1020] ;读取 SP+1020地址上的字数据,保存到 R3中
STR R2,[SP] ;存储 R2寄存器的数据到 SP指向的存储单元(偏移量为 0)
? PUSH 和 POP
寄存器入栈及出栈指令.实现低寄存器和可选的 LR 寄存器入栈寄存器和可选的 PC
寄存器出栈操作,堆栈地址由 SP寄存设置,堆栈是满递减堆栈.指令格式如下;
PUSH {reglist[,LR]}
POP {reglist[,PC]}
其中 reglist 入栈/出栈低寄存器列表,即 R0~R7
LR 入栈时的可选寄存器
PC 出栈时的可选寄存器
寄存器入栈及出栈指令举例如下;
PUSH {R0-R7,LR} ;将低寄存器 R0~R7全部入栈,LR 也入栈
POP {R0-R7,PC} ;将堆栈中的数据弹出到低寄存器 R0~R7及 PC中
? LDMIA 和 STMIA
批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据.Thumb 指令集批量加载/存储指令为 LDMIA 和 STMIA,LDMIA 为加载多个寄存器;STM
为存储多个寄存器,允许一条指令传送 8个低寄存器的任何子集.指令格式如下;
LDMIA Rn!,reglist
STMIA Rn!,reglist
其中 Rn 加载/存储的起始地址寄存器.Rn 必须为 R0~R7
Reglist 加载/存储的寄存器列表.寄存器必须为 R0~R7
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 43 页常用 ARM 指令集及 汇 编 Ver,1.0.12
LDMIA/STMIA 的主要用途是数据复制,参数传送等,进行数据传送时,每次传送后地址加 4.若 Rn在寄存器列表中,对于 LDMIA指令,Rn 的最终值是加载的值,而不是增加后的地址;对于 STMIA指令,在 Rn是寄存器列表中的最低数字的寄存器,则 Rn存储的值为
Rn在初值,其它情况不可预知,
批量加载/存储指令举例如下;
LDMIA R0,{R2-R7} ;加载 R0 指 向的地址上的多字数据,保存到 R2~R7 中,R0 的值 更新,
STMIA R1!,{R2-R7};将 R2~R7的数据存储到 R1指向的地址上,R1 值更新,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 44 页常用 ARM 指令集及 汇 编 Ver,1.0.12
Thumb数据处理指令
大多数 Thumb处理指令采用 2地 址格式,数据处理操作比 ARM状态的更少,访问寄存器 R8~R15受到一定限制,
Thumb 数据处理指令
助记符 说明 操作 影响标志
MOV Rd,#expr 数据转送 Rd←expr,Rd 为 R0~R7 影响 N,Z
MOV Rd,Rm 数据转送 Rd←Rm,Rd、Rm 均可为 R0~R15
RdT和R m均 为
R0~R 7 时,影响
N,Z,清零 C,V
MVN Rd,Rm 数据非传送指令 Rd←(~Rm),Rd,Rm 均为 R0~ R7 影响 N,Z
NEG Rd,Rm 数据取负指令 Rd←(-Rm),Rd,Rm 均为 R0~R7 影 响 N,Z,C,V
ADD Rd.Rn,Rm 加法运算指令 Rd←Rn+Rm,Rd,Rn,Rm 均为 R0~R7 影响 N,Z,C,V
ADD Rd.Rn,#expr3 加法运算指令 Rd←Rn+expr#,Rd,Rn 均为 R0~R7 影响 N,Z,C,V
ADD Rd,#expr8 加法运算指令 Rd←Rd+expr8,Rd 为 R0~R7 影响 N,Z,C,V
ADD Rd,Rm 加法运算指令 Rd←Rd+Rm,Rd,Rm 均可为 R0~ R15
Rd和R m均 为R 0~
R7 时,影响
N,Z,C,V
ADD Rd,Rp#expr SP/PC加法运算指令 Rd←SP+expr 或 PC+expr,Rd 为 R0~R7 无
ADD SP,#expr SP加法运算指令 SP←SP+expr 无
SUB Rd,Rn,Rm 减法运算指令 Rd←Rn-Rm,Rd、Rn、Rm 均为 R0~R7 影响 N,Z,C,V
SUB Rd,Rn#expr3 减法运算指令 Rd←Rn-expr3,RdRn 均为 R0~R7 影响 N,Z,C,V
SUB Rd,#expr8 减法运算指令 RD←Rd-expr8,Rd 为 R0~R7 影 响 N,Z,C,V
SUB SP,#expr SP减法运算指令 SP←SP-expr 无
ADC Rd,Rm 带进位加法指令 Rd←Rd+Rm+Carry,Rd、Rm 为 R0~R7 影响 N,Z,C,V
SBC Rd,Rm 带位减法指令 Rd←Rd-Rm-(NOT)Carry,Rd、Rm 为 R0~R7 影响 N,Z,C,V
MUL Rd,Rm 乘法运算指令 Rd←Rd*Rm,Rd、Rm 为 R0~R7 影 响 N,Z,
AND Rd,Rm 逻辑与操作指令 Rd←Rd&Rm,Rd、Rm 为 R0~R7 影 响 N,Z,
ORR Rd,Rm 逻辑或操作指令 Rd←Rd|Rm,Rd、Rm 为 R0~R7 影 响 N,Z,
EOR Rd,Rm 逻辑异或操作指令 Rd←Rd^Rm,Rd、Rm 为 R0~R7 影 响 N,Z,
BIC Rd,Rm 位清除指令 Rd←Rd&(~Rm),Rd、Rm 为 R0~R7 影响 N,Z,
ASR Rd,Rs 算术右移指令 Rd←Rd 算术右移 Rs位,Rd,Rs 为 R0~R7 影响 N,Z,C,
ASR Rd,Rm#expr 算术右移指令 Rd←Rm 算术右移 expr位,Rd,Rm 为 R0~R7 影 响 N,Z,C,
LSL Rd,Rs 逻辑左移指令 Rd←Rd<<Rs,Rd、Rs 为 R0~R7 影 响 N,Z,C,
LSL Rd,Rm,#expr 逻辑左移指令 Rd←Rm<<expr,Rd、Rm 为 R0~ R7 影响 N,Z,C,
LSR Rd,Rs 逻辑右移指令 Rd←Rd>>Rs,Rd、Rs 为 R0~R7 影 响 N,Z,C,
LSR Rd,Rm,#expr 逻辑右移指令 Rd←Rm>>mexpr,Rd、Rm 为 R0~R7 影响 N,Z,C,
ROR Rd,Rs 循环右移指令 Rd←Rm 循环右移 Rs位,Rd、R s为 R0~R7 影响 N,Z,C,
CMP Rn,Rm 比较指令 状态标←Rn-Rm,Rn、Rm 为 R0~R15 影响 N,Z,C,V
CMP Rn,#expr 比较指令 状态标←Rn-expr,Rn 为 R0~R 7 影响 N,Z,C,V
CMN Rn,Rm 负数比较指令] 状态标←Rn+Rm,Rn、Rm 为 R0~R7 影响 N,Z,C,V
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 45 页常用 ARM 指令集及 汇 编 Ver,1.0.12
TST Rn,Rm 位测试指令 状态标←Rn&Rm,Rn、Rm 为 R0~R7 影响 N,Z,C,V
数据传送指令
? MOV
数据传送指令.将 8 位立即数或寄存器(operand2)传送到目标寄存器(Rd).指令格式如下;
MOV Rd,#expr
MOV Rd,Rm
其中 Rd 目标寄存器.MOV Rd#expr 时,必须在 R0~R7 之间
exper 8位立即数,即 0~255
Rm 源寄存器.为 R0~R15
条件码标志,
MOV Rd,#expr指令会更 新N和Z 标志,对标 志C和V 无影响.而 MOV,Rd,Rm指令,若
Rd或 Rm是高寄存器(R8~R15),则标志不受影响,若 Rd或 Rm都是低寄存器(R0~R7),则会更新 N和 Z,且清除标 志C和V,
MOV指令举例如下
MOV R1,#0x10 ;R1=0x10
MOV R0,R8 ;R0=R8
MOV PC,LR ;PC=LR,子程序返回
? MVN
数据非传送指令.将寄存器 Rm按位取反后传送到目标寄存器(Rd).指令格式如下,
MVN Rd,Rm
其中,Rd 目标寄存器.必须在 R0~R7之间
Rm 源寄存器.必须在 R0~R7之间
条件码标志,
指令会更 新N和Z 标志,对标 志C和V 无影响,
MVN指令举例如下
MVN R1,R2 ;将 R2取反结果存到 R1
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 46 页常用 ARM 指令集及 汇 编 Ver,1.0.12
? NEG
数据取负指令.将寄存器 Rm乘以-1 后传送到目标寄存器(Rd).指令格式如下,
NEG Rd,Rm
其中,Rd 目标寄存器.必须在 R0~R7之间
Rm 源寄存器.必须在 R0~R7之间
条件码标志
指令会更新 N,Z,C,V和标志,
NEG指令举例如下
NEG R1,R0,;R1=-R0
算术逻辑运算指令
? ADD
加法运算指令.将两个数据相加,结果保存到 Rd寄存器,
低寄存器的 ADD 指令 的指令格式如下
ADD Rd,Rn,Rm
ADD Rd,Rn,#expr3
ADD Rd,#expr8
其中 Rd 目标寄存器.必须在 R0~R7之间,
Rn 第一个操作数寄存器.必须在 R0~R7之间,
Rm 第二个操作数寄存器.必须在 R0~R7之间,
expr3 3位立即数,即 0~7
expr8 8位立即数,即 0~255,
条件码标志:指令会更新 N、Z,C和 V标志,
高或低寄存器的 ADD 指令 的指令格式如下,
ADD Rd,Rm
其中 Rd 目标寄存器,也是第一个操数寄存器,
Rm 第二个操作数寄存器
条件码标志:若 Rd或 Rm都是低寄存器(R0~R7),指令会更新 N,Z,C和 V标志.其它情况不影响条件码标志,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 47 页常用 ARM 指令集及 汇 编 Ver,1.0.12
PC 或 SP 相 对偏移的 ADD 指 令 指令格式如下,
ADD Rd,Rp,#expr
其中 Rd 目标寄存器.必须在 R0~R7之间
Rp PC或 SP,第一个操作数寄存器,
expr 立即数,在 0~1020范围内,
条件码标志:不影响条件码标志,
SP 操作的 ADD 指 令 的指令格式如下
ADD SP,#expr
ADD SP,SP,#expr
其中 SP 目标寄存器,也是第一个操作数寄存器,
expr 立即数,在-508~+508 之间的 4的整数倍的数
条件码标志:不影响条件码标志,
ADD指令举例如下
ADD R1,R1,R0 ;R1=R1+R0
ADD R1,R1,#7 ;R1=R1+7
ADD R3,#200 ;R3=R3+200
ADD R3,R8 ;R3=R3+R8
ADD R1,SP,#1000 ;R1=SP+1000
ADD SP,SP,#-500 ;SP=SP-500
? SUB
减法运算指令.将两个数相减,结果保存到 Rd中,
低寄存器的 SUB 指令 的指令格式如下;
SUB Rd,Rn,Rm
SUB Rd,Rn,#expr3
SUB Rd,#expr8
其中 Rd 目标寄存器.必须在 R0~R7之间
Rn 第一个操作数寄存器.必须在 R0~R7之间
Rm 第一个操作数寄存器.必须在 R0~R7之间
expr3 3位立即数,即 0~7
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 48 页常用 ARM 指令集及 汇 编 Ver,1.0.12
expr8 8位立即数.即 0~255
条件码标志:指令会更新 N、Z,C和 V标志,
SP 操作的 SUB 指 令 的指令格式如下
SUB SP,#expr
SUB SP,SP,#expr
其中 SP 目标寄存器,也是第一个操作数据寄存器,
expr 立即数,在-508~+508 之间的 4的整数倍的数
条件码标志:不影响条件码标志
SUB指令举例如下
SUB R0,R2,R1,;R0=R2-R1
SUB R2,R1,#1 ;R2=R1-1
SUB R6,#250 ;R6=R6-250
SUB SP,#380 ;SP=SP-380
? ADC
带进位加法指令.将 Rm的值与 Rd的值相加,再加上 CPSR中的 C条 件标志位,结果保存到 Rd寄存器.指令格式如下
ADC Rd,Rm
其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7之间
Rm 第二个操作数寄存器.必须在 R0~R7之间
条件码标志:指令会更新 N、Z,C和 V标志,
ADC指令举例如下;
ADD R0,R0,R2,
ADC R1,R1,R3 ;使用 ADC实现 64位加法,(R1,R0)+(R3,R2)
? SBC
带进位减法指令.用寄存器 Rd减去 Rm,再减去 CPSR中的 C条件标志的非(即若 C标志清零,则结果减去 1),结果保存到 Rd中.指令格式如下
SBC Rd,Rm
其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7之间
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 49 页常用 ARM 指令集及 汇 编 Ver,1.0.12
Rm 第二个操作数寄存器.必须在 R0~R7之间]
条件码标志:指令会更新 N、Z,C和V标 志
SBC指令举例如下
SUB R0,R0,R2
SUB R1,R1,R3 ;使用 SBC实现 64位减法,(R1,R0)=(R1,R0)-(R3,R2)
? MUL
乘法运算指令.用寄存器 Rd乘以 Rm,结果保存到 Rd中.指令格式如下;
MUL Rd,Rm
其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7之间
Rm 第二操作数寄存器.必须在 R0~R7之间
条件码标志:指令会更 新N和Z标 志
MUL 指令举例如下
MUL R2,R0,R1 ;R2=R0*R1
? AND
逻辑与操作指令.将寄存器 Rd 的值与寄存器 Rm 值按位作逻辑与操作,结果保存到
Rd中.指令格式如下
AND Rd,Rm
其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7之间
Rm 第二个操作数寄存器.必须在 R0~R7之间
条件码标志:指令会更 新N和Z标 志
AND 指令举例如下;
MOV R1,#0x0F
AND R0,R1 ;R0=R0 & R1
? ORR
逻辑或操作指令.将寄存器 Rd 与寄存器 Rn 的值按位作逻辑或操作,结果保存到 Rd
中.指令格式如下,
ORR Rd,Rm
其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7之间
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 50 页常用 ARM 指令集及 汇 编 Ver,1.0.12
Rm 第二个操作数寄存器.必须在 R0~R7之间
条件码标志:指令会更 新N和Z 标志
ORR指令举例如下
MOV R1,#0x03
ORR R0,R1 ;R0=R0|R1
? EOR
逻辑异或操作指令.寄存器 Rd的值与寄存器 Rn的值按位作逻辑异或操作,结果保存到 Rd中,指令格式如下;
EOR Rd,Rm
其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7之间
Rm 第二个操作数寄存器.必须在 R0~R7之间
条件码标志:指令会更 新N和Z标 志
EOR指令举例如下
MOV R2,#0Xf0
EOR R3,R2,;R3=R3^R2
? BIC
位清除指令.将寄存器 Rd的值与寄存器 Rm的值反码按位作逻辑与操作.结果保存到
Rd中,指令格式如下
BIC Rd,Rm
其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7之间,
Rm 第二个操作数寄存器.必须在 R0~R7之间
条件码标志:指令会更 新N和Z标 志
BIC指令举例如下,
MOV R1,#0x80
BIC R3,R1 ;将 R1的最高位清零,其它位不变
? ASR
算术右移指令.数据算术右移,将符号位拷贝到空位,移位结果保存到 Rd中,指令格式如下;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 51 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ASR Rd,Rs
ASR Rd,Rm,#expr
其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7之间
Rs 寄存器控制移位中包含移位量的寄存器.必须在 R0~R7之间
Rm 立即数移位的源寄存器.必须在 R0~R7之间
expr 立即数移位量,值为 1~32
条件码标志:指令会更新 N,Z和 C标志(若移位量为零,则不影响 C标志)
ASR指令举例如下
ASR R1,R2,
ASR R3,R1,#2
若移位量为 32,则 Rd 清零,最后移出的位保留在标志 C 中,若移位量大于 32,则 Rd
和标志 C均被清零;若移位量为 0,则不影响 C标志
? LSL
逻辑左移指令.数据逻辑左移,空位清零,移位结果保存到 Rd中,指令格式如下
LSL Rd,Rs
LSL Rd,Rm,#expr
其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7之间
Rs 寄存器控制移位中包含位量的寄存器.必须在 R0~R7之间
Rm 立即数移位的源寄存器.必须在 R0~R7之间
expr 立即数移位量,值为 1~31
条件码标志:指令会更新 N,Z和 C标志(若移位量为零,则不影响 C标志)
LSL指令举例如下
LSL R6,R7
LSL R1,R6,#2
若移位量为 32,则 Rd 清零,最后移出的位保留在标志 C 中;若移位量大于 32,则 Rd
和标志 C均被清零;若移位量为 0,则不影响 C标志
? LSR
逻辑左移指令.数据逻辑左移,空位清零,移位结果保存到 Rd中.指令格式如下
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 52 页常用 ARM 指令集及 汇 编 Ver,1.0.12
LSR Rd,Rs
LSR Rd,Rm,#expr
其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7之间
Rs 寄存器控制移位中包含移位量的寄存器.必须在 R0~R7之间
Rm 立即数移位的源寄存器.必须在 R0~R7之间
expr 立即数移位量,值为 1~32
条件码标志:指令会更新 N,Z和 C标志(若移位量为零,则不影响 C标志)
LSR 指令举例如下
LSR R3,R0
LSR R5,R2,#2
若移位量为 32,则 Rd 清零,最后移出的位保留在标志 C 中;若移位量大于 32,则 Rd
和标志 C均被清零,若移位量为 0,则不影响 C标志,
? ROR
循环右移指令.数据循环右移,寄存器右边移出的位循环移回到左边,移位结果保存到 Rd中,指令格式如下
ROR Rd,Rs
其中 Rd 目标寄存器.也是第一个操作数寄存器.必须在 R0~R7之间
Rs 寄存器控制移位中包含移位量的寄存器.必须在 R0~R7之间
条件标志:指令会更新 N,Z,C的标志(若移位量为零,则不影响 C标志),
ROR 指令举例如下
ROR R2,R3
比较指令
? CMP
比较指令.指令使用寄存器 Rn 的值减去第二个操作数的值,根据操作的结果理新
CPSR中的相应条件标志位.指令格式如下
CMP Rn,Rm
CMP Rn,#expr
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 53 页常用 ARM 指令集及 汇 编 Ver,1.0.12
其中 Rn 第一个操作数寄存器.对 CMP,Rn#expr指令,Rn 在 R0~R7之间;对于
CMP,Rn,Rm指令在 Rn在 R0~R15之间
Rm 第二个操作数寄存器.Rm 在 R0~R15之间
expr 立即数,值为 0~255
条件码标志:指令会更新 N、Z,C和V标 志
CMP指令举例如下
CMP R1,#10 ;R1与 10比较,设置相关标志位
CMP R1,R2 ;R1与 R2比较,设置相关标志位
? CMN
负数比较指令.指令使用寄存器 Rn 的值加上寄存器 Rm 的值,根据操作的结果理新
CPSR中的相应条件标志.位指令格式如下
CMN Rn,Rm
其中 Rn 第一个操作数寄存器,必须在 R0~R7之间
Rm 第二个操作数寄存器.必须在 R0~R7之间
条件码标志:指令会更新 N、Z,C和 V标志,
CMN指令举例如下
CMM R0,R2 ;R0与 R2进行比较
? TST
位测试指令.指令将寄存器 Rn的值与寄存器 Rm的值按位作逻辑与操作.根据操作的结果理新 CPSR相应条件标志位.指令格式如下,
TST Rn,Rm
其中 Rn 第一个操作数寄存器.必须在 R0~R7之间
Rm 第二个操作数寄存器.必须在 R0~R7之间
条件码标志:指令会更新 N、Z,C和V标 志
TST 指令举例如下
MOV R0,#x01
TST R1,R0,;判断 R1的最低位是否为 0
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 54 页常用 ARM 指令集及 汇 编 Ver,1.0.12
Thumb 跳转指令
助记符 说明 操作 条件码位置
B label 跳转指令 PC←label B{cond}
BL label 带链接的跳转指令 LR←PC←4,PC←label 无
BX Rm 带状态切换的跳转指令 PC←label 切换处理器状态 无
? B
跳转指令.跳转到指定的地址执行程序.这是 Thumb 指令集中的惟一的有条件执行指令.指令格式如下
B{cond} label
跳转指令 B举例如下
B WAITB
BEQ LOOP1
若使用 cond则 label必须在当前指令的-252~+256 字节范围内;若指令是无条件的,
则跳转指令 label必须在当前指令的±2K 字节范围内
? BL
带链接的跳转指令.指令先将下一条指令的地址拷贝到 R14(即 LR)链接寄存器中,
然后跳转到指定地址运行程序.指令格式如下,
BL label
带链接的跳转指令 BL举例如下
BL DELAYI
机器级转指令 BL限制在当前指令的±4Mb 的范围内.(必要时,ARM 链接器插入代码以允许更长的转移.)
? BX
带状态切换的跳转指令.跳转到 Rm 指定的地址执行程序.若 Rm 的位[0]为 0,则 Rm
的位于也必须为 0,跳转时自动将 CPSR中的标志 T复 位,即把目标地址的代码解释为 ARM
代码.指令格式
BX Rm
带状态切换的跳转指令 BX举例如下,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 55 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ADR R0,ArmFun
BX R0 ;跳转到 R0指定的地址,并根据 R0的最低位来切换处理器状态,
Thumb 杂项指令
? SWI
软中断指令.SWI 指令用于产生软中断,从而实现在用户模式变换到管理模式.CPSR
保存到管理模式的 SPSR中,执行转移到 SWI向量.在其它模式下也可使用 SWI指令,处理器同样地切换到管理模式,
指令格式如下,
SWI immed_8
其中 immed_8 8 位立即数,值为 0~255之间的整数,
SWI指令举例如下
SWI 1 ;软中断,中断立即数为 0
SWI 0x55 ;软中断,中断立即数为 0x55
使用 SWI指令时,通常使用以下两种方法进行传递参数,SWI 异常中断处理程序可以提供相关的服务,这两种方法均是用户软件协定,SWI 异常中断处理程序要通过读取引起软中断的 SWI指令.以取得 8位立即数,
1.指令中 8位的立即数指定了用户请求的服务类型,参数通过用寄存器传递,
MOV R0,#34 ;设置子功能号为虎作 34
SWI 18 ;调用 18号软中断
2.指令中的 8位立即数被忽略,用户请求的服务类型由寄存器 R0的值决定,参数通过其它的通用寄存器传递,
MOV R0,#18 ;调用 18号软中断
MOV R1,#34 ;设置子功能号为了 4
SWI 0
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 56 页常用 ARM 指令集及 汇 编 Ver,1.0.12
Thumb 伪指令
? ADR
小范围的地址读取伪指令,ADR 指 令将基于 PC 相对偏移的地址值读取到寄存器中.ADR 伪指令格式如下,
ADR register,expr
其中 register 加载的目标寄存器,
expr 地址表达式.偏移量必须是正数并小于 1KB.Expr必须局部定义,
不能被导入,
ADR伪指令举例如下
ADR register,expr
其中 register 加载的目标寄存器。
expr 地址表达式。 偏移量必须是正数并小说于 1KB。 Expr必须局部
定义,不能被导入。
ADR伪指令举例如下,
ADR R0,TxtTab

TxtTab
DCB,ARM7TDMI”,0
? LDR
大范围的地址读取伪指令.LDR 伪指令用于加载 32位的立即数或一个地址值到指定寄存器.在汇编编译源程序时,LDR 伪指令被编译器替换成一条合适的指令.若加载的常数未超出 MOV范围,则使用 MOV或 MVN指令代替 LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的 LDR指令从文字池读出常量.LDR 伪指令格式如下,
LDR register,=expr/label_expr
其中,register 加载的目标寄存器
expr 32位立即数,
label_expr 基于 PC的地址表达式或外部表达式,
LADR伪指令举例如下;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 57 页常用 ARM 指令集及 汇 编 Ver,1.0.12
LDR R0,=0x12345678 ;加载 32位立即数 0x12345678
LDR R0,=DATA_BUF+60 ;加载 DATA_BUF地址+60

LTORG ;声明文字池

从 PC到文字池的偏移量必须是正数小于是 1KB,
与 Thumb指令的 LDR相比,伪指令的 LDR的参数有“=”号,
? NOP
空操作伪指令.NOP 伪指令在汇编时将会将会被代替成 ARM中的空操作,比如可能为
MOV,R8,R8指令等.NOP 伪指令格式如下,
NOP
NOP可用于延进操作
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 58 页常用 ARM 指令集及 汇 编 Ver,1.0.12
伪指令
ARM 汇编程序的由机器指令,伪指令和宏指令组成.伪指令不像机器指令那样在处理器运行期间由机器执行,而是汇编程序对源 程序汇编期间由汇编程序处理.在前面的指令集章节中,我们已经接触了几条常用到的伪指令,如 ADR,ADRL,LDR,NOP等,把它们和指令集一起介绍是因为它们在汇编时会被合适的机器指令代替,实现真正机器指令操作.宏是一段独立的程序代码,它是通过伪指令定义的,在程序中使用宏指令即可调用宏.
当程序被汇编时,汇编程序将对每个调用进行展开,用宏定义取代源程序中的宏指令,
符号定义伪指令
符号定义伪指令用于定义 ARM汇编程序的变量,对变量进行赋值以及定义寄存器名称,该类伪指令如下;
全局变量声明:GBLA,GBLL 和 GBLS
局部变量声明:LCLA,LCLL 和 LCLS
变量赋值,SETA,SETL 和 SETS
为一个通用寄存器列表定义名称:RLIST
为一个协处理器的寄存器定义名称:CN
为一个协处理定义名称,CP
为一个 VFP寄存器定义名称:DN 和 SN
为一个 FPA浮点寄存器定义名称:FN
? GBLA、GBLL、GBLS
全局变量声明伪指令,
GBLA伪指令用于声明一个全局的算术变量,并将其初始化为 0;
GBLL伪指令用于声明一个全局的逻辑变量,并将其初始化为{FALSE};
GBLS伪指令用于声明一个全局的字符串变量,并将其初始化为空字符串“” 。
伪指令格式;
GBLA variable
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 59 页常用 ARM 指令集及 汇 编 Ver,1.0.12
GBLL variable
GBLS variable
其中 variable 定义的全局变量名,在其作用范围内必须惟一.全局变量的作用范围为包含该变量的源程序,
伪指令应用举例如下;
GBLL codedbg ;声明一个全局逻辑变量
codebg SETL {TRUE} ;设置变量为{TRUE}

? LCLA、LCLL、LCLS
局部变量声明伪指令.用于宏定义的体中,
LCLA伪指令用于声明一个局部的算术变量,并将其初始化为 0
LCLL伪指令用于声明一个局部的逻辑变量,并将其初始化为{FALSE}
LCLS伪指令用于声明一个局部的字符串变量,并将其初始化为空字符串“”
伪指令格式;
LCLA variable
LCLL variable
LCLS variable
其中 variable 定义的局部变量名。在其作用范围内必须惟一。局部变量的作用范围为包含该局部变量只能在宏中进行声明及使用。
伪指令应用举例如下;
MACRO ;声明一个宏
SENDDAT $dat ;宏的原型
LCLA bitno ;声明一个局部算术变量

bitno SETA 8 ;设置变量值为 8

MEND
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 60 页常用 ARM 指令集及 汇 编 Ver,1.0.12
? SETA、SETL、SETS
变量赋值伪指令.用于对已定义的全局变量,局部变量赋值,
SETA伪指令用于给一个全局/局部的算术变量赋值,
SETL伪指令用于给一个全局/局部的逻辑变量赋值,
SETS伪指令用于给一个全局/局部的字符串变量赋值,
伪指令格式;
variable_a SETA expr_a
variable_l SETL expr_l
variable_s SETS expr_s
其中 variable_a 算术变量.用 GBLA,LCLA伪指令定义的变量,
expr_a 赋值的常数,
variable_l 逻辑变量.用 GBLL,LCLL伪指令定义的变量,
expr_l 逻辑值,即{TRUE}或{FALSE},
variable_s 字符串变量.用 GBLS,LCLS伪指令定义的变量,
expr_s 赋值的字符串,
伪指令应用举例如下,
GBLS ErrStr

ErrStr SETS,No,semaphone”

? RLIST
RLIST为一个通用寄存器列表定义名称.伪指令格式如下,
name RLIST {reglist}
其中 name 要定义的寄存器列表的名称,
reglist 通用寄存器列表,
伪指令应用举例如下;
LoReg RLIST {R0-R7} ;定义寄存器列表 LoReg
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 61 页常用 ARM 指令集及 汇 编 Ver,1.0.12

STMFD SP!,LoReg ;保存寄存器列表 LoReg

? CN
CN为一个协处理器的寄存器定义名称,
伪指令格式;
name CN expr
其中 name 要定义的协处理器的寄存器名称,
expr 协处理器的寄存器编号,数值范围为 0~15,
伪指令应用举例如下;
MemSet CN l ;将协处理的寄存器 l名称定义为 MemSet
? CP
CP为一个协处理器定义的名称,
伪指令格式;
name CP expr
其中 name 要定义的协处理器名称,
expr 协处理器的编号,数值范围为 0~15,
伪指令应用举例如下;
DivRun CN 5 ;将协处理器 5名称定义为 DivRun
? DN、SN
DN和 SN为 VFP的寄存器的名称定义的伪指令,
DN为一个双精度原 VFP寄存器定义名称,
SN为一个单精度的 VFP寄存器定义名称,
伪指令格式;
name DN expr
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 62 页常用 ARM 指令集及 汇 编 Ver,1.0.12
name SN expr
其中 name 要定义的 VFP寄存器名称,
expr 双精度的 VFP寄存器编号为 0~15,单精度的 VFP寄存器编号为 0~31,
伪指令应用举例如下;
cdn DN 1 ;将 VFP双精度寄存器 1名称定义为 cdn
rex SN 3 ;将 VFP单精度寄存器 3名称定义为 rex
? FN
FN为一个 FPA浮点寄存器定义名称
伪指令格式;
name FN expr
其中 name 要定义的浮点寄存器名称,
expr 浮点寄存器的编号,值为 0~7
伪指令应用举例如下;
ibq FN l ;将浮点寄存器 l名称定义为 ibq
数据定义伪指令
数据定义伪指令用于数据表定义,文字池定义,数据空间分配等.该类伪指令如下;
声明一个文字池:LTORG;
定义一个结构化的内存表的首地址:MAP
定义结构化内存表中的一个数据域:FIELD
分配一块内存空间,并用 0初始化:SPACE
分配一段字节的内存单元,并用指定的数据初始化:DCB;
分配一段字的内存单元,并用指令的数据初始化:DCD 和 DCDU;
分配一段字的内存单元,将每个单元的内容初始化为该单元相对于静态基址寄存器的偏移量:DCDO;
分配一段双字的内存单元,并用双精度的浮点数据初始化:DCFD 和 DCFDU;
分配一段字的内存单元,并用单精度的浮点数据初始化:DCFS 和 DCFSU;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 63 页常用 ARM 指令集及 汇 编 Ver,1.0.12
分配一段字的内存单元,并用单精度的浮点数 据初始化,指定内存单元存放的是代码,而不是数据:DCI
分配一段双字的内存单元,并用 64位整数数据初始化:DCQ 和 DCQU
分配一段半字的内存单元,并用指定的数据初始化:DCW 和 DCWU;
? LTORG
LTORG用于声明一个文字池,在使用 LDR伪指令时,要在适当的地址加入 LTORG声明文字池,这样就会把要加载的数据保存在文字池内,再用 ARM 的加载指令读出数据.(若没有使用 LTORG声明文字池,则汇编器会在程序末尾自动声明.)
伪指令格式,
LTORG
伪指令应用举例如下;

LDR R0,=0x12345678
ADD R1,R1,R0
MOV PC,LR
LTORG ;声明文字池,此地址存储 0x12345678
… ;其它代码
LTORG 伪指令常放在无条件跳转指令之后,或者子程序返回指令之后,这样处理器就不会错误地将文字池中的数据当作指令来执行,
? MAP
MAP 用于定义一个结构化的内存表的首地址.此时,内存表的位置计数器{VAR}设置为该地址值{VAR}为汇编器的内置变量.^与 MAP同义,
伪指令格式,
MAP expr,{base_register}
其中 expr 数字表达式或程序中的标号.当指令中没有
base_register时,expr 即为结构化内存表的首地址,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 64 页常用 ARM 指令集及 汇 编 Ver,1.0.12
base_register 一个寄存器.当指令中包含这一项时,结构化内存表的首地
址为 expr与 base_register寄存器值的和,
伪指令应用举例如下;
MAP 0x00,R9 ;定义内存表的首地址为 R9
Timer FIELD 4 ;定义数据域 Timer,长度为 4字 节
Attrib FIELD 4 ;定义数据域 Attrib,长度为 4字 节
String FIELD 100 ;定义数据域 String,长度为 100字节

ADR R9,DataStart ;设置 R9的值,即设置结构化的内存表地址
LDR R0,Atrrib ;相当于 LDR,R0,[R9,#4]

MAP伪指令和 FIELD伪指令配合使用,用于定义结构化的内存表结构.MAP 伪指令中的 base-register寄存器的值对于其后所有的 FIELD伪指令定义的数据域是默认使用的,
直到遇到新的包含 base-register项的 MAP伪指令,
? FIELD
FIELD用于定义一个结构化内存表中的数据域.#与 FIELD同义,
伪指令格式,
{tabel} FIELD expr
其中 label 当指令中包含这一项时,label 的值为当前内存表的位置计数
器{VAR}的值,汇编编译器处理了这条 FIELD伪指令后,内存表
计数器的值将加上 expr,
expr 表示本数据域在内存表中所占用的字节数,
伪指令应用举例如下;
MAP 0x40003000 ;内存表的首地址为 0x40003000
count1 FIELD 4 ;定义数据域 count1,长度为 4字 节
count2 FIELD 4 ;定义数据域 count2,长度为 4字 节
count3 FIELD 4 ;定义数据域 count3,长度为 4字 节

IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 65 页常用 ARM 指令集及 汇 编 Ver,1.0.12
LDR R1,count1 ;R1=[0x40003000+0x00]
STR R1,count2 ;[0x40003000+0x00]=R1
MAP,FIELD伪指令仅仅是定义数据结构,它们并不实际分配内存单元,
? SPACE
SPACE用于分配一块内存单元,并用 0初始化.%与 SPACE同义,
伪指令格式,
{label} SPACE expr
其中 label 内存块起始地址标号,
expr 所要分配的内存字节数,
伪指令应用举例如下;
AREA DataRA,DATA,READWROTE ;声明一数据段,名为 DataRAM
DataBuf SPACE 1000 ;分配 1000字节空间
? DCB
DCB 用于分配一段字节内存单元,并用伪指令中的 expr 初始化.一般可用来定义数据表格,或文字符串.=与 DCB同义,
伪指令格式,
{label} DCB expr{,expr}{,expr}…
其中 label 内存块起始地址标号,
expr 可以为-128~255 的数值或字符串.内存分 配的字节数由 expr 个数 决定,
伪指令应用举例如下
DISPTAB DCB 0x33,0x43,0x76,0x12
DCB -120,20,36,55
ERRSTR DCB,Send,data is error!”,0
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 66 页常用 ARM 指令集及 汇 编 Ver,1.0.12
? DCD和DCDU
DCD用于分配一段字内存单元,并用伪指令中的 expr初始化.DCD 伪指令分配的内存需要字对齐,一般可用来定义数据表格或其它常数.&与 DCD同义,
DCDU用于分配一段字内存单元,并用伪指令中的 expr初始化.DCD 伪指令分配的内存不需要字对齐,一般可用来定义数据表格或其它常数,
伪指令格式,
{label} DCD expr{,expr}{,expr}…
{label} DCDU expr{,expr}{,expr}…
其中 label 内存块起始地址标号,
expr 常数表达式或程序中的标号.内存分配字节数由 expr个数决定,
伪指令应用举例如下,
Vectors
LDR PC,ReserAddr
LDR PC,UndefinedAddr

ResetAddr DCD Reset
UndefinedAddr DCD Undefined

Reset

Undefined

? DCDO
DCDO 用于分配一段字内存单元.并将每个单元的内容初始化为该单元相对于静态基址寄存器的偏移量,DCDO 伪指令作为基于静态基址寄存器 R9 的偏移量分配内存单元.DCDO 伪指令分配的内存需要字对齐,
伪指令格式;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 67 页常用 ARM 指令集及 汇 编 Ver,1.0.12
{label} DCDO expr{,expr}{,expr}…
其中 label 内存块起始地址标号,
expr 地址偏移表达式或程序中的标号.内存 分配的字数由 expr 个数 决定,
伪指令应用举例如下;
IMPORT externsym
DCDO externsym ;分配 32位的字单元,其值为标号 externsym基于 R9的偏移
? DCFD和DCFDU
DCFD用于分配一段双字的内存单元,并用双精度的浮点数据 fpliteral初始化。 每个双精度的浮点数占据两个字单元。DCFD 伪指令分配的内存需要字对齐。
DCFDU具有 DCFD同样的功能,但分配的内存不需要字对齐。
伪指令格式,
{label} DCFD fpliteral{,fpliteral}{,fpliteral}…
{label} DCFDU fpliteral{,fpliteral}{,fpliteral}…
其中 label 内存块起始地址标号,
fpliteral 双精度的浮点数,
伪指令应用举例如下;
DCFD 2E30,-3E-20
DCFDU -.1,1000,2.1E18
? DCFS和DCFSU
DCFS 用于分配一段字的内存单元,并用单精度的浮点数据 fpliteral 初始化.每个单精度的浮点数占据一个字单元.DCFD 伪指令分配的内存需要字对齐,
DCFSU具有 DCFS同样的功能,但分配的内存不需要字对齐,
伪指令格式,
{label} DCFS fpliteral{,fpliteral}{,fpliteral}…
{label} DCFSU fpliteral{,fpliteral}{,fpliteral}…
其中 label 内存块起始地址标号
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 68 页常用 ARM 指令集及 汇 编 Ver,1.0.12
fpliteral 单精度的浮点数,
伪指令应用举例如下;
DCFS 1.1E2,-1.3E10,0.0999
? DCI
在 ARM代码中,DCI 用于分配一段字节的内存单元,用指定的数据 expr初始化.指定内存单元存放的是代码,而不是数据,
在 Thumb代码中,DCI 用于分配一段半字节的内存单元,用指定的数据 expr初始化.
指定内存单元存放的是代码,而不是数据,
伪指令格式,
{label} DCI expr
其中 label 内存块起始地址标号,
expr 可为数字表达式,
DCI 伪指令和 DCD 伪指令非常类似,不同之处在于 DCI 分配的内存中的数据被标识为指令.可用于通过宏指令业定义处理器不支持的指令,
伪指令应用举例如下;
MACRO ;宏定义(定义 NEWCMN Rd,Rn指令)
NEWCMN $Rd,$Rm ;宏名为 NEWCMN,参数为 Rd和 Rm
DCI 0xe16a0e20:OR:($Rd:SHL:12):OR:$Rm
MEND
? DCQ和DCQU
DCQ用于分配一段双字的内存单元,并用 64位的整数数据 literal初始化.DCQ 伪指令分配的内存需要字对齐,
DCQU具有 DCQ同样的功能,但分配的内存不需要字对齐,
伪指令格式,
{label} DCQ {-}literal{,{-}{literal}}…
{label} DCQU {-}literal{,{-}{literal}}…
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 69 页常用 ARM 指令集及 汇 编 Ver,1.0.12
其中 label 内存块起始地址标号,
literal 64位的数字表达式.取值范围为 0~2
64
-1当literal前有“.”号
时,取值范围为-2
63
~-1 之间
伪指令应用举例如下;
DCQU 1234,-76568798776
? DCW和DCWU
DCW用于分配一段字的内存单元,并用指定的数据 expr初始化.DCW 伪指令分配的内存需要字对齐,
DCWU具有 DCW同样的功能,但分配的内存不需要字对齐,
伪指令格式,
{label} DCW expr{,expr}{,expr}…
{label} DCWU expr{,expr}{,expr}…
其中 label 内存块起始地址标号,
expr 数字表达式,取值范围为-32768~65535,
伪指令应用举例如下;
DCW -592,123,6756
报告伪指令
报告伪指令用于汇编报告指示.该类伪指令如下,
断言错误:ASSERT;
汇编诊断信息显示:INFO;
设置列表选项:OPT;
插入标题:TTL 和 SUBT,
? ASSERT
ASSERT 为断言错误伪指令.在汇编编译器对汇编 程序的第二遍扫描中,如果其中
ASSERT条件不成立,ASSERT 伪指令将报告该错误信息,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 70 页常用 ARM 指令集及 汇 编 Ver,1.0.12
伪指令格式,
ASSERT Logical_expr
其中 Logical_expr 用于断言的逻辑表达式
伪指令应用举例如下
ASSERT Top<>Temp ;断言 Top不等于 Temp
? INFO
汇编诊断信息显示伪指令,在汇编器处理过程中的第一遍扫描或第一遍扫描时报告诊断信息,
伪指令格式,
INFO numeric_expr,string_expr
其中 numeric_expr 数据表达式.若值为 0,则在第一遍扫描时报告诊断信
息.否则在第一遍扫描时报告诊断信息,
strint_expr 要显示的字串
伪指令应用举例如下,
INFO 0,”Version 0.1” ;在第二遍扫描时,报告版本信息
if cont1 > cont2 ;如果 cont1 > cont2
INFO 1,”cont1 > cont2” ;则在第一遍扫描时报告”cont1 > cont2”
? OPT
设置列表选项伪指令.通过 OPT伪指令可以在源程序中设置列表选项,
伪指令格式,
OPI n
其中 n所设置的选项的编码如下,
1 设置常规列表选项
2 关闭常规列表选项
4 设置分页符,在新的一页开始显示
8 将行号重新设置为 0
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 71 页常用 ARM 指令集及 汇 编 Ver,1.0.12
16 设置选项,显示 SET,GBL,LCL伪指令
32 设置选项,不显示 SET,GBL,LCL伪指令
64 设置选项,显示宏展开
128 设置选项,不显示宏展开
256 设置选顶,显示宏调用
512 设置先项,不显示宏调用
1024 设置选顶,显示第一遍扫描列表
2048 设置选项,不显示第一遍扫描列表
4096 设置选项目,显示条件汇编伪指令
8192 设置选项,不显示条件汇编伪指令
16384 设置选项,显示 MEND伪指令
32768 设置选项,不显示 MEND伪
默认情况下,-list 选项生成常规的列表文件,包括变量声明,宏展开,条件汇编伪指令及 MEND伪指令,而且列表文件只是在第二遍扫描时给出,通过 OPT伪指令,可以在源程序中改变默认的选项,
伪指令应用举例如下
… ;代码
OPT 512 ;不显示宏调用
… ;代码
? TTL和SUBT
TTL和 SUBT为插入标题伪指令,
TTL 伪指令在列表文件的每一页的开头插入一个标题.该 TTL 伪指令的作用在其后的每一页,直到遇到新的 TTL伪指令,
SUBT 伪指令在列表文件的每页的开头第一个子标题.该 SUBT 伪指令的作用在其后的每一页,直到遇到新的 SUBT伪指令,
伪指令格式,
TTL title
SUBT subtitle
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 72 页常用 ARM 指令集及 汇 编 Ver,1.0.12
其中 title 标题名,
subtitle 子标题名,
伪指令应用举例如下;

TTL mainc

SUBT subc con

汇编控制伪指令
汇编控制伪指令用于条件汇编,宏定义,重复汇编控制等.该类伪指令如下,
条件汇编控制,IF,ELSE 和 ENDIF
宏定义,MACRO 和 MEND
重复汇编,WHILE 及 WEND
? IF、ELSE和ENDIF
IF,ELSE 和 ENDIF 伪指令能够根据条件把一段代码包括在汇编程序内或将其排除在程序之外,
[与 IF同义,|与 ELSE同义,]与 ENDIF同义
伪指令格式,
IF logical_expr;指令或伪指令代码段 1
ELSE;指令或伪指令代码段 2
}
{
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 73 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ENDIF
其中 logical_expr 用于控制的逻辑表达式.若条件成立,则代码段落在汇编
源程序中有效.若条件不成立,代码段 1无效,同时若使
用 ELSE伪指令,代码段有效,
伪指令应用举例如下;

IF {CONFIG}=16
BNE __rt_udiv_1
LDR R0,=__rt_div0
BX R0
ELSE
BEQ __rt_div0
ENDIF
IF,ELSE和 ENDIF伪指令是可以嵌套使用的,
? MACRO和MEND
MACRO 和 MEND 伪指令用于宏定义.MACRO 标识宏定义的开始,MEND 标识宏定义久的结束.用 MACRO及 MEND定义的一段代码,称为宏定义体.这样在程序中就可以通过宏指令多次调用该代码段,
伪指令格式,
MACRO
{$label} macroname {$parameter} {$parameter}…;宏定义体,
MEND
其中 $label 宏指令被展开时,label 可被替换成相应的符号,通常为一
个标号在一个符号前使用$表示被汇编时将使用相应的值替
代$后的符号,
macroname 所定义的宏的名称,
$parameter 宏指令的参数.当宏指令被展开时将被替换成相应的值,类
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 74 页常用 ARM 指令集及 汇 编 Ver,1.0.12
似于函数中的形式参数
对于子程序代码比较短,而需要传递的参数比 较多的情况下可以使用汇编技术.首先要用 MACR和 MEND伪指令定义宏,包括宏定义体代码.在 MACRO伪指令之后的第一行声明宏的原型,其中包含该宏定义的名称,及需要的参数.在汇编程序中可以通过该宏定义的名称来调用它.当源程序被汇编时,汇编编译器将展开每个宏调用,用宏定义体代替源程序中的宏定义的名称,并用实际的参数值代替宏定义时的形式参数,
伪指令应用举例如下
MACRO
CSI_SETB ;宏名为 CSI_SETB,无参数
LDR R0,=rPDATG ;读取 GPG0口的值
LDR R1,[R0]
ORR R1,R1#0x01 ;CSI置位操作
STR R1,[R0] ;输出控制
MEND
带参数的宏定义如程序清单,
MACRO
$IRQ_Label HANDLER $IRQ_Exception
EXPORT $IRQ_Label
IMPORT $IRQ_Exception
$IRQ_Label
SUB LR,LR,#4
STMFD SP!,{R0-R3,R12,LR}
MRS R3,STSR
STMFD SP!,{R3}

MEND
? WHIL和WEND
WHILE和 WEND伪指令用于根据条件重复汇编相同的或几乎相同的一段源程序,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 75 页常用 ARM 指令集及 汇 编 Ver,1.0.12
伪指令格式,
WHILE logical_expr;指令或伪指令代码段
WEND
其中 logical_expr 用于控制的逻辑表达式.若条件成立,则代码段在汇编
源程序中有效,并不断重复这段代码直到条件不成立,
伪指令应用举例如下;
WHILE no<5
no SETA no+1

WEND
WHILE和 WEND伪指令是可以嵌套使用的,
杂项伪指令
杂项伪指令在汇编编程设计较为常用,如段定义伪指令,入口点设置伪指令,包含文件伪指令,标号导出或引入声明等,该类伪指令如下;
边界对齐,ALIGN
段定义,AREA
指令集定义,CODE16 和 CODE32
汇编结束,END
程序入口,ENTRY
常量定义,EQU
声明一个符号可以被其它文件引用:EXPORT 和 GLORBAL
声明一个外部符号:IMPORT 和 EXTERN
包含文件:GET 和 INCLUDE
包含不被汇编的文件:INCBIN
保留符号表中的局部符号:KEEP
禁止浮点指令:NOFP
指示两段之间的依赖关系:REQUIRE
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 76 页常用 ARM 指令集及 汇 编 Ver,1.0.12
堆栈 8字节对准:PEQUIRE8 和 PRESERVE8
给特定的寄存器命名:RN
标记局部标号使用范围的界限:ROUT,
? ALIGN
ALIGN伪指令通过添加补丁字节使当前位置满足一定的对齐方式,
伪指令格式,
ALIGN {expr{,offset}}
其中 expr 数字表达式,用于指定对齐的方式.取值 为2的n 次幂,如 1,2,4,8,
等,不能为 0其没有 expr.,则默认为字对齐方式,
offset 数字表达式,当前位置对齐到下面形式的地址处:offset+n*expr
在下面的情况中,需要特定的地址对齐方式;
1.Thumb 伪指令 ADR 要求地址是字对齐的.而 Thumb 代码中地址标号可能不是字对齐的.这时就要使用伪指令 ALIGN4使 Thumb代码中地址标号为字对齐,
2.由于有些 ARM处理器的 Cache采用了其他对齐方式.如 16字节对齐方式,这时使用 ALIGN伪指令指定合适的对齐方式可以充分发挥 Cache的性能优势,
3.LDRD 和 STRD 指令要求存储单元为 8 字节对齐.这样在为 LDRD/STRD 指令分配的存储单元前要使用伪指令 ALIGN8实现 8字节对齐方式,
4.地址标号通常自身没有对齐要求,而在 ARM 代码中要求地起标号对齐是字对齐的,Thumb 代码中要求半字对齐.这样可以使用 ALIGN4 和 ALIGN2 伪指令来调整对齐方式,
伪指令应用举例如下,
通过 ALIGN伪指令使程序中的地址标号字对齐,
AREA Example,CODE,READONLY ;声明代码段 Example
START LDR R0,=Sdfjk

MOV PC,LR
Sdfjk DCB 0x58 ;定义一字节存储空间,字对齐方式被破坏
ALIGN ;声明字对齐
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 77 页常用 ARM 指令集及 汇 编 Ver,1.0.12
SUBI MOV R1,R3 ;其它代码

MOV PC,LR
在段定义 AREA中,也可使用 ALIGN伪指令对齐,但表达式的数字含义是同的
AREA MyStack,DATA,NOINIT,ALIGN=2 ;声明数据段;MyStack,并重新字对齐
IrqStackSpace SPACE IRQ_STACK_LEGTH*4 ;中断模式堆栈空间
FiqStackSpace SPACE FIQ_STACK_LEGTH*4 ;快速中断模式堆栈空间
AbtStackSpace SPACE ABT_STACK_LEGTH*4 ;中止义模式堆栈空间
UndtStackSpace SPACE UND_STACK_LEGTH*4 ;未定义模式堆栈

将两个字节的数据放在同一个字的第一个字节和第四个字节中,带 offset的 ALIGN
对齐,
AREA offsetFxample,CODE
DCB 0x31 ;第一个字节保存 0x31
ALIGN 4,3 ;字对齐
DCB 0x32 ;第四个字节保存 0x32

? AREA
AREA 伪指令用于定义一个代码段或数据段.ARM 汇编程序设计采用分段式设计,一个 ARM源程序至少需要一个代码段,大的程序可以包含多少个代码段及数据段,
伪指令格式,
AREA sectionname{,attr}{,attr}…
其中 sectionname 所定义的代码段或数据段的名称.如果该名称是以数据开头
的,则该名称必须用,|” 括起来,如|1_datasec|.还有一些代
码段具有的约定的名称.如|text|表示 C语言编译器产生的
代码段或者与 C语言库相关的代码段,
attr 该代码段或数据段的属性,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 78 页常用 ARM 指令集及 汇 编 Ver,1.0.12
在 AREA伪指令中,各属性之间用逗号隔开.以下为段属性及相关说明,
ALIGN = expr.默认的情况下,ELF 的代码段和数据段是 4 字节对齐的,expr 可以取 0~31 的数值,相应的对齐方为 2expr 字节对齐.如 expr=3 时为字节对齐.对于代码段,expr 不能 为0或1 ;
ASSOC = section.指定与本段相关的 ELF 段.任何时候连接 section 段也必须包括
sectionname段;
DODE 为定义代码段.默认属性为 READONLY;
COMDEF 定义一个通用的段.该段可以包含代 码或者数据.在其它源文件中,同名的
COMDEF段必须相同;
COMMON 定义一个通用的段.该段不包含任何用户代码和数据,连接器将其初始化为此.各源文件中同名的 COMMON段共用同样的内存单元,连接器为其分配合适的尺寸;
DATA 为定义段.默认属性为 READWRITE;
NOINIT 指定本数据段仅仅保留了内存单元,而没有将各初始写入内存单元,或者将内存单元值初始化为 0;
READONLY 指定本段为只读,代码段的默认属性为 READONLY;
READWRITE 指定本段为可读可写.数据段的默认属性为 READWRITE;
使用 AREA伪指令将程序分为多个 ELF格式的段,段名称可以相同,这时同名的段被放在同一个 ELF段中,
伪指令应用举例如下;
AREA Example,CODE,READNOLY ;声明一个代码,名为 Example
? CODE16和CODE32
CODE16伪指令指示汇编编译器后面的指令为 16位的 Thumb指令,
CODE32伪指令指示汇编编译器后面的指令为 32位的 ARM指令,
伪指令格式,
CODE16
CODE32
CODE16 和 CODE32 伪指令只是指示汇编编译器后面的指令的类型,伪指令本身并不进行程序状态的切换.要进行状态切换,可以使用 BX指令操作,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 79 页常用 ARM 指令集及 汇 编 Ver,1.0.12
伪指令应用举例如下;
AREA Example CODE,READONLY
CODE32

使用 CODE16和 CODE32定义 Thumb指令及 ARM指令并用 BX指令进行切换。
CODE16和 CODE32的使用,
AREA ArmThumC,CODE,READONLY
CODE32
ADR R0,ThumbStart+1
BX R0
CODE16
ThumbStart
MOV R0,#10

END
? END
END 伪指令用于指示汇编编译器源文件已结束.每一个汇编源文件均要使用一个
END伪指令,指示本源程序结束
伪指令格式,
END
? ENTRY
ENTRY伪指令用于指定程序的入口点,
伪指令格式,
ENTRY
一个程序(可以包含多个源文件)中至少要有一个 ENTRY,可以有多个 ENTRY.但一个源文件中最多只有一个 ENTRY,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 80 页常用 ARM 指令集及 汇 编 Ver,1.0.12
伪指令应用举例如下,
AREA,Example,CODE,READNOLY
ENTRY
CODE32
START MOV R1,#0x5F

? EQU
EQU 伪指令为数字常量,基于寄存器的值和程序中的标号定义一个名称。*与 EQU
同义。
指令格式,
name EQU expr{,type}
其中 name 要定义的常量的名称,
expr 基于寄存器的地址值,程序中的标号,32 位地址常量或 32位常量,
type 当 expr为 32位 常量时,可用 type指示 expr表示的数据类型.如下
CODE16
CODE32
DATA
EQU伪指令的作用类似于 C语言中的#define.用于为一个常量定义名称,
伪指令应用举例如下;
T_bit EQU 0x20 ;定义常量 T_bit,其值为 0x20
PLLCON EQU 0xE01FC080 ;定义寄存器 PLLCON,地址为 0Xe01F080
ABCD EQU label+8 ;定义 ABCD为 label+8
? EXPORT和GLOBAL
EXPORT声明一个符号可以被其它文件引用.相当于声明了一个全局变量,
GLOBAL与 EXPORT相同
指令格式,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 81 页常用 ARM 指令集及 汇 编 Ver,1.0.12
EXPORT symbol{[WEAK]}
GLOBAL symbol{[WEAK]}
其中 symbol 要声明的符号名称
[WEAK] 声明其它的同名符优先于本符号被引用,
伪指令应用举例如下,
EXPORT InitStack
GLOBAL Vectors
? IMPORT和EXTERN
IMJPORT 伪指令指示编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号,
EXTERN与 IMPORT相同
指令格式,
IMPORT symbol{[WEAK]}
EXTERN symbol{[WEAK]}
其中 symbol 要声明的符号名称,
[WEAK] 指定该选项后,如果 symbol在所有的源程序中都没有被定义,编
译器也不会生任何错误信息,同时编译器也不会到当前没有被
INCLUDE进来库中去查找该标号,
使用 IMPORT 或 EXTERN 声明外部标号时,若连接器在连接处理时不能解释该符号,
而伪指令中没有[WEAK]选项,则连接器会报告错误,若伪指令中有[WEAK]选项,则连接器不会报告错误,而是进行下面的操作,
1.如果该符号被 B或 者 BL指令引用,则该符号被设置成下一条指令的地址,该 B或者 BL指令相当于一条 NOP指令,
2.其它情况下该符号被设置 0
伪指令应用举例如下
IMPORT InitStack
EXTERN Vectors
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 82 页常用 ARM 指令集及 汇 编 Ver,1.0.12
? GET和INCLUDE
GET 伪指令将一个源文件包含到当前源文件中,并将被包含的文件在具当前位置进行汇编处理 INCLUDE与 GFT同义
指令格式
GET filename
INCLUDE filename
其中 filename 要包含的源文件名,可以使用路径信息,
GET伪指令通常用于包含一些宏定义或常量定义的源文件.如用 EQU定义的常量,用
MAP 和 FIELD 定义的结构化的数据类型,这样的源文件类似于 C 语言中的头文件,GET,INCLUDE 伪指令不能用来包含目标文件,而 INCBIN伪指令可以包含目标文件,
伪指令应用举例如下
INCLUDE LPC2106.inc
? INCBIN
INCBIN伪指令将一个文件包含到当前源文件中,而被包含的文件不进行汇编处理,
指令格式,
INCBIN filename
其中 filename 要包含的源文件名,可以使用路径信息,
通常可以使用 INCBIN 将一个执行文件或者任意数据包含到当前文件中,被包含的执行文件或数据将被原封不动地放下当前文件中,编译器从 INCBIN 伪指令后面开始继续处理,
伪指令应用举例如下
INCBIN charlib.bin
? KEEP
KEEP伪指令指示编译器保留符号表中的局部符号,
伪指令格式
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 83 页常用 ARM 指令集及 汇 编 Ver,1.0.12
KEEP {symbol}
其中 s ymbol 要保留的局部标号.若没有 此项,则除了基于寄存器处的所有符号将包含在目标文件的符号表中,
? NOFP
NOFP伪指令用于禁止源程序中包含浮点运算指令,
伪指令格式,
NOFP
? REQUIRE
REQUIRE伪指令指定段之间的依赖关系,
伪指令格式
REQUIRE label
其中 label 所需要的标号的名称,
当进行链接处理时,包含了 REQUIRE label伪指令的源文件,则定义 label的源文件也被包含,
? PEQUIRE8和PRESERVE8
PEQUIRE8伪指令指示当前文件请求堆栈为 8字节对齐,
PRESERVE8伪指令指示当前文件保持堆栈为 8字节对齐,
伪指令格式,
PEQUIRE8
PRESERVE8
链接器保证要求 8字节对齐的堆栈只能被堆栈为 8字的对齐的代码调用,
? RN
RN伪指令用于给一个特殊的寄存器命名,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 84 页常用 ARM 指令集及 汇 编 Ver,1.0.12
伪指令格式
name RN expr
其中 name 给寄存器定义的名称,
expr 寄存器编号
伪指令应用举例如下
COUNT RN 6 ;定义寄存器 R6为 COUT
Count1 RN R7 ;定义寄存器 R7为 Cout1
? ROUT
ROUT伪指令用于定义局部标号的有效范围,
伪指令格式如下,
{name} ROUT
其中 name 所定义的作用范围的名称,
当没有使用 ROUT伪指令时,局部标号的作用范围为其所在段.ROUT 伪指令的作用范围在本 ROUT伪指令和下一个 ROUT伪指令之间(指同一段中的 ROUT伪指令.)
伪指令应用举例如下,
routineA ROUT ;定义局部标号的有效范围,名称为 routineA

3routineA ;routineA范围内的局部标号 3

BEQ %4routineA ;若条件成立,跳转到 routineA范围内的局部标号 4

BEG %3 ;若条件成立,跳转到 routineA范围内的局部标号 3

4routineA … ;routineA范围内的局部标号 4

otherstuff ROUT ;定义新的局部标号的有效范围
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 85 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM 伪指令
ARM伪指令有 ADR,ADRL,LDR,NOP,LDFD,LDFS,
? ADR
为小范围的地址读取伪指令.ADR 指令将基于 PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,当地址值是非字对齐时,取值范围-255~255 字节之间,
当地址值是字对齐时,取值范围-1020~1020 字节之间
? ADRL
为中等范围的地址读取伪指令.ADRL 指令将基于 PC 相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,当地址值是非字对齐时,取值范围-64K~64K 字节之间,当地址值是字对齐时,取值范围-256K~256K 字节之间
? LDR
为大范围的地址读取伪指令.LDR 伪指令用于加载 32位的立即数或一个地址值到指定寄存器.若汇编器将常量放入文字池,并使用一条程序相对偏移的 LDR 指令从文字池读出常量,则从 PC到文字池的偏移量必须小于 4KB,
? NOP
为空操作伪指令.NOP 伪指令在汇编时将会被代替成 ARM 中的空操作,比如可能为
MOV R0,R0指令等,
? LDFD
伪指令将一个双精度浮点数常数放进一个浮点数寄存器,
伪指令格式,
LDFD fx,=expr
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 86 页常用 ARM 指令集及 汇 编 Ver,1.0.12
其中 fx 浮点数寄存器
expr 双精度浮点数值,
伪指令应用举例如下
LDFD f1,=0.12
? LDFS
伪指令将一个单精度浮点数常数放进一个浮点寄存器,
伪指令格式,
LDFS fx,=expr
其中 fx 浮点数寄存器
expr 单精度浮点数值,
伪指令应用举例如下
LDFS f1,=O.12
Thumb 伪指令
Thumb伪指令有 ADR,LDR,NOP,
? ADR
为小范围的地址读取伪指令.ADR 指令将基于 PC相对偏移的地址值读取到寄存器中,
偏移量必须是正数并小于 1KB,
? LDR
为大范围的地址读取伪指令.LDR 伪指令用于加载 32位的立即数或一个地址值到指定寄存器,
若汇编器将常量放入文字池,并使用一条程序相对偏移的 LDR指令从文字池读出常量,则从 PC到文字池的偏移量必须是正数并小于 1KB
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 87 页常用 ARM 指令集及 汇 编 Ver,1.0.12
? NOP
为空操作伪指令.NOP 伪指令在汇编时将会被代替成 ARM 中的空操作,比如可能为
MOV R8,R8指令等,
ARM汇编程序设计
文件格式
ARM 源程序文件(即源文件)为文件格式,可 以使用任一文本编辑器编写程序代码.
一般地,ARM 源程序文件名的后缀名如下表,
程序 文件名汇编 *.S
引入文件 *.INC
C程序 *.C
头文件 *.H
在一个项目中,至少要有一个汇编源文件或 C 程序文件,可以有多个汇编源文件或多个 C程序文件,或者 C程序文件和汇编文件两者的组合,
ARM 汇编的一些规范
汇编语句格式
ARM汇编中,所有标号必须在一行的顶格书写,其后面不要添加,:,,而所有指令均不能顶格书写。 ARM汇编器对标识符大小写敏感,书写标号及指令时字母大小写要一致,
在 ARM汇编程序中,一个 ARM指令,伪指令,寄存器名可以全部为大写字母,也可以全部为小写字母,但不要大小写混合使用。注释使用“;,,注释内容由“;,开始到此行结束,注释可以在一行的顶格书写。
格式,[标号] <指令|条件| S> <操作数>[;注释]
源程序中允许有空行,适当地插入空行可以提高源代码的可读性。如果单行太长,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 88 页常用 ARM 指令集及 汇 编 Ver,1.0.12
可以使用字符“\”将其分行,“\”后不能有任何字符,包括空格和制表符等。对于变量的设置,常量的定义,其标识符必须在一行的顶格书写。
汇编指令正确的例子和错误的例子如下,
正确的例子,

Str1 SETS My string1.” ;设置字符串变量 Str1
Count RN R0 ;定义寄存器名 Count
USR_STACK EQU 64 ;定义常量
START LDR R0,=0x1123456 ;R0=0x123456H
MOV R1,#0
LOOP
MOV R2,#3

错误的例子,
START MOV R0,#1 ;标号 START没有顶格写
ABC,MOV R1,#2 ;标号后不能带,
MOV R2,#3 ;命令不允许顶格书写
loop Mov R2,#3 ;指令中大小写混合
B Loop ;无法跳转到 Loop标号
标号
在 ARM汇编中,标号代表一个地址,段内标号的地址在汇编时确定,而段外标号的地址值在连接时确定。根据标号的生成方式,可以有以下 3钟,
? 基于 PC 的标号
基于 PC的标号时位于目标指令前的标号或程序中的数据定义伪指令前的标号,这种标号在汇编时将被处理成 PC值加上或减去一个数字常量。它常用于表示跳转指令的
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 89 页常用 ARM 指令集及 汇 编 Ver,1.0.12
目标地址,或者代码段中所嵌入的少量数据。
? 基于寄存器的标号
基于寄存器的标号通常用 MAP和 FILED伪指令定义,也可以用于 EQU伪指令定义,
这种标号在汇编时被处理成寄存器的值加上或减去一个数字常量。 它常用于访问位于数据段中的数据。
? 绝对地址
绝对地址是一个 32为的数字量,它可以寻址的范围为 0~2
32
-1,可以直接寻址整个内存空间。
局部标号
局部标号主要用于局部范围代码中,在宏定义也是很有用的。 局部标号是一个 0~
99 之间的十进制数字,可重复定义,局部标号后面可以紧接一个通常表示该局部变量作用范围的符号。局部变量的作用范围为当前段,也可以用伪指令 ROUT来定义局部标号的作用范围。
局部标号定义格式,N{routname}
其中:N 局部标号,为 0~99
routname 局部标号作用范围的名称,由 ROUT伪指令定义
局部标号引用格式,
%{F|B}{A|T} N{routname}
其中,% 表示局部标号引用操作
F 指示编译器只向前搜索
B 指示编译器只向后搜索
A 指示编译器搜索宏的所有嵌套层次
T 指示编译器搜索宏的当前层
如 果F和B 都没有指定,则编译器先向前搜索,再向后搜索。 如 果A和T 都没有指定,编译器搜索所有从宏的当前层次到宏的最高层次,比当前层次的层次不再搜索。
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 90 页常用 ARM 指令集及 汇 编 Ver,1.0.12
如果指定了 routname,编译器向前搜索最近的 ROUT伪指令,若 routname与该 ROUT
伪指令定义的名称不匹配,编译器报告错误,汇编失败。
示例如下,
routintA ROUT

3routineA
BEQ %4routineA
BGE %3
4routineA

otherstuff ROUT

符号
在 ARM汇编中,符号可以代表地址,变量,数字常量。 当符号代表地址时又称为标号,符号就是变量的变量名、数字常量的名称、标号,符号的命名规则如下,
1、符号由大小写字母、数字以及下划线组成;
2、除局部标号以数字开头外,其它的符号不能以数字开头;
3、符号区分大小写,且所有字符都是有意义的;
4、符号在其作用域范围你必须是唯一的;
5、符号不能与系统内部或系统预定义的符号同名;
6、符号不要与指令助记符、伪指令同名。
常量
? 数字常数
数字常量有三种表示方式,
十进制数,如:12,5,876,0;
十六进制数,如 0x4387,0xFF0,0x1;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 91 页常用 ARM 指令集及 汇 编 Ver,1.0.12
n进制数,用 n-XXX表示,其中 n为 2~9,XXX为具体的数。 如 2-010111,8-4363156
等。
? 字符常量
字符常量由一对单引号及中间字符串表示,标准 C语言中的转义符也可使用。 如果需要包含双引号或“$”,必须使用“”和$$代替。如下,
Hello SETS,Hello World!,
Errorl SETS,The parameter,,VFH””error$$2”
? 布尔常量
布尔常量的逻辑真为{TRUE},逻辑假为{FALSE}.如下,
testno SETS {FALSE}
段定义
ARM汇编程序设计采用分段式设计,一个 ARM源程序至少需要一个代码段,大的程序可以包含多个代码段及数据段,
ARM 汇编程序经过汇编处理后生成一个可执行的映象文件,该文件通常包含下面 3
部分内容,
z 一个或多代码段.代码段通常是只读的,
z 零个或多个包含初始化值的数据段.这些数据段通常是可读写的,
零个或多个不包含初始值的数据段.这些数据被初始化为 0,通常中可读写的,
连接器根据一定的规则将各个段安排到内存中的相应位置.源程序中段之间的相邻关系与执行的映象文件中段之间的相邻关系并不一定相同,
代码段的例子如下,
AREA Hello,CODE,READONLY ;声明代码段 Hello
ENTRY ;程序入口(调试用)
START MOV R7,#10
MOV R6,#5
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 92 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ADD R6,R6,R7 ;R6=R6+R7
B ;死循环
END
每一个汇编文件都要以 END结束,包括*INC 文件,否则编译会有警告,
数据段的例子如下,
AREA DataArea,DATA,NOINIT,ALLGN=2
DISPBUF SPACE 100
RCVBUF SPACE 100

宏定义及其作用
使用宏定义可以提高程序的可读性,简化程序代码和同步修改.ARM 宏定义与标准 C
的#define 相似,只在源程序中进行字符代换.宏定义从 MACRO伪指令开始,到 MEND结束,
并可以使用参数,
宏要先定义,然后再使用.使用时直接书写宏名,并根据对应的宏定义格式设置输入参数或书写标号等.当源程序被汇编时,汇编编译器将展开每一个宏调用,用宏定义体代替程序中的宏调用,并使用实际的参数值代替宏定义时的形式参数,
程序程序清单见后,程序中定义了一个宏 CALL,用于调用子程序,调用时设置所要调 用 的 子 程 序 名 $Function 及 两 个 入 口 参 数 $dat1 和 $dat2.由 于 宏 定 义 体 中 使 用 的 是
MOV指令,所以$dat1 参数只能为 8位图的立即数或通用寄存器,
宏应用的例子,

MACRO ;宏定义
CALL $Function,$dat1,$dat2 ;宏名称为 CALL,带 3个参数
IMPORT $Function ;声明外部子程序
MOV R0,$dat1 ;设置子程序参数,R0=$dat1
MOV R1,$dat2
BL Function ;调用子程序
MEND ;宏定义结束
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 93 页常用 ARM 指令集及 汇 编 Ver,1.0.12

CALL FADD1,#3,#2 ;宏调用

汇编预处理后,宏调用将被展开,程序清单如下,

IMPORT FADD1
MOV R0,#3
MOV R1,#3
BL FADD1

子程序的调用
使用 BL指令进行调用,该指令会把返回的 PC值保存在 LR,示例如下,

BL DLEAY

DELAY …
MOV PC,LR
当子程序执行完毕后,使用 MOV,B/BX,STMFD等指令返回,当然 STMFD要与 LDMFD配套使用,子程序返回的方法,
MOV PC,LR
或 B LR
或 BX LR
或 STMFD SP!{R0-R7,PC }
ARM7TDMI(-S)是没有 BLX指令的,但是可以通过几条程序实现其功能,模拟 BLX指令如下,
ADR R1,DELAY+1
MOV LR,PC ;保存返回地址到 LR
BX R1 ;跳转并切换指令集
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 94 页常用 ARM 指令集及 汇 编 Ver,1.0.12

数据比较跳转
汇编程序可以使用 CMP指令进行两个数据比较,然后调高相应的 ARM条件码,实现跳转.代码例子如下,
CMP R5,#10
BEQ DOEQUAL ;若 R5为 10,则跳转到 DOEQUAL

CMP R1,R2
ADDHI R1,R1,#10 ;若 R1>R2,则 R1=R1+10
ADDLS R1,R1,#5 ;若 R1<=R2,则 R1=R1+5

ANDS R1,R1,#0x80 ;R1=R1&0x80,并设置相应标志位
BNE WAIT ;若 R1的 d7位为则跳转到 WAIT
循环
下面的代码为循环程序的例子.例子指定循环次数,每循环一次进行减 1操作,并判断结果是否为 0,若为 0则退出循环,
MOV R1,#10
LOOP … ;循环体
SUBS R1,R1,#1
BNE LOOP

数据块复制
程序可以使用存储器访问指令 LDM/STM 指 令 进行读取和存储,数据块复制示例如下,
LDR R0,=DATA_DST ;指向数据目标地址
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 95 页常用 ARM 指令集及 汇 编 Ver,1.0.12
LDR R1,=DATA_SRC ;指向数据源地址
MOV R10,#10 ;复制数据个数为 10*N个字
LOOP LDMIA R1!,{R2-R9} ;N为 LDM/STM指令操作数据个数
STMIA R0!,{R2-R9}
SUBS R10,R10,#1
BNE LOOP

栈操作
ARM 使用存储器访问指令 LDM/STM 实现栈操作,用于子程序寄存器保存.注意,使用堆栈时,要先分配好堆栈空间,设置好寄存器 R13(即堆栈指针 SP),否则操作失败,
OUTDAT
STMFD SP!{R0-R7,LR}

BL DELAY

LDMFD SP!{R0-R7,PC}
特殊寄存器定义及应用
基于 ARM 核的芯片一般有片内外设,它们通过其特殊寄存器访问.片内外设的使用示例如下,
WDTC EQU 0xE000000 ;寄存器定义

LDR R0,=WDTC
MOV R1,#0x12
STR R1,[R0] ;WDTC=0x12
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 96 页常用 ARM 指令集及 汇 编 Ver,1.0.12
散转功能
散转是汇编程序常用的一种算法,其示例如下,
CMP R0,#MAXINDEX ;判断索引号是否超出最大索引值
ADDLO PC,PC,R0,LSL #2 ;若没有超出,则跳转到相应位置
B ERROR ;若已经超出,则进行出错处理;散转表,对应索引号为 0~N
B FUN1
B FUN2
B FUN3

查表操作
查表操作是汇编程序常用的一种操作,其示例如下,

LDR R3,=DISP_TAB ;取得表头
LDR R2,[R3,R5,LSL #2] ;根据 R5的值查表,取出相应的值
…;下表为 0--F的字模
DISR_TAB DCD 0xC0,0xF9,0xA4,0x99,0x92
DCD 0x82,0xF8,0x80,0x90,0x88,0x83
DCD 0xC6,0xa1,0x86,0x8E,0xFF
长跳转
ARM的 B 和 BL指令不能全空间跳转,但通过对 PC进行赋值,实现 32位地址的跳转/
调用,示例如下,
ADD LR,PC,#4 ;保存返回地址,即 RET_FUN
LDR PC,[PC,#-4] ;跳转到 LADR_FUN
DCD LADR_FUN
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 97 页常用 ARM 指令集及 汇 编 Ver,1.0.12
RET_FUN …
也可使用伪指令 LDR PC,=LADR_FUN实现长跳转。
对信号量的支持
ARM 提供一条内存与寄存器交换的指令 SWP 用于支持信号量的操作,实现系统任务之间的同步或互斥,其使用的例子如下,
DISP_SEM EQU 0x40002A00

DISP_WAIT MOV R1,#0
LDR R0,=DISP_SEM
SWP R1,R1[R0] ;取出信号量,并设置其为 0
CMP R1,#0 ;判断是否有信号
BEQ DISP_WAIT ;若没有信号,则等待

伪指令使用
LDR伪指令和 NOP伪指令应用例子代码如下,
LDR R1,=0x12345678 ;加载 32位立即数
LDR R0,=LDE_TAB ;加载标号地址
NOP ;空指令
B ;死循环
一个完整的例子
下面是汇编程序完整的例子,
ABC EQU 0x12;声明一个代码段 Example
AREA Example,CODE,READONLY
ENIRY
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 98 页常用 ARM 指令集及 汇 编 Ver,1.0.12
CODE32
ADR R0,Thumb_START+1 ;装载地址,并设置 d0位为 1
BX R0 ;切换到 Thumb状态
CODE16 ;声明 16位代码(Thumb)
Thumb_START
MOV R1,#ABC
ADD R1,R1,#0x10
B Thumb_START
END
外围部件控制
在 32位 的 ARM核芯片中,其外围部件的控制寄存器中,一般会设置,置位/复位”寄存器,这样可以方便的实现位操作,而不会影响其它位,如 IOSET=0x01只会将 P0.1的置位,而其它 I/O 状态不变,另外,ARM 存储/保存指令具有前偏移功能,所以对外围部件的控制寄存器进行操作时可使用此功能,避免了每次都加载寄存器地址的操作示例如下,
LDR R0,=GPIO_BASE
MOV R1,#0x00
STR R1,[R0,#0x04] ;IOSET=0x00
MOV R1,#0x10
STR R1,[R0,#0x0C] ;IOCLR=0x101
三级流水线介绍
ARM7TDM(-S)使用三级流水线执行指令,第一阶段从内存中取回的指令,第二阶段开始解码,而第三阶段实际执行指令.故此,程序计数器总是超出当前执行的指令两条指令.(在为跳转指令计算偏移量时必须计算在内).因为有这个流水线,在跳转时丢失 2个指令周期(因为要重新添满流水线).所以最好利用条件执行指令来避免浪费周期,
条件跳转示例,

IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 99 页常用 ARM 指令集及 汇 编 Ver,1.0.12
CMP R0,#0
BEQ LOOP1
MOV R1,#0x10
MOV R2,#0x88
LOOP1

可以写为更有效的,

CMP R0,#0
MOVNE R1,#0x10
MOVNE R2,#0x88

C与汇编混合编程
在需要 C 与汇编混合编程时,若汇编代码较结,则可使用直接内嵌汇编的方法混合编程;否则,可以将汇编文件以文件的形式加入项目中,通过 ATPCS规定与 C程序相互调用及访问,
ATPCS,即 ARM,Thumb 过程调用标准(ARM/Thumb Procedure Call Standard),它规定了一些子程序间调用的基本规则,如子程序调 用过程中的寄存器的使用规则,堆栈的使用规则,参数的传递规则等,
内嵌汇编
在 C 程序嵌入汇编程序,可以实现一些高级语言没有的功能,提高程序执行效率.armcc 编译器的内嵌汇编器支持,ARM 指令集,tcc 编译器的内嵌汇编支持 Thumb指令集,
内嵌汇编的语法,
__asm
{
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 100 页常用 ARM 指令集及 汇 编 Ver,1.0.12
指令[;指令] /*注释*/

[指令]
}
嵌入汇编程序的例子如下所示,其中 enable_IRQ 函数为使能 IRQ 中断,而
disable_IRQ函数为关闭 IRQ中断,
使能/禁能 IRQ中断,
__inline void enable_IRQ(void)
{
int tmp
_asm //嵌入汇编代码
{
MRS tmp,CPSR //读取 CPSR的值
BIC tmp,tmp,#0x80 //将 IRQ中断禁止位 I清零,即允许 IRQ中断
MSR
CPSR_c,tmp //设置 CPSR的值
}
}
__inline void disable_IRQ(void)
{
int tmp;
_asm
{
MRS tmp,CPSR
ORR tmp,tmp,#0x80
MSR CPSR_c,tmp
}
}
另外一个嵌入汇编程序的例子如下所示,其中 my_strcpy 函数是字符串复制 函
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 101 页常用 ARM 指令集及 汇 编 Ver,1.0.12
数,src 为源字符串指针,dst 为目标字符串指针。
制操作全部由嵌入的汇编代码实现.在主程序中,可以使用 my_strcpy(a,b)来调用函数,还可以使用嵌入汇编方法进行调用,嵌入汇编的代码先要设置入口参数 R0,R1,然后使用 BL my_strcpy,{R0,R1}指令调用函数,其中,输入寄存器列表为{R0,R1},没有输出寄存器列表,
字符串复制,
#include <stdio.h>
void my_strcpy(const char*src,char*dst)
{
int ch;
_asm
{
loop,
#ifndef_thumb
//ARM指令版本
LDRB ch,[src],#1
STRB ch,[dst],#1
#else
//Thumb指令版本
LDRB ch,[src]
ADD src,#1
STRB ch,[dst]
ADD dst,#1
#endif
CMP ch,#0
BNE loop
}
}
int main(void)
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 102 页常用 ARM 指令集及 汇 编 Ver,1.0.12
{
const char*a=“Hello world!,
char b[20]
//my_strcpy(a,b);
_asm
{
MOV R0,a //设置入口参数
MOV R1,b
BL my_strcpy,{R0,R1} //调用 my_strcpy()函数
}
printf(“Original string:’%s’\n,”a); //显示 my_strcpy()函数字符串复制结果
printf(“Copied string:’%s’\n,”b);
return(0);
}
内嵌汇编的指令用法
操作数.内嵌的汇编指令中作为操作数的寄存 器和常量可以是表达式.这些表达式可以是 char,short或 int类型,而且这些表达式都是作为无符号数进行操作.若需要带符号数,用户需要自己处理与符号有关的操作.编译器将会计算这些表达式的值,并为其分配寄存器,
物理寄存器,内嵌汇编中使用物理寄存器有以下限制;
z 不能直接向 PC寄存器赋值,程序跳转只能使 用B或B L指令实现
z 使用物理寄存器的指令中,不要使用过于复杂的 C表达式.因为表达式过于复杂时,将会需要较多的物理寄存器.这些寄 存器可能与指令中的物理寄存器使用冲突,
z 编译器可能会使用 R12 或 R13 存放编译的中间结果,在计算表达式的值时可能会将寄存器 R0~R3,R12和 R14用于子程序调用.因此在内嵌的汇编指令中,不要将这些寄存器同时指定为指令中的物理寄存器,
z 通常内嵌的汇编指令中不要指定物理寄存 器,因为这可能会影响编译器分配寄
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 103 页常用 ARM 指令集及 汇 编 Ver,1.0.12
存器,进而影响代码的效率,
常量,在内嵌汇编指令中,常量前面的”#”可以省略,
指令展开,内嵌汇编指令中,如果包含常量操作 数,该指令有可能被内嵌汇编器展开成几条指令,
标号,C程序中的标号可以被内嵌的汇编指令使用,但是只有指令 B可以使用 C程 序中的标号,而指令 BL则不能使用,
内存单元的分配,所有的内存分配均由 C 编 译器完成,分配的内存单元通过变量供内嵌汇编器使用.内嵌汇编器不支持内嵌汇编程序中用于内存分配的伪指令,
SWI和B L指 令,在内嵌的 SWI 和 BL 指令中,除了正常的操作数域外,还必须增加以下 3个可选的寄存器列表,
z 第 1个寄存器列表中的寄存器用于输入的参数,
z 第 2个寄存器列表中的寄存器用于存储返回的结果
z 第 3 个寄存器列表中的寄存器的内容可能被被调用的子程序破坏,即这些寄存器是供被调用的子程序作为工作寄存器
内嵌汇编器与armasm汇编器的差异
内嵌汇编器不支持通过“.”指示符或 PC获取当前指令地址;不支持 LDR Rn,=expr
伪指令,而使用 MOV Rn,expr 指令向寄存器赋值;不支持标号表达式;不支持 ADR 和
ADRL伪指令;不支持 BX指令;不能向 PC赋值,
使用 0x前缀代替”&”,表示十六进制数.使用 8位移位常数导致 CPSR的标志更新时,N、Z,C和 V标志中的 C不具有真实意义,
内嵌汇编注意事项
9 必须小心使用物理寄存器,如 R0~R3,IP,LR和 CPSR中的 N,Z,C,V标志位.因为计算汇编代码中的 C 表达式时,可能会使用这些物理寄存器,并会修改 N,Z,C,V
标志位.如,
__asm
{ MOV R0,x
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 104 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ADD y,R0,x/y //计算 x/y时 R0会被修改
}
在计算 x/y 时 R0 会 被修改,从而影响 R0+x/y 的结果.用一个 C 程 序的变量代替 R0
就可以解决这个问题,
__asm
{
MOV var,x
ADD y,var,x/y
}
内嵌汇编器探测到隐含的寄存器冲突就会报错,
9 不要使用寄存器代替变量.尽管有时寄存 器明显对应某个变量,但也不能直接使用寄存器代替变量,
int bad_f(int x) //x存放在 R0中
{
__asm
{
ADD R0,R0,#1 //发生寄存器冲突,实际上 x的值没有变化
}
return(x);
}
尽管根据编译器的编译规则似乎可以确定 R0对应 x,但这样的代码会使内嵌汇编器认为发生了寄存器冲突.用其他寄存器代替 R0 存放参数 x,使得该函数将 x 原封不动地返回,
这段代码的正确写法如下,
int bad_f(intx)
{ __asm
{
ADD x,x,#1
}
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 105 页常用 ARM 指令集及 汇 编 Ver,1.0.12
return(x)
}
9 使用内嵌式汇编无需保存和恢复寄存器.事实上,除了 CPSR和 SPSR寄存器,
对物理寄存器先读后写都会引起汇编器报错.例如.,
int f(int x)
{ __asm
{
STMFD SP!{R0} //保存 R0.先读后写,汇编出错
ADD R0,x,1
EOR x,R0,x
LDMFD SP!,{R0}
}
returnt(x),
}
LDM 和 STM 指令的寄存器列表中只允许使用物理寄存器.内嵌汇编可以修改处理器模式,协处理器模式和 FP,SL,SB等 APCS寄存器.但是编译器在编译时并不了解这些变化,
所以必须保证在执行 C代码前恢复相应被修改的处理器模式,
9 汇编语言中的”.”号作为操作数分隔符号.如果有 C表达式作为操作数,若表达式包含有,.” 必须使用,(” 号和,)” 号将其归纳为一个汇编操作数。 例如,
_asm
{
ADD x,y,(f(),z) //“f(),z”为一个带有“.”的 C表达式
}
访问全局变量
使用 IMPORT伪指令引入全局变量,并利用 LDR和 STR指令根据全局变量的地址访问它们,对于不同类型的变量,需要采用不同选项的 LDR和 STR指令,
unsigned char LDRB/STRB
unsigned short LDRH/STRH
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 106 页常用 ARM 指令集及 汇 编 Ver,1.0.12
unsingned int LDR/STR
char LDRSB/STRSB
short LDRSH/STRSH
对于结构,如果知道各个数据项的偏移量,可 以通过存储/加载指令访问.如果结构所占空间小于 8个字,可以使用 LDM和 STM一次性读写,
下面例子是一个汇编代码的函数,它读取全局变量 globval,将其加 1后写回,
访问 C程序的全局变量,
AREA globats,CODE,READONLY]
EXPORT asmsubroutime
IMPORt glovbvar ;声明外部变量 glovbvar
asmsubroutime
LDR R1,=glovbvar ;装载变量地址
LDR R0,[R1] ;读出数据
ADD R0,R0,#1 ;加1操 作
STR R0,[R1] ;保存变量值
MOV PC LR
END
C 与 汇编相互调用
在 C 程 序和 ARM 汇编程序之间相互调用必须遵守 ATPCS.使用 ADS 的 C 语言编译器编译的 C语言子程序满足用户指定的 ATPCS类型.而对于汇编语言来说,完全要依赖用户来保证各个子程序满足选定的 ATPCS 类型.具体来说,汇编语言子程序必须满足下面 3
个条件,
9 在子程序编写时必须遵守相应的 ATPCS规则
9 堆栈的使用要遵守相应的 ATPCS规则,
9 在汇编编译器中使用-apcs 选项
基本 ATPCS 规定了在子程序调用时的一些基本规则,包括:各寄存器的使用规则及其相应的名称,堆栈的使用规则,参数传送的规则,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 107 页常用 ARM 指令集及 汇 编 Ver,1.0.12
寄存器的使用规则
9 子程序间通过寄存器 R0~R3来传递参数.这时,寄存器 R0~R3可记作 A0~A3.
被调用的子程序在返回前无须恢复寄存器 R0~R3的内容,
9 在子程序中,使用寄存器 R4~R11来保存局部变量.这时,寄存器 R4~R11可以记作 V1~V8.如果在子程序中使用了寄存器 V1~V8中的某些寄存器,子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值.在 Thumb程序中,通常只能使用寄存器 R4~R7来保存局部变量,
9 寄存器 R12用作过程调用中间临时寄存器,记作 IP.在子程序间的连接代码段中常有这种使用规则,
9 寄存器 R13用作堆栈指针,记作 SP.在子程序中寄存器 R13不能作其他用途.
寄存器 SP在进入子程序时的值和退出子程序时的值必须相等,
9 寄存器 R14 称为连接寄存器,记作 LR.它用于保存子程序的返回地址.如果在子程序中保存了返回地址,寄存器 R14则可以用作其他用途,
9 寄存器 R15是程序计数器,记作 PC.它不能用作其它用途,
堆栈使用规则
ATPCS规定堆栈为 FD类型,即满递减堆栈,并且对堆栈的操作是 8字节对齐,
使用 ADS中的编译器产生的目标代码中包含了 DRAFT2格式的数据帧.在调试过程中,
调试器可以使用这些数据帧来查看堆栈中的相 关信息.对于汇编语言来说,用户必须使用 FRAME 伪指令来描述堆栈的数据帧.ARM 汇编器根据这些伪指令在目标文件中产生相应的 DRAFT2格式的数据帧.(堆栈中的数据帧---在堆栈中,为子程序分配的用来保存寄存器和局部变量的区域),对于汇编程序来说,如果目标文件中包含了外部调用,则必须满足下列条件,
9 外部接口的堆栈必须是 8字节对齐的,
9 在汇编程序中使用 PRESERVE8伪指令告诉连接器,本汇编程序数据是 8字 节对齐的,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 108 页常用 ARM 指令集及 汇 编 Ver,1.0.12
参数传递规则
根据参数个数是否固定可以将子程序分为参数个数固定的子程序和参数个数可变化的子程序.这两种子的参数传递规则是不一样的,
9 参数个数可变的子程序参数传递规则
对于参数个数可变的子程序,当参数不超过 4个时,可以使用寄存器 R0~R3来传递参数;当参数超过 4个时,还可以使用堆栈来传递参数,
在参数传递时,将所有参数看作是存放在连续的内存字单元的字数据.然后,依次将各字数据传送到寄存器 R0,R1,R2,R3中,如果参数多于 4个,将剩余的字数据传送堆栈中,
入栈的顺序与参数顺序相反,即最后一个字数据先入栈,
按照上面的规则,一个浮点数参数可以通过寄存器传递,也可以通过堆栈传递,也可能一半通过寄存器传递,另一半通过堆栈传递,
9 参数个数固定的子程序参数传递规则
对于参数个数固定的子程序,参数传递与参数个数可变的子程序参数传递规则不同,
如果系统包含浮点运算的硬件部件,浮点参数将按下面的规则传递;
各个浮点参数按顺序处理;
为每个浮点参数分配 FP寄存器;
分配的方法是,满足该浮点参数需要的且编号最小的一组连续的 FP寄存器
第一个整数参数,通过寄存器 R0~R3来传递.其他参数通过堆栈传递,
9 子程序结果返回规则
子程序中结果返回的规则如下;
结果为一个 32位的整数时,可以通过寄存器 R0返回;
结果为一个 64位的整数时,可以通过寄存器 R0和 R1返回;
结果为一个浮点数时,可以通过浮点运算部件的寄存器 f0,d0或 s0来返回;
结果为复合型的浮点(如复数)时,可以通过寄存器 f0~fnA或 d0~dn来返回;
对于位数更多的结果,需要通过内存来传递,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 109 页常用 ARM 指令集及 汇 编 Ver,1.0.12
C程序调用汇编程序
汇编程序的设置要遵循 ATPCS规则,保证程序调用时参数的正确传递,
9 在汇编程序中使用 EXPORT 伪指令声明本子程序,使其它程序可以调用此子程序,
9 在 C 语 言程序中使用 extern 关键字声明外部函数(声明要调用的汇编子程序),即可调用此汇编子程序,
如以下程序所示,汇编子程序 strcopy使用两个参数,一个表示目标字符串地址,一个表示源字符串的地址,参数分别存放 R0,R1寄存器中,
调用汇编的 C 函数,
#include <stdio.h>
extern void strcopy(char*d,const char*s) //声明 外部函数,即要调用的汇编子程序
int mian(void)
{
const char *srcstr=“First string-source” ; //定义字符串常量
char dstsrt[] =“Second string-destination” ; //定义字符串变量
printf(“Before copying:\n”);
printf(“’%s’\n ‘%s\n,”srcstr,dststr); //显示源字符串和目标字符串的内容
strcopy(dststr,srcstr); //调用汇编子程序,R0=dststr,R1=srcstr
printf(“After copying:\n”)
printf(“’%s’\n ‘%s\n,”srcstr,dststr); //显 示 strcopy复制字符串结果
return(0);
}
被调用汇编子程序,
AREA SCopy,CODE,READONLY
EXPORT strcopy ;声明 strcopy,以便外部程序引用
strcopy;R0为目标字符串的地址;R1为源字符串的地址 ;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 110 页常用 ARM 指令集及 汇 编 Ver,1.0.12
LDRB R2,[R1],#1 ;读取字节数据,源地址加 1
STRB R2,[R0],#1 ;保存读取的 1字节数据,目标地址加 1
CMP r2,#0 ;判断字符串是否复制完毕
BNE strcopy ;没有复制完毕,继续循环
MOV pc,lr ;返回
END
汇编程序调用C程序
汇编程序的设置要遵循 ATPCS规则,保证程序调用时参数的正确传递,
在汇编程序中使用 IMPORT伪指令声明将要调用的 C程序函数,
在调用 C程序时,要正确设置入口参数,然后使用 BL调用,
以下程序清单所示,程序使用了 5 个参数,分别使用寄存器 R0 存储第 1 个 参数,R1
存储第 2个数,R2 存储第 3个参数,R3 存储第 4个参数,第 5个参数利用堆栈传送.由于利用了堆栈传递参数,在程序调用用结果后要调整堆栈指针
汇编调用 C程序的 C 函 数,
/*函数 sum5()返回 5个整数的和*/
int sum5(int a,lit b,int c,int d,int e)
{
return(a+b+c+d+e); //返回 5个变量的和
}
汇编调用 C程序的汇编程序,
EXPORT CALLSUM5
AREA Example,CODE,READONLY
IMPORT sum5 ;声明外部标号 sum5,即 C函 数 sum5()
CALLSUMS
STMFD SP!{LR} ;LR寄存器放栈
ADD R1,R0,R0 ;设置 sum5函数入口参数,R0 为参数 a
ADD R2,R1,R0 ;R1为参数 b,R2为参数 c
ADD R3,R1,R2,
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 111 页常用 ARM 指令集及 汇 编 Ver,1.0.12
STR R3,[SP,#-4]! ;参数 e要通过堆栈传递
ADD R3,R1,R1 ;R3为参数 d
BL sum5 ;调用 sum5(),结果保存在 R0
ADD SP,SP#4 ;修正 SP指针
LDMFD SP,{PC ;子程序返回
END
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 112 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM指令集列表
ARM 存储器访问指令表列表
助记符 说明 操作 条件码位置
LDR Rd,addressing 加载字数据 Rd←[addressing],addressing 索引 LDR{cond}
LDRB Rd,addressing 加载无符字节数据 Rd←[addressing],addressing 索引 LDR{cond}B
LDRT Rd,addressing 以用户模式加载字数据 Rd←[addressing],addressing 索引 LDR{cond}T
LDRBT Rd,addressing 以用户模式加载无符号字数据 Rd←[addressing],addressing 索引 LDR{cond}BT
LDRH Rd,addressing 加载无符半字数据 Rd←[addressing],addressing 索引 LDR{cond}H
LDRSB Rd,addressing 加载有符字节数据 Rd←[addressing],addressing 索引 LDR{cond}SB
LDRSH Rd,addressing 加载有符半字数据 Rd←[addressing],addressing 索引 LDR{cond}SH
STR Rd,addressing 存储字数据 [addressing]←Rd,addressing 索引 STR{cond}
STRB Rd,addressing 存储字节数据 [addressing]←Rd,addressing 索引 STR{cond}B
STRT Rd,addressing 以用户模式存储字数据 [addressing]←Rd,addressing 索引 STR{cond}T
STRBT Rd,addressing 以用户模式存储字节数据 [addressing]←Rd,addressing 索引 STR{cond}BT
STRH Rd,addressing 存储半字数据 [addressing]←Rd,addressing 索引 STR{cond}H
LDM{mode} Rn{!},reglist 批量(寄存器)加载 reglist←[Rn…],Rn 回存等 LDM{cond}{more}
STM{mode} Rn{!},rtglist 批量(寄存器)存储 [Rn…]← reglist,Rn 回存等 STM{cond}{more}
SWP Rd,Rm,Rn 寄存器和存储器字数据交换 Rd←[Rd],[Rn]←[Rm](Rn≠Rd 或 Rm) SWP{cond}
SWPB Rd,Rm,Rn 寄存器和存储器字节数据交换 Rd←[Rd],[Rn]←[Rm](Rn≠Rd 或 Rm) SWP{cond}B
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 113 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM 数据处理指令列表
助记符号 说明 操作 条件码位置
MOV Rd,operand2 数据转送 Rd←operand2 MOV {cond}{S}
MVN Rd,operand2 数据非转送 Rd←(operand2) MVN {cond}{S}
ADD Rd,Rn operand2 加法运算指令 Rd←Rn+operand2 ADD {cond}{S}
SUB Rd,Rn operand2 减法运算指令 Rd←Rn-operand2 SUB {cond}{S}
RSB Rd,Rn operand2 逆向减法指令 Rd←operand2-Rn RSB {cond}{S}
ADC Rd,Rn operand2 带进位加法 Rd←Rn+operand2+carry ADC {cond}{S}
SBC Rd,Rn operand2 带进位减法指令 Rd←Rn-operand2-(NOT)Carry SBC {cond}{S}
RSC Rd,Rn operand2 带进位逆向减法指令 Rd←operand2-Rn-(NOT)Carry RSC {cond}{S}
AND Rd,Rn operand2 逻辑与操作指令 Rd←Rn&operand2 AND {cond}{S}
ORR Rd,Rn operand2 逻辑或操作指令 Rd←Rn|operand2 ORR {cond}{S}
EOR Rd,Rn operand2 逻辑异或操作指令 Rd←Rn^operand2 EOR {cond}{S}
BIC Rd,Rn operand2 位清除指令 Rd←Rn&(~operand2) BIC {cond}{S}
CMP Rn,operand2 比较指令 标志 N、Z、C、V←Rn-operand2 CMP {cond}
CMN Rn,operand2 负数比较指令 标志 N、Z、C、V←Rn+operand2 CMN {cond}
TST Rn,operand2 位测试指令 标志 N、Z、C、V←Rn&operand2 TST {cond}
TEQ Rn,operand2 相等测试指令 标志 N、Z、C、V←Rn^operand2 TEQ {cond}
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 114 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM 乘法指令列表
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL RdLo,RdHi,Rm,Rs 64位无符号乘法指令 (RdLo,RdHi)←Rm*Rs UMULL{cond}{S}
UMLAL RdLo,RdHi,Rm,Rs 64位无符号乘加指令 (RdLo,RdHi)←Rm*Rs+(RdLo,RdHi) UMLAL{cond}{S}
SMULL RdLo,RdHi,Rm,Rs 64位有符号乘法指令 (RdLo,RdHi)←Rm*Rs SMULL{cond}{S}
SMLAL RdLo,RdHi,Rm,Rs 64位有符号乘加指令 (RdLo,RdHi)←Rm*Rs+(RdLo,RdHi) SMLAL{cond}{S}
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 115 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM 跳转指令列表
助记符 说明 操作 条件码位置
B label 跳转指令 Pc←label B{cond}
BL label 带链接的跳转指令 LR←PC-4,PC←label BL{cond}
BX Rm 带状态切换的跳转指令 PC←label,切换处理状态 BX{cond}
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 116 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM 协处理器指令列表
助记符 说明 操作 条件码位置
CDP
coproc,opcodel,CRd,CRn,CRm{,opcode2}
协处理器数据操作指令 取决于协处理器 CDP{cond}
LDC{L} coproc,CRd〈地址〉 协处理器数据读取指令 取决于协处理器 LDC{cond}{L}
STC{L} coproc,CRd,〈地址〉 协处理器数据写入指令 取决于协处理器 STC{cond}{L}
MCR coproc,opcodel,Rd,CRn,{,opcode2}
ARM寄存器到协处理器寄存器的数据传送指令
取决于协处理器 MCR{cond}
MRC coproc,opcodel,Rd,CRn,{,opcode2}
协处理器寄存器到 ARM寄存器到数据传送指令
取决于协处理器 MCR{cond}
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 117 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM 杂项指令列表
助记符 说明 操作 条件码位置
SWI immed_24 软中断指令 产生软中断,处理器进入管理模式 SWI{cond}
MRS Rd,psr 读状态寄存器指令 Rd←psr,psr 为 CPSR或 SPSR MRS{cond}
MSR psr_fields,Rd/#immed_8r 写状态寄存器指令
psr_fields← Rd/#immed_8r,psr 为
CPSR或 SPSR
MSR{cond}
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 118 页常用 ARM 指令集及 汇 编 Ver,1.0.12
ARM 伪指令列表
伪指令助记符 说明 操作 条件码位置
ADR register,expr 小范围的地址读取伪指令 register<-expr指向的地址 ADR{cond}
ADRL register,expr 中等范围的地址读取伪指令 register<-expr指向的地址 ADR{cond}
LDR
register,=expr/label-expr
大范围的地址读取伪指令 register<-expr/label-expr指定的数据/地址
LDR{cond}
NOP 空操作伪指令 无 无
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 119 页常用 ARM 指令集及 汇 编 Ver,1.0.12
Thumb指令集列表
Thumb 存储器访问指令列表
助记符 说明 操作 影响标志
LDR Rd,[Rn,#immed_5×4] 加载字数据 Rd←[Rm,#immed_5×4],Rd,Rn 为 R0~R7 无
LDRH Rd,[Rn,#immed_5×2] 加载无符半字数据 Rd←[Rm,#immed_5×2],Rd,Rn 为 R0~R7 无
LDRB Rd,[Rn,#immed_5×1] 加载无符字节数据 Rd←[Rm,#immed_5×1],Rd,Rn 为 R0~R7 无
STR Rd,[Rn,#immed_5×4] 存储字数据 Rn,#immed_5×4Rd←Rd,Rn 为 R0~R7 无
STRH Rd,[Rn,#immed_5×2] 存储无符半辽数据 Rn,#immed_5×2]Rd←Rd,Rn 为 R0~R7 无
STRB Rd,[Rn#immed_5×1] 存储无符字节数据 Rn,#immed_5×1]Rd←Rd,Rn 为 R0~R7 无
LDR Rd,[Rn,Rm] 加载字数据 Rd←[Rn,Rm],Rd,Rn,Rm 为 R0~R7 无
LDRH Rd,[Rn,Rm] 加载无符半字数据 Rd←[Rn,Rm],Rd,Rn,Rm 为 R0~R7 无
LDRB Rd,[Rn,Rm] 加载无符字节数据 Rd←[Rn,Rm],Rd,Rn,Rm 为 R0~R7 无
LDRSH Rd[Rn,Rm] 加载有符半字数据 Rd←[Rn,Rm],Rd,Rn,Rm 为 R0~R7 无
LDRSB Rd[Rn,Rm] 加载有符字节数据 Rd←[Rn,Rm],Rd,Rn,Rm 为 R0~R7 无
STR Rd,[Rn,Rm] 存储字数据 [Rn,Rm]←Rd,Rd,Rn,Rm 为 R0~R7 无
STRH Rd,[Rn,Rm] 存储无符半字数据 [Rn,Rm]←Rd,Rd,Rn,Rm 为 R0~R7 无
STRB Rd,[Rn,Rm] 存储无符字节数据 [Rn,Rm]←Rd,Rd,Rn,Rm 为 R0~R7 无
LDR Rd,[PC,#immed_8×4] 基于 PC加载字 数据 Rd←{PC,#immed_8×4]Rd 为 R0~R7 无
LDR Rd,label 基于 PC加载字 数据 Rd←[label],Rd 为 R0~R7 无
LDR Rd,[SP,#immed_8×4] 基于 SP加载字 数据 Rd←{SP,#immed_8×4]Rd 为 R0~R7 无
STR Rd,[SP,#immed_8×4] 基于 SP存储字 数据 {SP,#immed_8×4]←Rd,Rd 为 R0~R7 无
LDMIA Rn{!}reglist 批量(寄存器)加载 regist←[Rn…],Rn 回存等(R0~R7) 无
STMIA Rn{!}reglist 批量(寄存器)加载 [Rn…]←reglist,Rn 回存等(R0~R7) 无
PUSH {reglist[,LR]} 寄存器入栈指令 [SP…]←reglist[,LR],SP 回存等(R0~R7,LR) 无
POP {reglist[,PC]} 寄存器入栈指令 reglist[,PC]←[SP…],SP 回存等(R0~R7,PC) 无
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 120 页常用 ARM 指令集及 汇 编 Ver,1.0.12
Thumb 数据处理指令列表
助记符 说明 操作 影响标志
MOV Rd,#expr 数据转送 Rd←expr,Rd 为 R0~R7 影响 N,Z
MOV Rd,Rm 数据转送 Rd←Rm,Rd、Rm 均可为 R0~R15
RdT 和 Rm 均 为 R0~R7
时,影响 N,Z,清零 C,V
MVN Rd,Rm 数据非传送指令 Rd←(~Rm),Rd,Rm 均为 R0~ R7 影响 N,Z
NEG Rd,Rm 数据取负指令 Rd←(-Rm),Rd,Rm 均为 R0~R7 影 响 N,Z,C,V
ADD Rd.Rn,Rm 加法运算指令 Rd←Rn+Rm,Rd,Rn,Rm 均为 R0~R7 影响 N,Z,C,V
ADD Rd.Rn,#expr3 加法运算指令 Rd←Rn+expr#,Rd,Rn 均为 R0~R7 影响 N,Z,C,V
ADD Rd,#expr8 加法运算指令 Rd←Rd+expr8,Rd 为 R0~R7 影响 N,Z,C,V
ADD Rd,Rm 加法运算指令 Rd←Rd+Rm,Rd,Rm 均可为 R0~ R15
Rd 和 Rm 均 为 R0~R7
时,影响 N,Z,C,V
ADD Rd,Rp#expr SP/PC加法运算指令 Rd←SP+expr 或 PC+expr,Rd 为 R0~R7 无
ADD SP,#expr SP加法运算指令 SP←SP+expr 无
SUB Rd,Rn,Rm 减法运算指令 Rd←Rn-Rm,Rd、Rn、Rm 均为 R0~R7 影响 N,Z,C,V
SUB Rd,Rn,#expr3 减法运算指令 Rd←Rn-expr3,RdRn 均为 R0~R7 影响 N,Z,C,V
SUB Rd,#expr8 减法运算指令 RD←Rd-expr8,Rd 为 R0~R7 影 响 N,Z,C,V
SUB SP,#expr SP减法运算指令 SP←SP-expr 无
ADC Rd,Rm 带进位加法指令 Rd←Rd+Rm+Carry,Rd、Rm 为 R0~R7 影响 N,Z,C,V
SBC Rd,Rm 带位减法指令 Rd←Rd-Rm-(NOT)Carry,Rd、Rm 为 R0~R7 影响 N,Z,C,V
MUL Rd,Rm 乘法运算指令 Rd←Rd*Rm,Rd、Rm 为 R0~R7 影 响 N,Z,
AND Rd,Rm 逻辑与操作指令 Rd←Rd&Rm,Rd、Rm 为 R0~R7 影 响 N,Z,
ORR Rd,Rm 逻辑或操作指令 Rd←Rd|Rm,Rd、Rm 为 R0~R7 影 响 N,Z,
EOR Rd,Rm 逻辑异或操作指令 Rd←Rd^Rm,Rd、Rm 为 R0~R7 影 响 N,Z,
BIC Rd,Rm 位清除指令 Rd←Rd&(~Rm),Rd、Rm 为 R0~R7 影响 N,Z,
ASR Rd,Rs 算术右移指令 Rd←Rd 算术右移 Rs位,Rd,Rs 为 R0~R7 影响 N,Z,C,
ASR Rd,Rm,#expr 算术右移指令 Rd←Rm 算术右移 expr位,Rd,Rm 为 R0~R7 影 响 N,Z,C,
LSL Rd,Rs 逻辑左移指令 Rd←Rd<<Rs,Rd、Rs 为 R0~R7 影 响 N,Z,C,
LSL Rd,Rm,#expr 逻辑左移指令 Rd←Rm<<expr,Rd、Rm 为 R0~ R7 影响 N,Z,C,
LSR Rd,Rs 逻辑右移指令 Rd←Rd>>Rs,Rd、Rs 为 R0~R7 影 响 N,Z,C,
LSR Rd,Rm,#expr 逻辑右移指令 Rd←Rm>>mexpr,Rd、Rm 为 R0~R7 影响 N,Z,C,
ROR Rd,Rs 循环右移指令 Rd←Rm 循环右移 Rs位,Rd、R s为 R0~R7 影响 N,Z,C,
CMP Rn,Rm 比较指令 状态标←Rn-Rm,Rn、Rm 为 R0~R15 影响 N,Z,C,V
CMP Rn,#expr 比较指令 状态标←Rn-expr,Rn 为 R0~R 7 影响 N,Z,C,V
CMN Rn,Rm 负数比较指令] 状态标←Rn+Rm,Rn、Rm 为 R0~R7 影响 N,Z,C,V
TST Rn,Rm 位测试指令 状态标←Rn&Rm,Rn、Rm 为 R0~R7 影响 N,Z,C,V
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 121 页常用 ARM 指令集及 汇 编 Ver,1.0.12
Thumb 跳转指令及软中断指令列表
助记符 说明 操作 条件码位置
B label 跳转指令 PC←label B{cond}
BL label 带链接的跳转指令 LR←PC←4,PC←label 无
BX Rm 带状态切换的跳转指令 PC←label 切换处理器状态 无
SWI immed_8 软中断指令 产生软中断,处理器进入管理模式 无
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 122 页常用 ARM 指令集及 汇 编 Ver,1.0.12
Thumb 伪指令列表
伪指令助记符 说明 操作 条件码位置
ADR register,expr 小范围的地址读取伪指令 register<-expr指向的地址 无
LDR
register,=expr/label-expr
大范围的地址读取伪指令
register<-expr/label-expr指定的数据/地址

NOP 空操作伪指令 无 无
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 123 页常用 ARM 指令集及 汇 编 Ver,1.0.12
汇编预定义变量及伪指令
预定义的寄存器和协处理器名
ARM 汇编器对 ARM 的寄存器进行了预定义(包括 APCS 对 R0~R15 寄存器的定义),
所有的寄存器和协处理器名都是大小写敏感.预定义的寄存器如下,
通用寄存器
R0~R15和 r0~r15 (16个通用寄存器);
a1~a4(参数,结果或临时寄存器,同 R0~R3);
v1~v8(变量寄存器,同 R4~R11);
SB和 sb(静态基址,同 R9);
SL和 sl(堆栈限制,同 R10);
FP和 fp(帧指针);
IP和 ip(过程调用中间临时寄存器,同 R12);
SP和 sp(堆栈指针,同 R13);
LR和 lr(链接寄存器,同 R14);
PC和 pc(程序计数器,同 R15),
程序状态寄存器
CPSR和 cpsr;
SPSR和 spsr;
浮点数寄存器
F0~F7和 f0~f7(FPA寄存器);
S0~S7和 s0~s7(VFP单精度寄存器);
D0~D7和 d0~d7(VFP双精度寄存器);
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 124 页常用 ARM 指令集及 汇 编 Ver,1.0.12
协处理器及协处理器寄存器
p0~p15(协处理器 0~15);
c0~c15(协处理器寄存器 0~15);
内置变量列表
ARM 汇编器中定义了一些内置变量,如下表所示.这些内置变量不能使用伪指令设置(如 SETA,SETL,SETS),一般用于程序的条件汇编控制等,如下;
IF {CONFIG}=16

ELSE

ENDIF
B ;跳转到当前地址,即死循环
内置变量表
变量 说明
{PC}或"." 当前指令的地址
{VAR}或"@" 存储区位置计数器的当前值
{TRUE} 逻辑真
{FALSE} 逻辑假
{OPT} 当前设置列表选项值.OPT 用来保存当前列表选项,改变选项值,或恢复原始值
{CONFIG} 如果汇编器汇编 ARM代码,则 值为 32;若是汇编 Thumb代码,则值为 16
{ENDLAN} 如果汇编器在大端模式下,则值为 big;若在小端模式下,否则为 little
{CODESIZE} 如果汇编 Thumb代码,则值为 16,否则为 32.同{CONFIG}变量
{CPU} 选定的 CPU名,缺省为 ARM7TDMI.如果用命令行-cpu 选项,则为 genericARM
{FPU} 设定的 FPU名,缺省为 SoftVFP
{ARCHITECTURE} 选定的 ARM体 系结构的值,如 3,3M,4,4T,4TxM
{PCSTOREOFFSET} STR pc,[…]或 STR Rb,{…PC}指令的地址和 PC的存储值之间的偏移量
{ARMASM_VERSION}或|ads$
version|
ARM ASM的版本号,为整数
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 125 页常用 ARM 指令集及 汇 编 Ver,1.0.12
伪指令列表
伪指令类型 伪指令 功能
GBLA 声明一个全局的算术变量,并将其初始化为 0
GBLL 声明一个全局的逻辑变量,并将其初始化为{FALSE}
GBLS 声明一个全局的字符串变量,并将其初始化为空字符串""
LCLA 声明一个局部的算术变量,并将其初始化为 0
LCLL 声明一个局部的逻辑变量,并将其初始化为{FALSE}
LCLS 声明一个局部的字符串变量,并将其初始化为空字符串""
SETA 给一个全局/局部的算术变量赋值
SETL 给一个全局/局部的逻辑变量赋值
SETS 给一个全局/局部的字符串变量赋值
RLIST 为一个通用寄存器列表定义名称
CN 给一个协处理器寄存器命名,协处理器寄存器编号为 0~15
CP 为一个协处理器定义名称,协处理器编号为 0~15
DN 为一个双精度的 VFP寄存器 定义名称
SN 为一个单精度的 VFP寄存器 定义名称
符号定义指示符
FN 为一个 FPA浮 点寄存器定义名称
LTORG 声明一个文字池
MAP或^ 定义一个机构化的内存表首地址
FIELD或# 定义机构化内存表中的一个数据域
SPACE或% 分配一块内存空间,并用 0 初始化
DCB或= 分配一段字节的内存单元,并用指定的数据初始化
DCD或& 分配一段字的内存单元,并用指定的数据初始化
DCDU 分配一段在字的内存单元,并用指定的数据初始化(不需要字对齐)
DCDO
分配一段字的内存单元,将每个单元的内容初始化为该单元相对于静态基地址寄存器的偏移量
DCFD 分配一段双字的内存单元,并用双精度的浮点数初始化
DCFDU 分配一段双字的内存单元,并用双精度的浮点数据初始化(不需要字对齐)
DCFS 分配一段字的内存单元,并用单精度的浮点数据初始化
DCFSU 分配一段字的内存单元,并用单精度的浮点数据初始化(不需要字对齐)
DCI
分配一段字节的内存单元,用指定的数据初始化,指定内存单元存放的是代码而不是数据
DCQ 分配一段双字的内存单元,并用 64位的整 数数据初始化
DCQU 分配一段双字的内存单元,并用 64位的整 数数据初始化(不需要字对齐)
DCW 分配一段半字的内存单元,并用指定的数据初始化
数据定义指示符
DCWU 分配一段半字的内存单元,并用指定的数据初始化(不需要字对齐)
ASSERT
在汇编编译器对汇编程序的第二遍扫描中,如果 ASSERT 条件不成立,ASSERT
伪指令将报告该错误信息
INFO或! 在汇编编译器对汇编程序的第一遍或第二遍扫描时报告诊断信息
报告指示符
OPT 在源程序中设置列表选项
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 126 页常用 ARM 指令集及 汇 编 Ver,1.0.12
TTL 在列表文件中的每一页的开头插入一个标题
SUBT 在列表文件中的每一页的开头插入一个子标题
IF或[
ELSE或|
ENDIF或]
IF,ELSE和 ENDIF伪指令能够根据条件把一段源代码包括在汇编源程序内或将其排除在外
MACRO
MEND
MACRO和 MEND 伪指令用于宏定义
MEXIT 退出宏定义
WHILE
汇编控制指示符
WEND
WHILE和 WEND 伪指令用于根据条件重复汇编相同的或几乎相同的一段源代码
ALIGN 通过添加补丁字节使当前位置满足一定的对齐方式
AREA 定义一个代码段或数据段
CODE16 指示汇编编译器后面的指令为 16位的 Thumb指令
CODE32 指示汇编编译器后面的指令为 32位的 ARM 指令
END 指示汇编编译器源文件已结束
ENTRY 指定程序入口点
EQU或* 为数字常量、基于寄存器的值和程序中的标号定义一个名称
EXPORT或
GLOBAL
声明一个符号可以被其它文件引用。相当于生命了一个全局变量
IMPORT或
EXTERN
指示编译器当前的符号不是在本源文件中定义的,而是在其它源文件中定义的,在本源文件中可能引用该符号
GET或
INCLUDE
将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理
INCBIN 将一个文件包含到当前源文件中,而被包含的文件不进行和汇编处理
KEEP 指示编译器保留符号表中的局部符号
NOFP 禁止源程序中包含浮点运算指令
REQUIRE 指定段之间的依赖关系
REQUIRE8 指示当前文件请求堆栈为 8 字节对齐
PRESERVE8 指示当前文件保持堆栈为 8 字节对齐
RN 给一个特殊的寄存器命名
杂项指示符
ROUT 定义局部标号的有效范围
ADR 小范围的地址读取伪指令
ADRL 中等范围的地址读取伪指令
LDR 大范围的地址读取伪指令
ARM伪指令
NOP 空操作伪指令
ADR 中等范围的地址读取伪指令
LDR 大范围的地址读取伪指令 Thumb伪指令
NOP 空操作伪指令
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 127 页常用 ARM 指令集及 汇 编 Ver,1.0.12
指令条件码列表
条件码助记符 标志 含义
EQ Z=1 相等
NE Z=0 不相等
CS/HS C=1 无符号数大于或等于
CC/LO C=0 无符号数小于
MI N=1 负数
PL N=0 正数或零
VS V=1 溢出
VC V=0 没有溢出
HI C=1,Z=0 无符号数大于
LS C=0,Z=1 无符号数小于或等于
GE N=V 带符号数大于或等于
LT N!=V 带符号数小于
GT Z=0,N=V 带符号数大于
LE Z=1,N!=V 带符号数小于或等于
AL 任何 无条件执行(指令默认条件)
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 128 页常用 ARM 指令集及 汇 编 Ver,1.0.12
CPSR 和 SPSR 分配图
CPSR或 SPSR模式常量定义,
CPSR_f 或 SPSR_f CPSR_s 或 SPSR_s CPSR_x 或 SPSR_x CPSR_c 或 SPSR_c
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
N Z C V -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- I F T M4 M3 M2 M1 M0
负数或小于

进位或借位或扩展
溢出保留位
IRQ
禁止
1-
禁止
0
null允许
FIQ
禁止
1-
禁止
0
null允许
状态位
0-A
R
M 1-Th
umb
模式位
10000-0x0010-用户
10001-0x0011-快速中断
10010-0x0012-中断
10011-0x0013 管理
10111-0x0017-未定义
11111-0x001F-系统
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
By 宛城布 衣 QQ:57523799 email,mcu8031@163.com
第 129 页