【教学目标和要求】

通过实验了解嵌入式汇编语言程序结构,完成实验中要求的工作模式切换功能。

【主要仪器设备和药品】

(1)硬件:微机

(2)软件:ADS1.2

【实验要求】

(1)按照实验要求编写汇编语言源程序。

(2)对汇编源程序进行编译、汇编。

(3)对程序进行调试。

(4)观察程序运行结果。

【实验程序】

(1)汇编程序:

本程序将0-12依次移入R0-R12寄存器后,跳转到initstack标号执行模式切换,最后回到跳转点,最终将模式切换为用户模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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 ; 开IRQ中断
msr cpsr_cxsf,r0 ; cpsr<--r0

;切换到用户模式
msr cpsr_c,#0xd0;110 10000 cpsr[4:0]
mrs r0,cpsr
stmfd sp!,{r1-r12};将r12至依次入栈
;切换到系统模式
msr cpsr_c,#0xdf ;110 11111 cpsr[4:0]
mrs r0,cpsr
stmfd sp!,{r1-r12}
halt b halt
initstack mov r0,lr ; r0<--lr,将连接寄存器的值赋给R0

;设置管理模式堆栈
msr cpsr_c,#0xd3 ; 110 10011 cpsr[4:0]
ldr sp,stacksvc
stmfd sp!,{r1-r12}
;设置IRQ中断模式堆栈
msr cpsr_c,#0xd2 ;110 10010 cpsr[4:0]
ldr sp,stackirq
stmfd sp!,{r1-r12}
;设置FIQ快速中断模式堆栈
msr cpsr_c,#0xd1 ;110 10001 cpsr[4:0]
ldr sp,stackfiq
stmfd sp!,{r1-r12}
;设置中止模式堆栈
msr cpsr_c,#0xd7 ;110 10111 cpsr[4:0]
ldr sp,stackabt
stmfd sp!,{r1-r12}
;设置未定义模式堆栈
msr cpsr_c,#0xdb ;110 11011 cpsr[4:0]
ldr sp,stackund
stmfd sp!,{r1-r12}
;设置系统模式堆栈
msr cpsr_c,#0xdf ;110 11111
ldr sp,stackusr
stmfd sp!,{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. 程序复位之后系统处于什么模式?

答:

img

图 1 程序复位后寄存器状态

由上图可知,复位后系统处于管理模式。

2. 记录每种模式下的初始堆栈指针,以及执行 R1-R12 内容压栈后本模式堆栈相关内存单元的数值。并分析快速中断 FIQ 模式与其他模式存入的 R1-R12 有什么不同。

答:

(1) 管理模式:

img

图 2 系统切换到管理模式

初始堆栈指针为0x8244

img

图 3 管理模式下将r0-r12数据入栈

R1-R12压栈后,堆栈指针为0x8214,较初始堆栈指针相距0x30字节,在32位系统即12个字,对应R1-R12的数据。

(2) IRQ中断模式:

img

图 4 系统切换到IRQ模式

初始堆栈指针为0x8344

img

图 5 IRQ模式下将r0-r12数据入栈

R1-R12压栈后,堆栈指针为0x8314,较初始堆栈指针相距0x30字节,在32位系统即12个字,对应R1-R12的数据。

(3) FIQ模式:

img

图 6 系统切换到FIQ模式

初始堆栈指针为0x8384

img

图 7 FIQ模式下将r0-r12数据入栈

R1-R12压栈后,堆栈指针为0x8354,较初始堆栈指针相距0x30字节,在32位系统即12个字,但FIQ模式下只压入了R1-R7的数据,这是因为在FIQ模式下,可访问的寄存器只有R1-R7,不能访问R8-R12,FIQ模式下有对应自己的R8-R12。

(4) 中止模式:

img

图 8 系统切换到中止模式

初始堆栈指针为0x83C4

img

图 9 中止模式下将r0-r12数据入栈

R1-R12压栈后,堆栈指针为0x8394,较初始堆栈指针相距0x30字节,在32位系统即12个字,对应R1-R12的数据。

(5) 未定义模式:

img

图 10 系统切换到未定义模式

初始堆栈指针为0x8404

img

图 11 未定义模式下将r0-r12数据入栈

R1-R12压栈后,堆栈指针为0x83D4,较初始堆栈指针相距0x30字节,在32位系统即12个字,对应R1-R12的数据。

(6) 系统模式:

img

图 12 系统切换到系统模式

初始堆栈指针为0x81C4

img

图 13 系统模式下将r0-r12数据入栈

R1-R12压栈后,堆栈指针为0x8194,较初始堆栈指针相距0x30字节,在32位系统即12个字,对应R1-R12的数据。

(7) 用户模式:

img

图 14 系统切换到用户模式

初始堆栈指针为0x8194

img

图 15 用户模式下将r0-r12数据入栈

R1-R12压栈后,堆栈指针为0x8164,较初始堆栈指针相距0x30字节,在32位系统即12个字,对应R1-R12的数据。

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

答:如下图当前模式为用户模式,在该模式下执行切换系统模式的代码:

img

图 16 系统切换到用户模式下

img

图 17 在用户模式下切换模式结果

可以看到模式仍为用户模式,因此切换成用户模式之后不能从用户模式切换到其他模式,除非异常发生。

4. 用户模式下能否执行堆栈压栈操作?如果能得话,观察用户模式下压栈之前和压栈之后其堆栈区域的变化情况。

答:由问题2的测试可知,用户模式下可以执行堆栈压栈操作,且以4个字节(1个字)为单位进行压栈操作。

5. 观察本程序模式切换过程中 SPSR 有无变化,并解释其原因

答:模式切换过程中SPSR无变化。因为SPSR是异常模式的程序状态保存寄存器,在本程序切换过程中没有异常发生,所以SPSR无变化。