程序设计思路:通过状态寄存器与通用寄存器之间数据传输指令MRS/MSR实现,修改时应采用“读取-修改-写回”三个步骤来实现。每次只需修改相应的域即可,如本次程序只修改C控制域。同时应注意系统模式与用户模式共用SP,只需初始化其一即可。
程序代码如下:
(1)在GNU ARM开发环境下编程:
.equ _ISR_STARTADDRESS, 0xC7FF000 @设置栈的内存基地址
.equ UserStack, _ISR_STARTADDRESS @用户模式堆栈地址0x7FF000
.equ SVCStack, _ISR_STARTADDRESS+256 @管理模式堆栈地址0x7FF100
.equ UndefStack, _ISR_STARTADDRESS+256*2
.equ AbortStack, _ISR_STARTADDRESS+256*3
.equ IRQStack, _ISR_STARTADDRESS+256*4
.equ FIQ Stack, _ISR_STARTADDRESS+256*5
.equ USERMODE, 0x10
.equ FIQMODE, 0x11
.equ IRQMODE, 0x12
.equ SVCMODE, 0x13
.equ ABORTMODE, 0x17
.equ UNDEFMODE, 0x1B
.equ SYSMODE, 0x1F
.equ MODEMASK, 0x1F
.global _start
.text
_start:
MRS R0, CPSR @读取当前CPSR
BIC R0, R0, #MODEMASK @清除模式位
#设置用户模式下的SP
ORR R1, R0, #SYSMODE
MSR CPSR_c, R1
LDR SP, =UserStack
#设置未定义模式下的SP
ORR R1, R0, #UNDEFMODE
MSR CPSR_c, R1
LDR SP, =UndefStack
#设置终止模式下的SP
ORR R1, R0, #ABORTMODE
MSR CPSR_c, R1
LDR SP, =AbortStack
#设置管理模式下的SP
ORR R1, R0, #SVCMODE
MSR CPSR_c, R1
LDR SP, =SVCStack
#设置IRQ模式下的SP
ORR R1, R0, #IRQMODE
MSR CPSR_c, R1
LDR SP, =IRQStack
#设置FIQ模式下的SP
ORR R1, R0, #FIQMODE
MSR CPSR_c, R1
LDR SP, =FIQStack
Stop:
B Stop
.end
(2)程序执行结果如下:
SP_usr=0xC7FF000
SP_svc=0xC7FF100
SP_und=0xC7FF200
SP_abt=0xC7FF300
SP_irq=0xC7FF400
SP_fiq=0xC7FF500