iar_stack_enter_leave.s51
来自「8051试验程序 基础教材」· S51 代码 · 共 2,959 行 · 第 1/5 页
S51
2,959 行
RSEG RCODE:CODE:NOROOT
PUBLIC ?SMALL_INTERRUPT_ENTER_PSP
EXTERN ?VB
EXTERN ?V0
EXTERN ?PSP
EXTERNS_FOR_ALL_DPTR_SYMBOLS()
cfi BLOCK ?SMALL_INTERRUPT_ENTER_PSP Using cfi_common
cfi NOFUNCTION
cfi A Undefined
?SMALL_INTERRUPT_ENTER_PSP:
ADD A,?PSP ; Allocate space on the stack
MOV R0,A ; R0 = PSPold - nrVreg - 4/5/6
XCH A,?PSP ; A = PSPold
CLR C ; Counter = end - start - 4/5/6
SUBB A,R0 ; -> A = nrVreg + 4/5/6
#if ((__NUMBER_OF_DPTRS__ > 1) && (defined(__EXTENDED_DPTR__)))
ADD A,#-6 ; -> A = nrVreg
#elif ((__NUMBER_OF_DPTRS__ > 1) || (defined(__EXTENDED_DPTR__)))
ADD A,#-5 ; -> A = nrVreg
#else
ADD A,#-4 ; -> A = nrVreg
#endif
MOV R7,A ; R7 = Vreg counter
; Save all the virtual registers
MOV R1,#?V0
Loop: MOV A,@R1
INC R1
MOVX @R0,A
INC R0
DJNZ R7,Loop
; save DPS
#if (__NUMBER_OF_DPTRS__ > 1)
EXTERN ?DPS
MOV A,?DPS
MOVX @R0,A
INC R0
#ifdef __DPTR_SHADOWED__
SELECT_DPTR0()
#endif
#endif
MOV A,DPL
MOVX @R0,A
INC R0
MOV A,DPH
MOVX @R0,A
INC R0
#if (defined(__EXTENDED_DPTR__))
MOV A,?DPX
MOVX @R0,A
INC R0
#endif
MOV A,B
MOVX @R0,A
INC R0
MOV A,?VB
MOVX @R0,A
RET
cfi ENDBLOCK ?SMALL_INTERRUPT_ENTER_PSP
ENDMOD
;-----------------------------------------------------------------------------
;
; Function: ?INTERRUPT_ENTER_PSP
;
; Description:
; Saves register R0-R7,DPL,DPH,(DPX),B,PSW,V0,(DPS) plus a specified
; number of virtual registers on the PDATA stack.
;
; +----------+
; | R0 |
; + - - - - -+
; | R1 |
; + - - - - -+
; | R2 |
; + - - - - -+
; | R3 |
; + - - - - -+
; | V0 |
; | : |
; | Vn |
; + - - - - -+
; | ?DPS | (if nr of DPTRs > 1)
; + - - - - -+
; | DPL0 |
; + - - - - -+
; | DPH0 |
; + - - - - -+
; | DPX0 | (if extended DPTR)
; + - - - - -+
; | B |
; + - - - - -+
; | PSW |
; + - - - - -+
; | ?VB |
; + - - - - -+
; | R4 |
; + - - - - -+
; | R5 |
; + - - - - -+
; | R6 |
; + - - - - -+
; | R7 | <-- PSP
; +----------+
;
; Register input:
; A = -(#Vregs + 13/14/15)
;
; Register output:
; ?PSP = ?PSP - (-A)
; DPTR = PC
; R0 = Undefined
; A = 0
; R6 = 0
; CY = 0
;
; Multiple DPTR
; Shadowed: Requires DPTR: none Requires DPS: none
; Modifies DPTR: 0 Returns DPS: 0
;
; Separate: Requires DPTR: none Requires DPS: none
; Modifies DPTR: none Returns DPS: none
;
; Stack usage: 2
;
;-----------------------------------------------------------------------------
MODULE ?INTERRUPT_ENTER_PSP
RSEG RCODE:CODE:NOROOT
PUBLIC ?INTERRUPT_ENTER_PSP
EXTERN ?VB
EXTERN ?V0
EXTERN ?PSP
EXTERNS_FOR_ALL_DPTR_SYMBOLS()
cfi BLOCK ?INTERRUPT_ENTER_PSP Using cfi_common
cfi NOFUNCTION
cfi A Undefined
?INTERRUPT_ENTER_PSP:
PUSH PSW
PUSH B
MOV B,R0
ADD A,?PSP ; Allocate space on the stack
MOV R0,A ; R0 = PSPold - nrVreg - 11/12
XCH A,?PSP ; A = PSPold
CLR C ; Counter = end - start - 11/12
SUBB A,R0 ; -> A = nrVreg + 11/12
#if ((__NUMBER_OF_DPTRS__ > 1) && (defined(__EXTENDED_DPTR__)))
ADD A,#-15 ; -> A = nrVreg
#elif ((__NUMBER_OF_DPTRS__ > 1) || (defined(__EXTENDED_DPTR__)))
ADD A,#-14 ; -> A = nrVreg
#else
ADD A,#-13 ; -> A = nrVreg
#endif
PUSH A
; Save R0-R3
MOV A,B ; B = R0
MOVX @R0,A
INC R0
MOV A,R1
MOVX @R0,A
INC R0
MOV A,R2
MOVX @R0,A
INC R0
MOV A,R3
MOVX @R0,A
INC R0
; Save all the virtual registers
POP A
MOV R3,A
MOV R1,#?V0
Loop: MOV A,@R1
INC R1
MOVX @R0,A
INC R0
DJNZ R3,Loop
; save ?DPS
#if (__NUMBER_OF_DPTRS__ > 1)
EXTERN ?DPS
MOV A,?DPS
MOVX @R0,A
INC R0
#ifdef __DPTR_SHADOWED__
SELECT_DPTR0()
#endif
#endif
; save DPL,DPH,(DPX),B and PSW
MOV A,DPL
MOVX @R0,A
INC R0
MOV A,DPH
MOVX @R0,A
INC R0
#if (defined(__EXTENDED_DPTR__))
MOV A,?DPX
MOVX @R0,A
INC R0
#endif
POP A ; -> A = B
MOVX @R0,A
INC R0
POP A ; -> A = PSW
MOVX @R0,A
INC R0
; save ?VB
MOV A,?VB
MOVX @R0,A
INC R0
; Save R4-R7
MOV A,R4
MOVX @R0,A
INC R0
MOV A,R5
MOVX @R0,A
INC R0
MOV A,R6
MOVX @R0,A
INC R0
MOV A,R7
MOVX @R0,A
RET
cfi ENDBLOCK ?INTERRUPT_ENTER_PSP
ENDMOD
;-----------------------------------------------------------------------------
;
; Function: ?INTERRUPT_LEAVE_PSP
;
; Description:
; Restore register R0-R7,?VB,B,(?DPS),DPL,DPH,(?DPX)
; plus a specified number of virtual
; registers from the PDATA stack.
;
; Register input:
; R7 = Number of virtual registers to restore.
;
; Register output:
; R0 = ?PSP
; R6 = Restored value
; R7 = Restored value
; A = RETH
;
; Multiple DPTR
; Shadowed: Requires DPTR: none Requires DPS: none
; Modifies DPTR: 0 (restored) Returns DPS: restored
;
; Separate: Requires DPTR: none Requires DPS: none
; Modifies DPTR: 0 (restored) Returns DPS: restored
;
; Stack usage: NA
;
;-----------------------------------------------------------------------------
MODULE ?INTERRUPT_LEAVE_PSP
RSEG RCODE:CODE:NOROOT
PUBLIC ?INTERRUPT_LEAVE_PSP
EXTERN ?VB
EXTERN ?V0
EXTERN ?PSP
EXTERNS_FOR_ALL_DPTR_SYMBOLS()
cfi BLOCK ?INTERRUPT_LEAVE_PSP USING cfi_common
cfi NOFUNCTION
cfi A Undefined
?INTERRUPT_LEAVE_PSP:
MOV R0,?PSP
; restore r0-r3
MOVX A,@R0
INC R0
PUSH A ; -> R0 original to idata stack
MOVX A,@R0
INC R0
PUSH A ; -> R1 original to idata stack
MOVX A,@R0
INC R0
MOV R2,A
MOVX A,@R0
INC R0
MOV R3,A
; restore Vregs
MOV R1,#?V0
Loop: MOVX A,@R0
INC R0
MOV @R1,A
INC R1
DJNZ R7,Loop
; save ?DPS
#if (__NUMBER_OF_DPTRS__ > 1)
EXTERN ?DPS
MOVX A,@R0
MOV B,A
INC R0
#ifdef __DPTR_SHADOWED__
SELECT_DPTR0()
#endif
#endif
; restore B and PSW
MOVX A,@R0
INC R0
MOV DPL,A
MOVX A,@R0
INC R0
MOV DPH,A
#if (defined(__EXTENDED_DPTR__))
MOVX A,@R0
INC R0
MOV ?DPX,A
#endif
#if (__NUMBER_OF_DPTRS__ > 1)
MOV ?DPS,B
#endif
MOVX A,@R0
INC R0
MOV B,A
MOVX A,@R0
INC R0
MOV PSW,A
; restore ?VB och ?DPS
MOVX A,@R0
INC R0
MOV ?VB,A
; restore r4-r7
MOVX A,@R0
INC R0
MOV R4,A
MOVX A,@R0
INC R0
MOV R5,A
MOVX A,@R0
INC R0
MOV R6,A
MOVX A,@R0
INC R0
MOV R7,A
MOV ?PSP,R0
POP A
MOV R1,A
POP A
MOV R0,A
; restore register A
POP A
RETI
cfi ENDBLOCK ?INTERRUPT_LEAVE_PSP
ENDMOD
;-----------------------------------------------------------------------------
;
; Function: ?SMALL_INTERRUPT_LEAVE_PSP
;
; Description:
; Restore register ?VB,B,(?DPS),DPL,DPH,(?DPX)
; plus a specified number of virtual
; registers from the PDATA stack.
;
; Register input:
; R7 = Number of virtual registers to restore.
;
; Register output:
;
; Multiple DPTR
; Shadowed: Requires DPTR: none Requires DPS: none
; Modifies DPTR: 0 (restored) Returns DPS: restored
;
; Separate: Requires DPTR: none Requires DPS: none
; Modifies DPTR: 0 (restored) Returns DPS: restored
;
; Stack usage: NA
;
;-----------------------------------------------------------------------------
MODULE ?SMALL_INTERRUPT_LEAVE_PSP
RSEG RCODE:CODE:NOROOT
PUBLIC ?SMALL_INTERRUPT_LEAVE_PSP
EXTERN ?VB
EXTERN ?V0
EXTERN ?PSP
EXTERNS_FOR_ALL_DPTR_SYMBOLS()
cfi BLOCK ?SMALL_INTERRUPT_LEAVE_PSP USING cfi_common
cfi NOFUNCTION
cfi A Undefined
?SMALL_INTERRUPT_LEAVE_PSP:
MOV R0,?PSP
; restore Vregs
MOV R1,#?V0
Loop: MOVX A,@R0
INC R0
MOV @R1,A
INC R1
DJNZ R7,Loop
; restore ?DPS
#if (__NUMBER_OF_DPTRS__ > 1)
EXTERN ?DPS
MOVX A,@R0
MOV B,A
INC R0
#ifdef __DPTR_SHADOWED__
SELECT_DPTR0()
#endif
#endif
; restore DPL,DPH,(DPX),B
MOVX A,@R0
INC R0
MOV DPL,A
MOVX A,@R0
INC R0
MOV DPH,A
#if (defined(__EXTENDED_DPTR__))
MOVX A,@R0
INC R0
MOV ?DPX,A
#endif
#if (__NUMBER_OF_DPTRS__ > 1)
MOV ?DPS,B
#endif
MOVX A,@R0
INC R0
MOV B,A
; restore ?VB och ?DPS
MOVX A,@R0
INC R0
MOV ?VB,A
MOV ?PSP,R0
; restore PSW and reg A
POP PSW
POP A
RETI
cfi ENDBLOCK ?SMALL_INTERRUPT_LEAVE_PSP
ENDMOD
;-----------------------------------------------------------------------------
;
; Function: ?INTERRUPT_ENTER_XSP
;
; Description:
; Saves register R0-R7,(DPX),DPH,DPL,PSW,VB,B,(DPS)
; plus a specified number of virtual
; registers on the XDATA stack.
;
; +----------+
; | R0 |
; + - - - - -+
; | R1 |
; + - - - - -+
; | R2 |
; + - - - - -+
; | R3 |
; + - - - - -+
; | V0 |
; | : |
; | Vn |
; + - - - - -+
; | R4 |
; + - - - - -+
; | R5 |
; + - - - - -+
; | R6 |
; + - - - - -+
; | R7 |
; + - - - - -+
; | DPX0 | (if extended DPTR)
; + - - - - -+
; | DPH0 |
; + - - - - -+
; | DPL0 |
; + - - - - -+
; | PSW |
; + - - - - -+
; | ?VB |
; + - - - - -+
; | B |
; + - - - - -+
; | ?DPS | <-- XSP (if nr of DPTRs > 1)
; +----------+
;
; Register input:
; A -(The number of bytes to push + 13/14/15).
;
; Register output:
;
; Multiple DPTR
; Shadowed: Requires DPTR: none Requires DPS: none
; Modifies DPTR: 0 Returns DPS: 0
;
; Separate: Requires DPTR: none Requires DPS: none
; Modifies DPTR: 0 Returns DPS: 0
;
; Stack usage peak : 5
; Stack usage after return: -2
;
;-----------------------------------------------------------------------------
MODULE ?INTERRUPT_ENTER_XSP
RSEG XSTACK:NOROOT:XDATA
RSEG RCODE:CODE:NOROOT
PUBLIC ?INTERRUPT_ENTER_XSP
EXTERN ?V0
EXTERN ?VB
EXTERN ?XSP
EXTERNS_FOR_ALL_DPTR_SYMBOLS()
cfi BLOCK ?INTERRUPT_ENTER_XSP Using cfi_common
cfi NOFUNCTION
cfi A Undefined
?INTERRUPT_ENTER_XSP:
#if (__NUMBER_OF_DPTRS__ > 1)
EXTERN ?DPS
PUSH ?DPS
SELECT_DPTR0()
#endif
PUSH PSW
ADD A,XSP_L
XCH A,DPL
PUSH A
MOV A,XSP_H
ADDC A,#255
XCH A,DPH
PUSH A
#if ( defined(__EXTENDED_DPTR__))
PUSH ?DPX
MOV ?DPX,#BYTE3(sfb(XSTACK))
#endif
MOV A,XSP_L
CLR C
SUBB A,DPL
#if ((defined(__EXTENDED_DPTR__)) && (__NUMBER_OF_DPTRS__ == 1))
ADD A,#-14 ; ext1, one dptr
#elif (defined(__EXTENDED_DPTR__))
ADD A,#-15 ; ext1, two dptr
#elif (__NUMBER_OF_DPTRS__ == 1)
ADD A,#-13 ; plain, one dptr
#else
ADD A,#-14 ; plain, two dptr
#endif
;; Disable interrupts for max 6 cycles
JBC 0xA8.7 /* IE.EA */,interrupts_disabled
MOV XSP_H,DPH
MOV XSP_L,DPL
SJMP finished
i
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?