D7. 跳转与存储器访问指令-ARM体系结构与接口技术-嵌入式学习LV9

DAY7. ARM汇编指令集-跳转与储存器访问指令


如果出现图片无法查看可能是网络问题,我用的GitHub+图床保存的图片,可以参考我另外一篇文章GitHub的使用方法含网络问题解决
GitHub使用教程含网络问题_github加速器_肉丸子QAQ的博客-CSDN博客

1. 跳转指令

跳转指令:实现程序的跳转,本质就是修改了PC寄存器

main函数中调用子函数

  • 方式一:直接修改PC寄存器的值(不建议使用,需要自己计算目标指令的绝对地址)
		
MAIN: @这个只是一个标号,不是指令
		 MOV R1, #1
		 MOV R2, #2
		 MOV R3, #3
		 MOV PC, #0x18 @0x18是因为指令按照顺序存储,FUNC函数的起始位置是  MOV R6, #6  从上往下数是0x18
		 MOV R4, #4
		 MOV R5, #5	
FUNC:
		 MOV R6, #6
		 MOV R7, #7
		 MOV R8, #8
  • ​ 方式二:不带返回的跳转指令(B),本质就是将PC寄存器的值修改成跳转标号下指令的地址
MAIN:
		 MOV R1, #1
		 MOV R2, #2
		 MOV R3, #3
		 B   FUNC
		 MOV R4, #4
		 MOV R5, #5	
FUNC:
		 MOV R6, #6
		 MOV R7, #7
		 MOV R8, #8
  • 方式三:带返回的跳转指令,本质就是将PC寄存器的值修改成跳转标号下指令的地址,同时将跳转指令下一条指令的地址存储到LR寄存器
 MAIN:
		 MOV R1, #1
		 MOV R2, #2
		 MOV R3, #3
		 BL  FUNC
		 MOV R4, #4
		 MOV R5, #5	
 FUNC:
		 MOV R6, #6
		 MOV R7, #7
		 MOV R8, #8
		 MOV PC, LR @如果不自己添加返回代码是无法跳转回去,BL指令会保存地址在LR,所以我们直接调用LR的内容就行

2. ARM指令的条件码

条件码不是指令

比较指令

CMP指令的本质就是一条减法指令(SUBS),只是没有将运算结果存入目标寄存器

如何比较:根据CPSR中的(N,Z,C,V)

	 MOV R1, #1
	 MOV R2, #2
	 CMP R1, R2
	 BEQ FUNC	
	@ 执行逻辑:if(EQ(R1和R2相等)){B FUNC}	本质:if(Z==1){B FUNC}
	 BNE FUNC	
	@ 执行逻辑:if(NQ){B FUNC}	本质:if(Z==0){B FUNC}
	 MOV R3, #3
	 MOV R4, #4
	 MOV R5, #5
FUNC:
	MOV R6, #6
	MOV R7, #7		

ARM指令集中大多数指令都可以带条件码后缀


3. 内存访问指令

Load/Srore指令:访问(读写)内存

  • Load:加载:LD开头指令一般用于读内存数据

  • Srore:存储:ST一般用于数据存在内存

  • [R2]:地址一定要写在中括号里面

读写数据

	@ 写内存
	 MOV R1, #0xFF000000
	 MOV R2, #0x40000000		@任何芯片都有芯片的规划
	 STR R1, [R2] 
	@ 将R1寄存器中的数据写入到R2指向的内存空间
	
	@ 读内存
	 LDR R3, [R2]
	@ 将R2指向的内存空间中的数据读取到R3寄存器
	
	
	

D7. 跳转与存储器访问指令-ARM体系结构与接口技术-嵌入式学习LV9_第1张图片

可以验证两个知识点

  • ARM是小端对齐
  • ARM是四的整数倍存储
  • 不同芯片对于自身内存有不同的规划
  • 如何在仿真环境查看地址

读/写指定的数据类型

@ 读/写指定的数据类型
		 MOV R1, #0xFFFFFFFF
		 MOV R2, #0x40000000
		 STRB R1, [R2] @写入一个字节
		@ 将R1寄存器中的数据的Bit[7:0]写入到R2指向的内存空间
		 STRH R1, [R2] 	@写入
		@ 将R1寄存器中的数据的Bit[15:0]写入到R2指向的内存空间
		 STR  R1, [R2] 	@写入
		@ 将R1寄存器中的数据的Bit[31:0]写入到R2指向的内存空间
  • B后缀:写入1个字节

  • H后缀:写入2个字节

  • 默认:四个字节


4. ARM指令的寻址方式

寻址方式:就是CPU去寻找操作数的方式

立即寻址

从立即数中获取

	@ 立即寻址
	 MOV R1, #1
	 ADD R1, R2, #1

寄存器寻址

从寄存器中获取

	@ 寄存器寻址
	 ADD R1, R2, R3

寄存器移位寻址

	@ 寄存器移位寻址
	 MOV R1, R2, LSL #1

寄存器间接寻址

  • R2不是直接参与,只是作为一个指针
  • 寄存器间接寻址是将指定的寄存器内容为地址,由该地址所指定的单元内容作为操作数
	@ 寄存器间接寻址
	 STR R1, [R2] 

基址加变址寻址

	@ 基址加变址寻址
	 MOV R1, #0xFFFFFFFF
	 MOV R2, #0x40000000
	 MOV R3, #4
	 STR R1, [R2,R3]
	@ 将R1寄存器中的数据写入到R2+R3指向的内存空间
	 STR R1, [R2,R3,LSL #1]
	@ 将R1寄存器中的数据写入到R2+(R3<<1)指向的内存空间

基址加变址寻址的索引方式

前索引
	@ 前索引
	 MOV R1, #0xFFFFFFFF
	 MOV R2, #0x40000000
	 STR R1, [R2,#8]
	@ 将R1寄存器中的数据写入到R2+8指向的内存空间,R2没有变化
	

C语言中数组,数组名是地址不变,改变其中内容:

  • C语言:c[10]; c[2] = ‘A’

  • 汇编:add c+2

用前索引就省去了add

后索引
@ 后索引
 MOV R1, #0xFFFFFFFF
 MOV R2, #0x40000000
 STR R1, [R2],#8
@ 将R1寄存器中的数据写入到R2指向的内存空间,然后R2自增8
自动索引

集合了上面两种

@ 自动索引
 MOV R1, #0xFFFFFFFF
 MOV R2, #0x40000000
 STR R1, [R2,#8]!
@ 将R1寄存器中的数据写入到R2+8指向的内存空间,然后R2自增8

以上寻址方式和索引方式同样适用于LDR

5. 作业

1.使用汇编语言实现100以内的正整数之和

注:将最终的运算结果存储在R2寄存器

.text		@ 表示当前为代码段
.global _start @ 将_start定义为全局符号
_start: 	@ 汇编的入口
 
 
.global _start
_start:
MOV R0, #0   
MOV R1, #1   
MOV R2, #0   

SUM_LOOP:
    ADD R2, R1   @ R1加到R2里面
    ADD R1, #1   @ R1自加一
	
    CMP R1, #100   @判断大于100后跳转结束
    BGT SUM_END   
	
    B SUM_LOOP   

SUM_END:


			
stop:					@死循环,防止程序跑飞
	B stop
 
.end					@ 汇编的结束 

你可能感兴趣的:(学习,arm开发,驱动开发,linux)