D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9

DAY6. ARM汇编指令集-数据处理指令


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

该节内容以上一节的概述为路线用代码实际教学
(72条消息) 嵌入式学习LV9-ARM体系结构与接口技术- D5. ARM指令集仿真环境搭建_肉丸子QAQ的博客-CSDN博客

1. 数据搬移指令

MOV

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R1, #1  @ 将1这个数搬到R1寄存器
		 MOV R2, #2
		 MOV R1, #3

STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束

调试现象

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第1张图片

进入调试模式

  • 1,2步复位再点单步调试

  • 蓝色背景表示上一次执行指令后产生了变化

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第2张图片

  • 点击两次单步调试后可以看到R1.R2的值通过MOV指令改写了
  • 黄色箭头表示程序运行到哪里了

也可以将别的寄存器值写入另外一个寄存器:MOV R1, R2

验证PC寄存器知识点
  • PC值自动增加4

image-20230627102647672

image-20230627102724411

复位和点击一次单步调试可以看到PC寄存器自增了4

  • ARM每条指令占用四个字节

image-20230627102904602

转换成二进制后可以知道机器码是32位的

  • PC的值可以修改
.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R1, #1  @ 将1这个数搬到R1寄存器
		 MOV R2, #2
		 MOV R3, #3
		 MOV PC, #0 @将PC修改为0,也就类似一个小循环,将程序跳转到了最开始的位置

STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第3张图片

可以看到将PC修改成0后,程序跳转到地址为0的位置,也就是第一条指令MOV R1, #1的位置

  • 指令存储地址是4的整数倍,既PC值也是4的整数倍

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第4张图片

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第5张图片

无论写什么值,PC最后都会变成4的整数倍

MVN

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MVN R1, #0xFF @ R1 = ~0xFF 值取反后写入
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第6张图片

  • 汇编语言一一对应
.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R0, #0  
		 MVN R0, #0


STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束

绿色:不同类型指令,相同寄存器,值相同——>机器码前缀不同

红色:相同指令,操作不同寄存器,值相同——>机器码中间不同

蓝色:相同指令,操作相同寄存器,值不同——>机器码后缀不同

总结:

汇编中每一条的指令的机器码都是一一对应的


立即数

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R0, #0x12345678 @报错
         MOV R0, #12  		 @不报错

STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束
  • 机器码32位
  • 第一条指令数据太大,超过了32位,无法编译成32位机器码
  • 立即数的本质就是包含在指令当中的数,属于指令的一部分
  • 立即数和变量的有区别
  • 立即数的优点:取指的时候就可以将其读取到CPU,不用单独去内存读取,速度快
  • 立即数的缺点:不能是任意的32位的数字,有局限性
  • 最直接辨别的方法:能编译通过的就是立即数
  • 对于MOV指令0-255都是立即数
  • 不用背那些是立即数,理解本质

编译器替换

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		  MOV R0, #0xFFFFFFFF 

STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束

前面讲到立即数是有限制的,数据过大会导致编译失败,但是这里发现编译通过了

  • 从反编译中可以看出指令是MOV变成了MVN
  • 这两条的指令的结果是相同的
    • MOV将R0全部写成了1
    • MVN将R0写成0后取反

2. 数据运算指令——数学运算

数据运算指令基本格式

《操作码》《目标寄存器》《第一操作寄存器》《第二操作数》

	 ADD R1, R2, R3
	 @ R1 = R2 + R3
	 ADD R1, R2, #5
	 @ R1 = R2 + 5
  • 操作码 指示执行哪种运算
  • 目标寄存器: 存储运算结果
  • 第一操作寄存器:存储第一个参与运算的数据==(只能是寄存器)==
  • 第二操作数: 第二个参与运算的数据(可以是寄存器或立即数)

加法指令 ADD

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R2, #5
		 MOV R3, #3
		 ADD R1, R2, R3
		 @R1 = R2 + R3
		 ADD R1, R2, #5
		 @R1 = R2 + 5

STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第7张图片

减法指令 SUB

运算顺序:第一操作寄存器 — 第二操作数

  • 寄减寄
  • 寄减数
.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R2, #5
		 MOV R3, #3
		@ 减法指令
		 SUB R1, R2, R3
		@ R1 = R2 - R3
		 SUB R1, R2, #3
		@ R1 = R2 - 3

STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第8张图片


逆向减法指令 RSB

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R2, #5
		 MOV R3, #3
		 RSB R1, R2, R3
		@ R1 = R3 - R2

STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第9张图片


乘法指令 MUL

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R2, #5
		 MOV R3, #3
		@ 乘法指令
		 MUL R1, R2, R3
		@ R1 = R2 * R3
		@ 乘法指令只能是两个寄存器相乘
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

注意!!!

  • 乘法指令只能是两个寄存器相乘
  • 在arm是精简指令集不支持除法

3. 数据运算指令——逻辑运算

按位与指令 AND

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R2, #0
		 MOV R3, #3
		@ 按位与指令
		 AND R1, R2, R3
		@ R1 = R2 & R3
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第10张图片

按位或指令 ORR

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R2, #0
		 MOV R3, #3
		 MOV R1, #0
		@ 按位或指令
		 ORR R1, R2, R3
		@ R1 = R2 | R3
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

按位异或指令 EOR

异或:相同为0,不同为1

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R2, #0
		 MOV R3, #3
		 MOV R1, #0
		@ 按位异或指令
		 EOR R1, R2, R3
		@ R1 = R2 ^ R3
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

左移指令 LSL

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R2, #0xF0
		 MOV R3, #2
		@ 左移指令
		 LSL R1, R2, R3   @R2左移R3个位
		@ R1 = (R2 << R3)
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第11张图片

右移指令 LSR

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
		 MOV R2, #0xF0
		 MOV R3, #2
		@ 右移指令
		 LSR R1, R2, R3
		@ R1 = (R2 >> R3)
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

位清零指令 BIC

第二操作数中的哪一位为1,就将第一操作寄存器的中哪一位清零,然后将结果写入目标寄存器

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口

		 MOV R2, #0xFF
		 BIC R1, R2, #0x0F
		@ 第二操作数中的哪一位为1,就将第一操作寄存器的中哪一位清零,然后将结果写入目标寄存器
		
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第12张图片

注意!!

  • 这里的清零不是将原本的寄存器清零,而是将原本的寄存器清零后的数据储存到另外一个寄存器

格式扩展

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口

		@ 格式扩展
		 MOV R2, #3
		 MOV R1, R2, LSL #1
		@ R1 = (R2 << 1)		
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第13张图片

《操作码》《目标寄存器》《第一操作寄存器》《第二操作数》

遵循指令基本格式:第一位是操作码

  1. 所以这条指令最后是MOV指令:将绿框内容搬移到R1寄存器
  2. 绿框内容表示将R2寄存器左移一位
  3. 最后结果就是将R2寄存器左移一位后放入R1保存
  4. 011变为110

4. 数据运算指令对条件位(N、Z、C、V)(CPSR寄存器)的影响

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第14张图片

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口

		
		 MOV R2, #3
		 SUB R1, R2, #5
	
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第15张图片

  • 从结果能看到CPSR寄存器的N位没有受到影响
  • 默认情况下数据运算不会对条件位产生影响,在指令后加后缀”S“才可以影响
.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口

		
		 MOV R2, #3
		 SUBS R1, R2, #5  @指令后面加S
	
STOP:	
		B STOP		@死循环,防止程序跑飞	

.end				@汇编程序的结束	

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第16张图片

32位计算机如何计算64位数据

  • 好比低年级学生只会个位加法,当计算十位数时需要将数据拆开单个运算,计算机同理
		@ 带进位的加法指令
		@ 两个64位的数据做加法运算
		@ 第一个数的低32位放在R1
		@ 第一个数的高32位放在R2
		@ 第二个数的低32位放在R3
		@ 第二个数的高32位放在R4
		@ 运算结果的低32位放在R5
		@ 运算结果的高32位放在R6
		
		@ 第一个数
		@ 0x00000001 FFFFFFFF
		@ 第二个数
		@ 0x00000002 00000005
		
		@ MOV R1, #0xFFFFFFFF
		@ MOV R2, #0x00000001
		@ MOV R3, #0x00000005
		@ MOV R4, #0x00000002
		@ ADDS R5, R1, R3
		@ ADC  R6, R2, R4  @ADC指令能自动加上低位的进位,如果用ADD计算机是不会加上进位数据
		@ 本质:R6 = R2 + R4 + 'C'
		
		@ 带借位的减法指令
		
		@ 第一个数
		@ 0x00000002 00000001
		@ 第二个数
		@ 0x00000001 00000005
		
		@ MOV R1, #0x00000001
		@ MOV R2, #0x00000002
		@ MOV R3, #0x00000005
		@ MOV R4, #0x00000001
		@ SUBS R5, R1, R3
		@ SBC  R6, R2, R4
		@ 本质:R6 = R2 - R4 - '!C' @取非

  • ADC:ADC指令能自动加上低位的进位,如果用ADD计算机是不会加上进位数据
    • ADC本质:R6 = R2 + R4 + ‘C’:加上了CPSR寄存器的C位
  • SBC:同理

5. 作业

1.编程实现使用32bit的ARM处理器实现两个128位的数据的加法运算。

注:

第一个数的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R1、R2、R3、R4寄存器
第二个数的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R5、R6、R7、R8寄存器
运算结果的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R9、R10、R11、R12寄存器

.text		@ 表示当前为代码段
.global _start @ 将_start定义为全局符号
_start: 	@ 汇编的入口
 
 
			@ 带进位的加法运算(两个128位数据)
			@ 第一个数	0xFFFFFFFF	00000001 00000001 00000001
			@ 第二个数	0x00000002	00000002 00000002 00000002
			@第一个数的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R1、R2、R3、R4寄存器
			@第二个数的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R5、R6、R7、R8寄存器
			@运算结果的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R9、R10、R11、R12寄存器
			 MOV R1, #0xFFFFFFFF
			 MOV R2, #0x00000001
			 MOV R3, #0x00000001
			 MOV R4, #0x00000001
			 
			 MOV R5, #0x00000002
			 MOV R6, #0x00000002
			 MOV R7, #0x00000002
			 MOV R8, #0x00000002
			
			 ADDS R9, R1, R5
			 ADCS  R10, R2, R6
			 ADCS  R11, R3, R7
			 
			 ADC  R12, R4, R8
			
stop:					@死循环,防止程序跑飞
	B stop
 
.end					@ 汇编的结束 

D6. 数据处理指令-ARM体系结构与接口技术-嵌入式学习LV9_第17张图片

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