iar_stack_enter_leave.s51
来自「8051试验程序 基础教材」· S51 代码 · 共 2,959 行 · 第 1/5 页
S51
2,959 行
POP A
MOV R6,A
POP A
MOV R0,A
IF '\1'='BANKED'
DEC SP
ELSE
#if ((__CODE_MODEL__ == __CM_FAR__))
DEC SP
#endif
ENDIF
DEC SP
DEC SP
MOV A,R0
PUSH A
MOV A,R6
PUSH A
#if ( __CODE_MODEL__ == __CM_FAR__ )
MOV A,R7
PUSH A
#endif
RET
?\1_ENTER_XDATA_CFI_INVALID_ENDS:
cfi valid
cfi ENDBLOCK ?\1_ENTER_XDATA
ENDMOD
ENDM
enter_XSP BANKED
enter_XSP FUNC
;-----------------------------------------------------------------------------
;
; Function: ?FUNC_LEAVE_XDATA
;
; Description:
; Restore register R6 and R7 plus a specified number of virtual
; registers from the machine stack.
;
; +----------+
; | ?DPX (if extended dptr) |
; + - - - - -+
; | DPH |
; + - - - - -+
; | DPL |
; + - - - - -+
; | Ret_cc_E (if banked or far) |
; + - - - - -+
; | Ret_cc_H |
; + - - - - -+
; | Ret_cc_L |
; + - - - - -+
; | R7 |
; + - - - - -+
; | VR |
; + - - - - -+
; | VB |
; + - - - - -+
; | R6 |
; + - - - - -+
; | | <-- XSP
; +----------+
;
;
; Register input:
; R7 Number of vitrual registers to restore
;
; Register output:
; R0 = Undefined
; DPTR = Restored value
; R6 = Restored value
; R7 = Restored value
; A = Undefined
; B = Undefined
;
; 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: 2
;
;-----------------------------------------------------------------------------
leave_XSP MACRO retType
MODULE ?\1_LEAVE_XDATA
RSEG XSTACK:NOROOT:XDATA
RSEG RCODE:CODE:NOROOT
PUBLIC ?\1_LEAVE_XDATA
EXTERN ?VB
EXTERN ?V0
EXTERN ?XSP
;#if ((__CODE_MODEL__ == __CM_BANKED_EXT2__))
EXTERN ?RET_EXT2
;#endif
IF '\1'='BANKED'
EXTERN ?BRET
ENDIF
EXTERNS_FOR_ALL_DPTR_SYMBOLS()
cfi BLOCK ?\1_LEAVE_XDATA USING cfi_common
cfi NOFUNCTION
cfi A Undefined
?\1_LEAVE_XDATA:
?\1_LEAVE_XDATA_CFI_INVALID_BEGINS:
cfi invalid
#if (__NUMBER_OF_DPTRS__ > 1)
SELECT_DPTR0()
#endif ; __NUMBER_OF_DPTRS__
MOV DPH,XSP_H
MOV DPL,XSP_L
#ifdef __EXTENDED_DPTR__
MOV ?DPX,#BYTE3(sfb(XSTACK))
#endif
;=======================================;
; Restore the R6 register. ;
;=======================================;
MOVX A,@DPTR
INC DPTR
MOV R6,A
;=======================================;
; Restore VB register. ;
;=======================================;
MOVX A,@DPTR
INC DPTR
MOV ?VB,A
;=======================================;
; Restore all the virtual registers. ;
;=======================================;
MOV R0,#?V0
Loop: MOVX A,@DPTR
INC DPTR
MOV @R0,A
INC R0
DJNZ R7,Loop
;=======================================;
; Restore the R7 register. ;
;=======================================;
MOVX A,@DPTR
INC DPTR
MOV R7,A
;===========================================;
; Prepare IStack with Return address. ;
;===========================================;
MOVX A,@DPTR
INC DPTR
PUSH A ; Ret_cc_L ==> IStack
MOVX A,@DPTR
INC DPTR
PUSH A ; Ret_cc_H ==> IStack
IF '\1'='BANKED'
MOVX A,@DPTR
INC DPTR
PUSH A ; Ret_cc_E ==> IStack
ELSE
#if ( (__CODE_MODEL__ == __CM_FAR__))
MOVX A,@DPTR
INC DPTR
PUSH A ; Ret_cc_E ==> IStack
#endif
ENDIF
;=======================================;
; Prepare IStack with old DPTR. ;
;=======================================;
MOVX A,@DPTR
INC DPTR
PUSH A ; old_DPL ==> IStack
MOVX A,@DPTR
INC DPTR
PUSH A ; old_DPH ==> IStack
#if (defined (__EXTENDED_DPTR__) )
MOVX A,@DPTR
INC DPTR
PUSH A ; old_?DPX ==> IStack
#endif
;=======================================;
; Dealloc XSP. ;
;=======================================;
CLR A
;; Preserve the Interrupt Enable register
;; Disable interrupts, max 6 cycles
XCH A,0xA8 /* IE */
MOV XSP_L,DPL
MOV XSP_H,DPH
;; Restore interrupts
XCH A,0xA8 /* IE */
;=======================================;
; Restore DPTR register. ;
;=======================================;
#if (defined (__EXTENDED_DPTR__) )
POP ?DPX
#endif
POP DPH
cfi CFA_MACHINE MACHINE_SP - 0
POP DPL
cfi CFA_MACHINE MACHINE_SP - 0
#if (__NUMBER_OF_DPTRS__ > 1)
SELECT_DPTR0()
#endif
IF '\1'='BANKED'
LJMP ?BRET
ELSE
RET
ENDIF
?\1_LEAVE_XDATA_CFI_INVALID_ENDS:
cfi valid
cfi ENDBLOCK ?\1_LEAVE_XDATA
ENDMOD
ENDM
leave_XSP BANKED
leave_XSP FUNC
;-----------------------------------------------------------------------------
;
; Function: ?INTERRUPT_ENTER_OVERLAY
;
; Description:
; Saves register R1-R7,PSW,DPL,DPH,(DPX),B,VB,(DPSEL)
; plus a specified number of virtual
; registers on the machine stack.
;
; Register input:
; R0 Points to parameter (PRM) area, where to save registers.
; A The number of Virtual regs to push.
;
; Register output:
; A = restored value
; R0 = restored value
;
; Multiple DPTR
; Shadowed: Requires DPTR: none Requires DPS: none
; Modifies DPTR: none Returns DPS: 0
;
; Separate: Requires DPTR: none Requires DPS: none
; Modifies DPTR: none Returns DPS: none
;
; Stack usage: NA
;
;-----------------------------------------------------------------------------
MODULE ?INTERRUPT_ENTER_OVERLAY
RSEG RCODE:CODE:NOROOT
PUBLIC ?INTERRUPT_ENTER_OVERLAY
EXTERN ?V0
EXTERN ?VB
EXTERNS_FOR_ALL_DPTR_SYMBOLS()
cfi BLOCK ?INTERRUPT_ENTER_OVERLAY Using cfi_common
cfi NOFUNCTION
cfi A Undefined
?INTERRUPT_ENTER_OVERLAY:
; save R1-R7
XCH A,R7 ; -> R7 = number of Vregs to save
MOV @R0,A
INC R0
MOV A,R6
MOV @R0,A
INC R0
MOV A,R5
MOV @R0,A
INC R0
MOV A,R4
MOV @R0,A
INC R0
MOV A,R3
MOV @R0,A
INC R0
MOV A,R2
MOV @R0,A
INC R0
MOV A,R1
MOV @R0,A
INC R0
; save reg PSW
MOV @R0,PSW
INC R0
;save reg DPL,DPH,B,VB,(DPSEL)
#if (__NUMBER_OF_DPTRS__ > 1)
MOV @R0,?DPS
INC R0
#ifdef __DPTR_SHADOWED__
SELECT_DPTR0()
#endif
#endif
MOV @R0,DPL
INC R0
MOV @R0,DPH
INC R0
#if (defined (__EXTENDED_DPTR__) )
MOV @R0,?DPX
INC R0
#endif
MOV @R0,B
INC R0
MOV @R0,?VB
INC R0
; save virtual registers
MOV R1,#?V0
Loop:
MOV A,@R1
MOV @R0,A
INC R0
INC R1
DJNZ R7,Loop
RET
cfi ENDBLOCK ?INTERRUPT_ENTER_OVERLAY
ENDMOD
;-----------------------------------------------------------------------------
;
; Function: ?SMALL_INTERRUPT_ENTER_OVERLAY
;
; Description:
; Saves register DPL,DPH,(DPX),B,VB,(DPSEL)
; plus a specified number of virtual
; registers on the machine stack.
;
; Register input:
; R0 Points to parameter (PRM) area, where to save registers.
; R7 The number of Virtual regs to push.
;
; Register output:
; A = restored value
; R7 = restored value
;
; Multiple DPTR
; Shadowed: Requires DPTR: none Requires DPS: none
; Modifies DPTR: none Returns DPS: 0
;
; Separate: Requires DPTR: none Requires DPS: none
; Modifies DPTR: none Returns DPS: none
;
; Stack usage: NA
;
;-----------------------------------------------------------------------------
MODULE ?SMALL_INTERRUPT_ENTER_OVERLAY
RSEG RCODE:CODE:NOROOT
PUBLIC ?SMALL_INTERRUPT_ENTER_OVERLAY
EXTERN ?V0
EXTERN ?VB
EXTERNS_FOR_ALL_DPTR_SYMBOLS()
cfi BLOCK ?SMALL_INTERRUPT_ENTER_OVERLAY Using cfi_common
cfi NOFUNCTION
cfi A Undefined
?SMALL_INTERRUPT_ENTER_OVERLAY:
;save reg DPL, DPH, B,VB,(DPSEL)
#if (__NUMBER_OF_DPTRS__ > 1)
MOV @R0,?DPS
INC R0
#ifdef __DPTR_SHADOWED__
SELECT_DPTR0()
#endif
#endif
MOV @R0,DPL
INC R0
MOV @R0,DPH
INC R0
#if (defined (__EXTENDED_DPTR__) )
MOV @R0,?DPX
INC R0
#endif
MOV @R0,B
INC R0
MOV @R0,?VB
INC R0
; save virtual registers
MOV R1,#?V0
Loop:
MOV A,@R1
MOV @R0,A
INC R0
INC R1
DJNZ R7,Loop
RET
cfi ENDBLOCK ?SMALL_INTERRUPT_ENTER_OVERLAY
ENDMOD
;-----------------------------------------------------------------------------
;
; Function: ?INTERRUPT_LEAVE_OVERLAY
;
; Description:
; Restore register R1-R7,PSW,DPL,DPH,(DPX),B,VB,(DPSEL)
; plus a specified
; number of virtual registers on the machine stack.
;
; Register input:
; R0 Points to parameter (PRM) area, from where to restore registers.
; R7 The number of Virtual regs to push.
;
; Register output:
; A = undefined.
; R7 = restored value.
; R0 Is undefined.
;
; 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_OVERLAY
RSEG RCODE:CODE:NOROOT
PUBLIC ?INTERRUPT_LEAVE_OVERLAY
EXTERN ?V0
EXTERN ?VB
EXTERNS_FOR_ALL_DPTR_SYMBOLS()
cfi BLOCK ?INTERRUPT_LEAVE_OVERLAY Using cfi_common
cfi NOFUNCTION
cfi A Undefined
?INTERRUPT_LEAVE_OVERLAY:
; restore R1-r7
MOV A,@R0
PUSH A ; R7 (restored)-> idata stack
INC R0
MOV A,@R0
MOV R6,A
INC R0
MOV A,@R0
MOV R5,A
INC R0
MOV A,@R0
MOV R4,A
INC R0
MOV A,@R0
MOV R3,A
INC R0
MOV A,@R0
MOV R2,A
INC R0
MOV A,@R0
PUSH A ; R1 (restored) -> idata stack
INC R0
; restore PSW
MOV PSW,@R0
INC R0
; restore B,VB,(DPSEL)
#if (__NUMBER_OF_DPTRS__ > 1)
MOV ?VB,@R0 ; save ?DPS resore value in ?VB
INC R0
#ifdef __DPTR_SHADOWED__
SELECT_DPTR0()
#endif
#endif
MOV DPL,@R0
INC R0
MOV DPH,@R0
INC R0
#if (defined (__EXTENDED_DPTR__) )
MOV ?DPX,@R0
INC R0
#endif
MOV B,@R0
INC R0
#if (__NUMBER_OF_DPTRS__ > 1)
MOV ?DPS,?VB
#endif
MOV ?VB,@R0
INC R0
; restore virtual register
MOV R1,#?V0
Loop:
MOV A,@R0
MOV @R1,A
INC R1
INC R0
DJNZ R7,Loop
; restore R1 and R7
POP A
MOV R1,A
POP A
MOV R7,A
; restore R0, A
POP A
MOV R0,A
POP A
RETI
cfi ENDBLOCK ?INTERRUPT_LEAVE_OVERLAY
ENDMOD
;-----------------------------------------------------------------------------
;
; Function: ?SMALL_INTERRUPT_LEAVE_OVERLAY
;
; Description:
; Restore register DPL,DPH,(DPX),B,VB,(DPS) plus a specified
; number of virtual registers on the machine stack.
;
; Register input:
; R0 Points to parameter (PRM) area, from where to restore registers.
; R7 The number of Virtual regs to push.
;
; Register output:
; A = undefined.
; R7 = restored value.
; R0 Is undefined.
;
; 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_OVERLAY
RSEG RCODE:CODE:NOROOT
PUBLIC ?SMALL_INTERRUPT_LEAVE_OVERLAY
EXTERN ?V0
EXTERN ?VB
EXTERNS_FOR_ALL_DPTR_SYMBOLS()
cfi BLOCK ?SMALL_INTERRUPT_LEAVE_OVERLAY Using cfi_common
cfi NOFUNCTION
cfi A Undefined
?SMALL_INTERRUPT_LEAVE_OVERLAY:
; restore DPL, DPH,B,VB,(DPS)
#if (__NUMBER_OF_DPTRS__ > 1)
MOV ?VB,@R0 ; save ?DPS resore value in ?VB
INC R0
#ifdef __DPTR_SHADOWED__
SELECT_DPTR0()
#endif
#endif
MOV DPL,@R0
INC R0
MOV DPH,@R0
INC R0
#if (defined (__EXTENDED_DPTR__) )
MOV ?DPX,@R0
INC R0
#endif
MOV B,@R0
INC R0
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?