嵌入式系统课程笔记03 ARM 指令系统

03 ARM 指令系统

文章目录


部分参考:

ARM64指令简易手册 - 简书 (jianshu.com)

指令格式

ARM 指令的基本格式

ARM指令基本格式
<opcode>{<cond>}{S} <Rd>,<Rn>,{<Op2>}

<>必须

{}可选

<opcode>

指令助记符 必需

{<cond>}

指令执行条件 可选。不写->无条件执行

ARM指令格式说明
项目 含义 备注
opcode 指令的操作码 指令助记符,eg LDR,STR
cond 条件域,满足条件才执行指令 可不加条件
S 指令执行时是否更新CPSR(程序状态寄存器) 可省略
Rd 目标寄存器 Rd为任意通用寄存器
Rn 第一个操作数 Rn为任意通用寄存器
Op2 第二个操作数 可为#immed_8r、寄存器Rm及任意移位的寄存器
; 注释符号 加注释
Op2备注
#immed_8r

常数表达式,该常数必须对应8位位图,即一个8位的常数通过循环右移偶数位得到的32位常数

寄存器Rm

在寄存器方式下,操作数即为寄存器的数值

eg

SUB R1,R1,R2 ; R1-R2→R1
MOV PC,R0 ; PC=R0,程序跳转到指定地址
寄存器Rm 移位

将寄存器的移位结果作为操作数,Rm 值保持不变

ADD R1,R1,R1,LSL#3 ; R1=R1+R1*8=9R1,
SUB R1,R1,R2,LSR#2 ; R2 逻辑右移2 位,最后结果是R1=R1-(R2/4)

汇编语言的一般格式

一个完整的ARM 汇编由两部分组成:声明实际代码段

声明
声明代码段

AREA 指令定义一个段,说明所定义段的相关属性(段的名字和段的属性等)

AREA指令是一个伪指令,用于段定义。

声明ARM 指令

用CODE来声明程序为ARM指令

声明程序入口

用ENTRY 指令标识程序的入口点。在程序完成后要用END 指令声明程序结束。每一个汇编程序段都必须有一条END 指令,指示代码段的结束。

段的定义

在ARM 汇编语言程序中,以程序段为单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。

段的分类

一个汇编程序至少有一个代码段。如果程序较长时,可以分割为多个代码段和数据段。多个段在程序编译连接时最终形成一个可执行的映像文件

代码段

代码段的内容为执行代码

数据段

数据段存放代码运行时需要用到的数据

ARM 指令编码

eg

	AREA	ARMex,CODE,READONLY	;代码块命名为ARMex
	ENTRY						;声明程序入口
start
	MOV		r0,#10				;设置参数
	MOV		r1,#3
	ADD		r0,r0,r1			;r0 = r0 + r1
stop
	MOV		r0,#0x18			;
	LDR		r1,=0x20026			;将存储器地址为0x20026的字数据读入寄存器R0
	SVC		#0x123456			;生成编号为#0x123456的SVC(supervisor call)

条件码

{<cond>}

表示一个可选的条件码。使用条件码“cond”可以实现高效的逻辑操作,提高代码效率

只有在CPSR 中条件码对应的标志满足指定条件时,带条件码的指令才被执行,否则指令被忽略

条件码位于ARM 指令的最高4 位[31:28]

指令的条件码

条件码 助记符后缀 标识 含义
0000 EQ Z置位 相等
0001 NE Z清零 不相等
0010 CS C置位 无符号数大于或等于
0011 CC C清零 无符号数小于
0100 MI N置位 负数
0101 PL N清零 正数或零
0110 VS V置位 溢出
0111 VC V清零 未溢出
1000 HI C置位Z清零 无符号数大于
1001 LS C清零Z置位 无符号数小于或等于
1010 GE N等于V 带符号数大于或等于
1011 LT N不等于V 带符号数小于
1100 GT Z清零且(N等于V) 带符号数大于
1101 LE Z置位或(N不等于V) 带符号数小于或等于
1110 AL 无条件执行

1111系统保留,暂不使用

NZCV标志位总结

N

N=1表示运算的结果为负数;N=0表示运算的结果为正数或零

Z

Z=1表示运算的结果为零,Z=0表示运算的结果非零

C

加法运算(包括CMN):当运算结果产生了进位时(无符号数溢出),C=1,否则C=0

减法运算(包括CMP):当运算时产生了借位时(无符号数溢出),C=0,否则C=1

对于包含移位操作的非加/减运算指令,C为溢出值的最后一位。

对于其它的非加/减运算指令,C的值通常不会改变。

V

对于加减法运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出

对于其它的非加/减运算指令,V的值通常不会改变。

ARM 指令的寻址方式

8 种基本的寻址方式

立即寻址

立即寻址也叫作立即数寻址。立即寻址方式的目的是将操作数紧跟在操作码后面,与操作码一起放在指令代码段中。在程序运行时,程序直接调用该操作数,而不需要到其他地址单元中去取相应的操作数

ADD		R1,R0,#1		;R0 <- R0 + 1
MOV		R0,#0xFF00		;R0 <- 0xFF00

寄存器寻址

寄存器寻址指的是操作数的值在寄存器中,指令中的地址码字段给出的是寄存器编号,指令执行时直接取出寄存器值来操作。

ADD		R0,R1,R2		;R0 <- R1 + R2
MOV		R1,R2			;R1 <- R2

指令MOV R1,R2

在这里插入图片描述

寄存器移位寻址

寄存器移位寻址的操作数是由寄存器做相应移位而得到的,移位的方式在指令中以助记符的形式给出,而移位的位数可用立即数或寄存器寻址方式表示。

MOV		R0,R2,LSL#3		;R2的值逻辑左移三位 R0 <- R2*8
ANDS	R1,R1,R2,LSL R3	;R2的值逻辑左移R3位,然后和R1相与存入R1

寄存器间接寻址

寄存器间接寻址指令中的地址码给出的是一个通用寄存器的编号,所需的操作数保存在存储器指定地址的存储单元中,即寄存器是操作数的地址指针。用于**间接寻址的寄存器必须用[ ]**括起来。

STR		R0,[R1]			;将R0的值传送到以Rq的值作为地址的存储器中
LDR		R1,[R2]			;将以R2的值作为地址的寄存器中的数据传送搭配R1中

指令LDR R1,[R2]

在这里插入图片描述

基址寻址

基址寻址方式就是将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到操作数的有效地址。寄存器间接寻址是偏移量为0的基址加偏移寻址。

用基址访问同在一个存储区域的某一存储单元的内容。
LDR		R0,[R1,#4]			;R0 <- [R1 + 4]
LDR		R2,[R3,#0x0C]		;R2 <- [R3 + 0x0C]

LDR R2,[R3,#0x0C]
在这里插入图片描述

带自动变址的前变址寻址

“!”符号表明指令在完成数据传送后应该更新基址寄存器。ARM 的这种自动变址不消耗额外时间

LDR		R0,[R1,#4]!			;R0 <- [R1 + 4],R1 <- R1 + 4

这条指令是将寄存器R1 的内容加上位移量4 形成操作数的有效地址,从该地址取的操作数存入寄存器R0 中,然后将R1 的内容自增4 字节

后变址寻址

基址加偏移寻址。基址不带偏移作为传送的地址,传送后自动变址

LDR		R0,[R1],#4			;R0 <- [R1],R1 <- R1 + 4

这里没有“!”符号,只使用立即数偏移作为基址寄存器的修改量。这条指令是将寄存器R1 的内容作为操作数的有效地址,从该地址取得操作数存入寄存器R0 中,然后将R1 的内容自增4 字节

指令指定一个基址寄存器,再指定另一个寄存器(变址),其值作为位移与基址相加形成存储器地址
LDR		R0,[R1,R2]			;R0 <- [R1 + R2]

相对寻址

相对寻址和基址变址寻址方式类似,以程序计数器PC 的当前值作为基地址,指令中的地址标号作为偏移
,将两者相加之后得到操作数的有效地址

跳转指令利用相对寻址

多寄存器寻址

多寄存器寻址可以实现一条指令完成多个寄存器值的传送,允许一条指令传送 16 个寄存器的任何子集或所有寄存器。

LDMIA		R0,{R1,R2,R3,R4}		;R1 <- [R0]
									;R2 <- [R0 + 4]
									;R3 <- [R0 + 8]
									;R4 <- [R0 + 12]

该条指令的后缀IA 即表示在每次执行完加载/存储操作之后,R0 按字长度(即4 字节)增加。因此指令可以将连续多个存储单元的值传送到R1~R4 中。

LDR R1!,{R2- R4,R6}

在这里插入图片描述

R2- R4:R2到R4

堆栈寻址

堆栈使用一个叫作堆栈指针专用寄存器指示当前操作位置,堆栈指针总是指向栈顶。存储器堆栈可分为如下两种方式

存储器堆栈方式
向上生长

当堆栈由低地址向高地址生成时,称为递增堆栈(Ascending Stack)

向下生长

当堆栈由高地址向低地址生成时,称为递减堆栈(Descending Stack)

在这里插入图片描述

堆栈工作方式

在ARM 指令中,数据的进栈和出栈通过Load/Store 指
令实现,指令STM 向堆栈写数据项,指令LDM 从堆栈读
数据项。

满递增堆栈(Full Ascending Stackÿ
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值