程序設計思路:通過狀態寄存器與通用寄存器之間數據傳輸指令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