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 + -
显示快捷键?