实验目的
(1)通过实验掌握学会使用msr/mrs指令实现ARM处理器工作模式的切换,观察不同模式下的寄存器,加深对CPU结构的理解;
(2)通过实验掌握ld中如何使用命令指定代码段起始地址。
实验环境
硬件:PC 机
软件:ADS1.2 集成开发环境
实验内容
通过ARM汇编指令,在各种处理器模式下切换并观察各种模式下寄存器的区别;掌握ARM不同模式的进入与退出。
实验要求
(1)按照2.3节介绍的方法,在ADS下创建一个工程asmmodelab,完成各个模式下的堆栈初始化工作,并将R1-R12的内容存入当前模式下堆栈。通过AXD运用单步执行方式调用程序,验证工作的模式,使用寄存器观察切换到不同的工作模式下观察SP(R13)的变化情况。
(2)实验过程中请记录并思考以下内容:
1)程序复位之后系统处于什么模式?
2)记录每种模式下的初始堆栈指针,以及执行R1-R12内容压栈后本模式堆栈相关内存单元的数值。并分析快速中断FIQ模式与其他模式存入的R1-R12有什么不同。
3)切换成用户模式之后还能否从用户模式切换到其他模式?
4)用户模式下能否执行堆栈压栈操作?如果能的话,观察用户模式下压栈之前和之后其堆栈区域的变化情况。
5)观察本程序模式切换过程中SPSR有无变化,并解释其原因。
实验代码:
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
entry
code32
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 ;初始化各模式下的堆栈指针
;打开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 ;110 10000: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 ;110 11111:I,F位置1,禁止IRQ和FIQ中断,T=0,ARM执行,M【4:0】为11111,切换到系统模式
mrs r0,cpsr
stmfd sp!,{r1-r12}
halt b halt
initstack mov r0,lr ; r0<--lr,因为各种模式下r0是相同的而各个模式?
;设置管理模式堆栈
msr cpsr_c,#0xd3 ; 110 10011 切换到管理模式
ldr sp,stacksvc ;设置管理模式堆栈地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减模式
;设置中断模式堆栈
msr cpsr_c,#0xd2 ;110 10010 切换到中断模式
ldr sp,stackirq ;设置中断模式堆栈地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减模式
;设置快速中断模式堆栈
msr cpsr_c,#0xd1 ;110 10001 切换到快速中断模式
ldr sp,stackfiq ;设置快速中断模式堆栈地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减模式
;设置中止模式堆栈
msr cpsr_c,#0xd7 ;110 10111 切换到中止模式
ldr sp,stackabt ;设置中止模式堆栈地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减模式
;设置未定义模式堆栈
msr cpsr_c,#0xdb ;110 11011 切换到未定义模式
ldr sp,stackund ;设置未定义模式堆栈地址
stmfd sp!,{r1-r12} ;R1-R12入栈,满递减模式
;设置系统模式堆栈
msr cpsr_c,#0xdf ;110 11111 切换到系统模式
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
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
1)程序复位之后系统处于什么模式?
答:处于管理模式
2)记录每种模式下的初始堆栈指针,以及执行R1-R12内容压栈后本模式堆栈相关内存单元的数值。并分析快速中断FIQ模式与其他模式存入的R1-R12有什么不同。
管理模式:
初始堆栈指针为0x00008244
执行R1-R12内容压栈后本模式堆栈相关内存单元的数值:
中断模式:
初始堆栈指针为0x00008344
执行R1-R12内容压栈后本模式堆栈相关内存单元的数值:
快速中断模式:
初始堆栈指针为0x00008384
执行R1-R12内容压栈后本模式堆栈相关内存单元的数值:
在快速中断模式中,可访问的寄存器只有R1-R7,不能访问R8-R12,快速中断模式下有自己的R8-R12。
中止模式:
初始堆栈指针为0x000083C4
执行R1-R12内容压栈后本模式堆栈相关内存单元的数值:
未定义模式:
初始堆栈指针为0x00008404
执行R1-R12内容压栈后本模式堆栈相关内存单元的数值:
系统模式:
初始堆栈指针为0x000081C4
执行R1-R12内容压栈后本模式堆栈相关内存单元的数值:
快速中断FIQ模式与其他模式存入的R1-R12的不同:由图可见快速中断模式只有R1-R7压入栈了,这是因为在快速中断模式中,可访问的寄存器只有R1-R7,不能访问R8-R12,快速中断模式下有自己的R8-R12。
3)切换成用户模式之后还能否从用户模式切换到其他模式?
答:不能切换,因为进入User模式后就不能再操作CPSR返回到其他模式了。
4)用户模式下能否执行堆栈压栈操作?如果能的话,观察用户模式下压栈之前和之后其堆栈区域的变化情况。
答: 用户模式下能进行堆栈压栈操作
未压栈时:
压栈后:
5)观察本程序模式切换过程中SPSR有无变化,并解释其原因。
答:除了用户模式和系统模式,其余模式下都有一个私有SPSR保存状态寄存器. 用来保存切换到该模式之前的执行状态,只有异常模式下有SPSR寄存器,因为在整个切换过程中没有异常发生,所以SPSR无变化。
暂无评论内容