📄 sma_stackutils.s
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $Workfile: SMA_stackutils.s $
; $Revision: 1.0 $
; $Author: kovitzp $
; $Date: 12 Mar 2002 14:36:12 $
;
; Project: ARM Processor Support
;
; Description:
; This module contains a function for changing the stack pointer
; Usage for functions (return old stack pointer):
; UNS_32 * arm_set_stack(UNS_32 * new_sp, UNS_32 mode)
; WARNING: This function is not re-entrant! Disable all
; interrupts before using this function.
;
; Revision History:
; $Log: P:/PVCS6_6/archives/LH79520/ProdTest/SMA_stackutils.s-arc $
;
; Rev 1.0 12 Mar 2002 14:36:12 kovitzp
; Initial revision.
;
; COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
; CAMAS, WA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
AREA ARM_STACKUTILS, CODE ; name this block of code
MODE_USR EQU 0x010
MODE_FIQ EQU 0x011
MODE_IRQ EQU 0x012
MODE_SVC EQU 0x013
MODE_ABORT EQU 0x017
MODE_UNDEF EQU 0x01b
MODE_SYSTEM EQU 0x01f
MODE_BITS EQU 0x01f
I_MASK EQU (1 << 7) ; 0x080
F_MASK EQU (1 << 6) ; 0x040
; Export the functions needed by other modules
EXPORT SMA_set_stack
; temporary storage used by all functions
; this is the reason functions are not re-entrant.
newstack DCD 0
ret_adr DCD 0
ret_status DCD 0
;-------------------------------------------------------------------
;
;
; Function: SMA_set_stack
;
; Purpose:
; Sets the stack pointer (r13) in IRQ mode to a new value
;
; Processing:
; Preserve the return address and current mode
; Switch to the mode specfied in r1 mode
; Store the old stack pointer value into r0
; Store the new stack pointer value into r13
; restore the previous mode and return
;
; Parameters:
; r0 = new IRQ stack pointer address
; r1 = mode identifier. Must be one of
; MODE_USR
; MODE_FIQ
; MODE_IRQ
; MODE_SVC
; MODE_ABORT
; MODE_UNDEF
; MODE_SYSTEM
; r14 = return address
;
; Outputs: None
;
; Returns:
; r0 = previous value of the IRQ stack pointer address UNLESS:
; - the current mode is user mode AND
; - the mode specified in r1 is not user mode.
; - For this case, the function call fails and r0 = 0.
;
; Notes:
; This function destroys r0 and r14. It sets r13 to the new value.
; Register r1 is unchanged.
;
; You may call this function from user mode, but only if you want
; to change the user stack pointer. If you attempt to change any
; other stack pointer, this function returns 0 and does nothing
; to the stack pointer.
;
; No stack in the current mode is assumed.
;
; WARNING! This function is not re-entrant. Only call this
; function if interrupts are disabled.
;---------------------------------------------------------------------
SMA_set_stack
str r0,newstack ; free r0
mrs r0,cpsr ; keep CPSR in r0
str r14,ret_adr ; free r14
str r0,ret_status ; be able to return
and r0,r0,#MODE_BITS ; if currently in user mode
cmp r0,#MODE_USR
bne not_in_user_mode
cmp r0,r1 ; and not changing user stack ptr
eoreq r0,r0,r0 ; then return 0
ldreq pc,ret_adr
mov r0,r13 ; else get old stack into r0
ldr r13,newstack ; get new stack into r13
mov pc,r14 ; and return
not_in_user_mode
cmp r0,r1 ; else if not in requested mode
beq in_mode
orr r0,r1,#I_MASK:OR:F_MASK ; switch modes with interrupts off
msr cpsr_cxsf, r0
in_mode
mov r0,r13 ; get return value into r0
ldr r13,newstack ; get new stack
ldr r14,ret_status ; get ready to return
msr cpsr_cxsf, r14
ldr pc,ret_adr ; done
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -