D9. 专用指令-ARM体系结构与接口技术-嵌入式学习LV9

DAY9. 专用指令


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


1. 状态寄存器传送指令MSR

MSR状态寄存器传送指令:访问(读写)CPSR寄存器,其他指令无法操作CPSR寄存器

  • 当程序运行完后点击复位,可以看到CPSR寄存器值没有清零,进入SVC模式、

读CPSR

		@ 读CPSR
		 MRS R1, CPSR
		@ R1 = CPSR

写CPSR

	@ 写CPSR
	 MSR CPSR, #0x10
	@ CPSR = 0x10
  • USER模式下不能随意修改CPSR
		@ 读CPSR
		 MRS R1, CPSR
		@ R1 = CPSR
		
		@ 写CPSR
		 MSR CPSR, #0x10 @改成user模式
		@ CPSR = 0x10
		
		@ 在USER模式下不能随意修改CPSR,因为USER模式属于非特权模式
		 MSR CPSR, #0xD3

D9. 专用指令-ARM体系结构与接口技术-嵌入式学习LV9_第1张图片

在user模式没办法修改cpsr寄存器,为了保护系统,将权力给到最低

2. 软中断指令SWI

软中断是一种异常

  • 软中断执行后会将模式切换为SVC模式
  • 执行过程(由下面代码为例)如下图
.text		@ 表示当前为代码段
.global _start @ 将_start定义为全局符号
_start: 	@ 汇编的入口
 MAIN:
		 
		@ 初始化SVC模式下的栈指针
		 MSR CPSR, #0x10
		@ 切换成USER模式,开启FIQ、IRQ
		 MOV R1, #1
		 MOV R2, #2
		 SWI #1
		@ 触发软中断异常
		 ADD R3, R2, R1
		 B STOP
			
stop:					@死循环,防止程序跑飞
	B stop
 
.end					@ 汇编的结束 

结果如下:

  • D9. 专用指令-ARM体系结构与接口技术-嵌入式学习LV9_第2张图片
  • LR:保存中断指令后一条地址用于返回程序;示例中ADD的地址
  • PC:修改为异常向量表的地址
  • CPSR:93》》》1001 0011:最低5位为模式位 10011是SVC模式;IRQ变为1,被禁用
  • SPSR:储存中断前的模式(user)

从仿真中会出现一个情况当执行软中断后程序指针跳转到了0X08这个位置

  • 是因为SWI异常向量表地址为0x08就相当于当前程序占用了异常处理程序的地址空间,所以这个main函数是有问题的,需要将main函数改动
  • 0-31地址都是异常向量表(32个字节)使用的
		@ 异常向量表(32个字节)
		 B MAIN @跳转到main中,0地址是复位,即复位后跳转到main
		 B .
		 B SWI_HANDLER @0x08地址,在异常向量表中一般不写异常处理程序,而是写异常处理程序的地址
		 B .
		 B .
		 B .
		 B .
		 B .
		
		@ 应用程序
 MAIN:
		 MOV SP, #0x40000020 @这句话要在SVC模式下写,因为每个模式都有自己R13(栈指针SP),如果写在CPSR后面就会变成usr模式下的栈指针
		@ 初始化SVC模式下的栈指针
		 MSR CPSR, #0x10
		@ 切换成USER模式,开启FIQ、IRQ
		 MOV R1, #1
		 MOV R2, #2
		 SWI #1
		@ 触发软中断异常
		 ADD R3, R2, R1
		 B STOP
 SWI_HANDLER:
		 STMFD SP!,{R1,R2,LR} @压栈,防止main的R1R2被破坏
		 @压栈保护现场
		 
		 MOV R1, #10
		 MOV R2, #20
		 SUB R3, R2, R1
		 
		 LDMFD SP!,{R1,R2,PC}^
		@ 出栈恢复现场
		@ 将压入到栈中的LR(返回地址)出栈给PC,实现程序的返回
		@ 出栈后加^符号‘^’表示出栈的同时将SPSR的值传递给CPSR,实现CPU状态的恢复

^表示出栈的同时将SPSR的值传递给CPSR,实现CPU状态的恢复

使用SWI的情况

当程序需要访问内存时需要在SVC模式,但是程序运行是在user模式下不能修改CPSR来直接修改为SVC模式

3. 协处理器指令

协处理器指令:操控协处理器的指令

  • 了解一下

1. 协处理器数据运算指令CDP

CDP

2. 协处理器存储器访问指令STC和LDC

  • STC 将协处理器中的数据写入到存储器

  • LDC 将存储器中的数据读取到协处理器

3. 协处理器寄存器传送指令MRC和MCR

  • MRC 将协处理器中寄存器中的数据传送到ARM处理器中的寄存器

  • MCR 将ARM处理器中寄存器中的数据传送到协处理器中的寄存器

4. 伪指令

cpu是无法停止工作的

1. 伪指令

伪指令:本身不是指令,编译器可以将其替换成若干条等效指令

  • NOP:空操作

    • NOR指令被替换成了MOV R0, R0
    	@ 空指令
    	 NOP
    	 MOV R0, R0 @自己颁给自己,相当于cpu什么都没干
    
  • LDR:非常特殊,根据格式的不同既可以是伪指令也能是指令

    • 指令
    	@ 指令
    	 LDR R1, [R2]
    	@ 将R2指向的内存空间中的数据读取到R1寄存器
    
    • 伪指令
    	@ 伪指令
    	 LDR R1, =0x12345678
    	@ R1 = 0x12345678	
    	@ LDR伪指令可以将任意一个32位的数据放到一个寄存器
    
 LDR R1, =STOP @将地址写入
 @将STOP表示的地址写入R1寄存器
 LDR R1, STOP @将机器码写入
 @将STOP地址中的内容写入R1寄存器

5. 作业

1.编程实现通过状态寄存器传送指令,将ARM处理器的模式修改成USER模式并将FIQ与IRQ使能

.text				@表示当前段为代码段
.global _start		@声明_start为全局符号
_start:				@汇编程序的入口
	MRS R1, CPSR
	MSR CPSR, #0X10 @模式修改成USER模式并将FIQ与IRQ使能,CPSR寄存器(00010000)(0x10)

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

.end				@汇编程序的结束

2.简述伪指令和指令的本质区别是什么

指令:是控制程序运行时的机器代码运作的,是CPU执行的依据,编程、编译、执行都是有效的。
伪指令:本身不是指令,编译器可以将其替换成若干条等效指令,编译完成后,伪指令的作用也就消失了。

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