文章和代码已归档至【Github仓库:hardware-tutorial】,需要的朋友们自取。或者重视大众号【AIShareLab】,回复 嵌入式 也可获取。
一、试验意图
(1) 经过试验掌握学会运用msr/mrs 指令完成ARM 处理器作业形式的切换,调查不同形式下的寄存器,加深对CPU 结构的了解;
(2) 经过试验掌握ld 中如何运用命令行指定代码段起始地址。
二、试验环境
硬件:PC机。
软件:ADS1.2 集成开发环境
三、试验内容
经过 ARM 汇编指令,在各种处理器形式下切换并调查各种形式下寄存器的差异;掌握ARM 不同形式的进入与退出。
四、试验要求
(1)按照2.3节介绍的办法, 在ADS下创建一个工程asmmodelab,完结各个形式下的仓库初始化作业,并将R1-R12的内容存入当前形式下仓库。经过AXD运用单步履行方式调试程序,验证作业形式的切换,注意调查CPSR寄存器中的改变。跟着程序调试进程中在形式间的切换,运用寄存器调查器切换到不同的作业形式下调查SP(R13)的改变状况。
(2)试验进程中请记载并考虑以下内容:
1)程序复位之后体系处于什么形式?
2)记载每种形式下的初始仓库指针,以及履行R1-R12内容压栈后本形式仓库相关内存单元的数值。并分析快速间断FIQ形式与其他形式存入的R1-R12有什么不同。
3)切换成用户形式之后还能否从用户形式切换到其他形式(如体系形式)?
4)用户形式下能否履行仓库压栈操作?如果能得话,调查用户形式下压栈之前和压栈之后其仓库区域的改变状况。
5)调查本程序形式切换进程中SPSR有无改变,并解说其原因。
五、试验状况
1、试验源代码(含注释):
usr_stack_legth equ 64 ;界说各个形式的栈空间长度
svc_stack_legth equ 32
fiq_stack_legth equ 16
irq_stack_legth equ 64
abt_stack_legth equ 16
und_stack_legth equ 16
area reset,code,readonly ;界说code片段reset只读
entry ;设置程序进口伪指令
code32 ;界说后面的指令为32位的ARM指令
;设置各个寄存器中的内容
start mov r0,#0
mov r1,#1
mov r2,#2
mov r3,#3
mov r4,#4
mov r5,#5
mov r6,#6
mov r7,#7
mov r8,#8
mov r9,#9
mov r10,#10
mov r11,#11
mov r12,#12
bl initstack ;跳转至initstack,并且初始化各形式下的仓库指针,打开IRQ间断(将cpsr寄存器的i位清0)
mrs r0,cpsr ;r0<--cpsr
bic r0,r0,#0x80 ;cpsr的I方位0,开IRQ间断
msr cpsr_cxsf,r0 ;cpsr<--r0
;切换到用户形式
msr cpsr_c,#0xd0 ;设置11010000,其间I,F方位1,制止IRQ和FIQ间断,T=0,ARM履行,M[4:0]为10000,切换到用户形式
mrs r0,cpsr ;r0<--cpsr
stmfd sp!,{r1-r12} ;将R1-R12入栈
;调查用户形式能否切换到其他形式
;切换到管理形式
msr cpsr_c,#0xdf ;设置11011111,其间I,F方位1,制止IRQ和FIQ间断,T=0,ARM履行,M[4:0]为11111,切换到体系形式
mrs r0,cpsr ;r0<--cpsr
stmfd sp!,{r1-r12} ;将寄存器列表中的r1-r12寄存器存入仓库
halt b halt ;从halt跳转到halt循环
initstack mov r0,lr ; r0<--lr,由于各种形式下r0是相同的而各个形式不同
;设置管理形式仓库
msr cpsr_c,#0xd3 ; 设置11010011 切换到管理形式
ldr sp,stacksvc ;设置管理形式仓库地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减形式
;设置间断形式仓库
msr cpsr_c,#0xd2 ;设置11010010 切换到间断形式
ldr sp,stackirq ;设置间断形式仓库地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减形式
;设置快速间断形式仓库
msr cpsr_c,#0xd1 ; 设置11010001 切换到快速间断形式
ldr sp,stackfiq ;设置快速间断形式仓库地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减形式
;设置间断形式仓库
msr cpsr_c,#0xd7 ; 设置11010111 切换到间断形式
ldr sp,stackabt ;设置间断形式仓库地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减形式
;设置未界说形式仓库
msr cpsr_c,#0xdb ; 设置11011011 切换到未界说形式
ldr sp,stackund ;设置未界说形式仓库地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减形式
;设置体系形式仓库
msr cpsr_c,#0xdf ; 设置11011111 切换到体系形式
ldr sp,stackusr ;设置体系形式仓库地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减形式
mov pc,r0 ;返回
;为各形式仓库拓荒一段连续的字存储空间
stackusr dcd usrstackspace+(usr_stack_legth-1)*4
stacksvc dcd svcstackspace+(svc_stack_legth-1)*4
stackirq dcd irqstackspace+(irq_stack_legth-1)*4
stackfiq dcd fiqstackspace+(fiq_stack_legth-1)*4
stackabt dcd abtstackspace+(abt_stack_legth-1)*4
stackund dcd undstackspace+(und_stack_legth-1)*4
;界说data段并命名
area reset,data,noinit,align=2
;为各形式仓库分配存储区域
usrstackspace space usr_stack_legth*4
svcstackspace space svc_stack_legth*4
irqstackspace space irq_stack_legth*4
fiqstackspace space fiq_stack_legth*4
abtstackspace space abt_stack_legth*4
undstackspace space und_stack_legth*4
end
2、试验进程(含结果截图及相应文字解说):
试验进程中请记载并考虑以下内容:
1)程序复位之后体系处于什么形式?
由上可知,体系复位后处于管理形式。
2)记载每种形式下的初始仓库指针,以及履行R1-R12内容压栈后本形式仓库相关内存单元的数值。并分析快速间断FIQ形式与其他形式存入的R1-R12有什么不同。
①管理形式
由上图可知,管理形式初始指针为0x8244。
履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8214,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。
②间断形式
由上图可知,间断形式初始指针为0x8344。
履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8314,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。
③快速间断形式
由上图可知,快速间断形式初始指针为0x8384。
履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8354,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R7存储的数值对应,说明该形式下仅能压入R1-R7,由于快速间断形式有自己的R8-R12。
④间断形式
由上图可知,间断形式初始指针为0x83C4。
履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8394,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。
⑤未界说形式
由上图可知,未界说形式初始指针为0x8404。
履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x83D4,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。
⑥体系形式
由上图可知,体系形式初始指针为0x81C4。
履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8194,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。
⑦用户形式:
由上图可知,用户形式初始指针为0x8194。
履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8164,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。
3)切换成用户形式之后还能否从用户形式切换到其他形式(如体系形式)?
由上图可知,当进行切换管理形式时,形式仍是用户形式,因此可知切换成用户形式之后,不能操作CPSR返回到其他形式。
4)用户形式下能否履行仓库压栈操作?如果能得话,调查用户形式下压栈之前和压栈之后其仓库区域的改变状况。
压栈前:
压栈后:
压栈后存储单元状况:
答:用户形式下能够履行仓库压栈操作,且以4个字节(1个字)为单位进行压栈操作,压栈前仓库区域状况如左图,压栈后如右图所示,对应的存储单元状况如上图。
5)调查本程序形式切换进程中SPSR有无改变,并解说其原因。
答:除了用户形式和体系形式,其他形式下都有一个私有SPSR保存状况寄存器. 用来保存切换到该形式之前的履行状况,SPSR是反常形式的程序状况保存寄存器, 当特定的反常间断产生时,这个寄存器寄存CPSR的内容,在反常间断退出时,能够用SPSR来康复CPSR,可是经过调查可知,整个切换进程中没有反常的产生,因此SPSR没有改变。
六、总结
ARM处理器形式别离是usr(用户形式),fiq(快速间断形式),irq(通用间断形式),svc(管理形式),abt(终止形式),sys(体系形式)以及und(未界说形式)。也经过ARM指令,完成了ARM不同形式的进入与退出,切换各种处理器形式,并调查各种形式下寄存器的差异。当特定的反常出现时,进入相应的形式。每种形式都有某些附加的寄存器,以防止反常出现时用户形式的状况不可靠。此外也运用状况寄存器到通用寄存器的传送指令(MRS)以及通用寄存器到状况寄存器的传送指令(MSR),修改状况寄存器经过“读取-修改-写回”三个过程操作来完成。
欢迎重视大众号【AIShareLab】,一同沟通更多相关知识,前沿算法,Paper解读,项目源码,面经总结。