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