文章和代码已归档至【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)程序复位之后体系处于什么形式?

嵌入式ARM设计编程(三) 处理器工作模式

由上可知,体系复位后处于管理形式。

2)记载每种形式下的初始仓库指针,以及履行R1-R12内容压栈后本形式仓库相关内存单元的数值。并分析快速间断FIQ形式与其他形式存入的R1-R12有什么不同。

①管理形式

嵌入式ARM设计编程(三) 处理器工作模式

由上图可知,管理形式初始指针为0x8244。

嵌入式ARM设计编程(三) 处理器工作模式

履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8214,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。

②间断形式

嵌入式ARM设计编程(三) 处理器工作模式

由上图可知,间断形式初始指针为0x8344。

嵌入式ARM设计编程(三) 处理器工作模式

履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8314,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。

③快速间断形式

嵌入式ARM设计编程(三) 处理器工作模式

由上图可知,快速间断形式初始指针为0x8384。

嵌入式ARM设计编程(三) 处理器工作模式

履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8354,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R7存储的数值对应,说明该形式下仅能压入R1-R7,由于快速间断形式有自己的R8-R12。

④间断形式

嵌入式ARM设计编程(三) 处理器工作模式

由上图可知,间断形式初始指针为0x83C4。

嵌入式ARM设计编程(三) 处理器工作模式

履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8394,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。

⑤未界说形式

嵌入式ARM设计编程(三) 处理器工作模式

由上图可知,未界说形式初始指针为0x8404。

嵌入式ARM设计编程(三) 处理器工作模式

履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x83D4,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。

⑥体系形式

嵌入式ARM设计编程(三) 处理器工作模式

由上图可知,体系形式初始指针为0x81C4。

嵌入式ARM设计编程(三) 处理器工作模式

履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8194,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。

⑦用户形式:

嵌入式ARM设计编程(三) 处理器工作模式

由上图可知,用户形式初始指针为0x8194。

嵌入式ARM设计编程(三) 处理器工作模式

履行R1-R12内容压栈后本形式仓库相关内存单元的数值如上图所示,可知压栈后,仓库指针变为0x8164,离初始的仓库指针0x30字节,即12个字(32位体系),从内存单元的数值能够看到别离与R1-R12存储的数值对应。

3)切换成用户形式之后还能否从用户形式切换到其他形式(如体系形式)?

嵌入式ARM设计编程(三) 处理器工作模式

由上图可知,当进行切换管理形式时,形式仍是用户形式,因此可知切换成用户形式之后,不能操作CPSR返回到其他形式。

4)用户形式下能否履行仓库压栈操作?如果能得话,调查用户形式下压栈之前和压栈之后其仓库区域的改变状况。

压栈前:

嵌入式ARM设计编程(三) 处理器工作模式

压栈后:

嵌入式ARM设计编程(三) 处理器工作模式

压栈后存储单元状况:

嵌入式ARM设计编程(三) 处理器工作模式

答:用户形式下能够履行仓库压栈操作,且以4个字节(1个字)为单位进行压栈操作,压栈前仓库区域状况如左图,压栈后如右图所示,对应的存储单元状况如上图。

5)调查本程序形式切换进程中SPSR有无改变,并解说其原因。

答:除了用户形式和体系形式,其他形式下都有一个私有SPSR保存状况寄存器. 用来保存切换到该形式之前的履行状况,SPSR是反常形式的程序状况保存寄存器, 当特定的反常间断产生时,这个寄存器寄存CPSR的内容,在反常间断退出时,能够用SPSR来康复CPSR,可是经过调查可知,整个切换进程中没有反常的产生,因此SPSR没有改变。

六、总结

ARM处理器形式别离是usr(用户形式),fiq(快速间断形式),irq(通用间断形式),svc(管理形式),abt(终止形式),sys(体系形式)以及und(未界说形式)。也经过ARM指令,完成了ARM不同形式的进入与退出,切换各种处理器形式,并调查各种形式下寄存器的差异。当特定的反常出现时,进入相应的形式。每种形式都有某些附加的寄存器,以防止反常出现时用户形式的状况不可靠。此外也运用状况寄存器到通用寄存器的传送指令(MRS)以及通用寄存器到状况寄存器的传送指令(MSR),修改状况寄存器经过“读取-修改-写回”三个过程操作来完成。


欢迎重视大众号【AIShareLab】,一同沟通更多相关知识,前沿算法,Paper解读,项目源码,面经总结。