iar_stack_enter_leave.s51

来自「8051试验程序 基础教材」· S51 代码 · 共 2,959 行 · 第 1/5 页

S51
2,959
字号
;          | Ret_cc_H |
;          + - - - - -+
;          | Ret_cc_L |
;          + - - - - -+
;          |    R7    |
;          + - - - - -+
;          |    Vn    |
;          + - - - - -+
;           :    :   :
;          + - - - - -+
;          |    V1    |
;          + - - - - -+
;          |    V0    |
;          + - - - - -+
;          |    VB    |
;          + - - - - -+
;   CFA--> |    R6    | <-- ?PSP end
;          +----------+
;               :
;               00
;
;	Register input:
;		A      = -(Number of bytes to save)
;
;	Register output:
;		?PSP   = ?PSP - (-A)
;		DPTR0  = 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: 0        Returns  DPS: 0
;
;	Stack usage: 2
;
;-----------------------------------------------------------------------------
enter_PSP MACRO retType
	MODULE	?\1_ENTER_PDATA
	RSEG	RCODE:CODE:NOROOT	
	PUBLIC	?\1_ENTER_PDATA
	EXTERN  ?VB
	EXTERN  ?V0
	EXTERN	?PSP
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()

    cfi BLOCK ?\1_ENTER_PDATA Using cfi_pdata_enter_common
    cfi NOFUNCTION
    cfi A     Undefined
    cfi CFA_SPP sub(SPP,sub(256,A))

?\1_ENTER_PDATA:
?\1_ENTER_PDATA_CFI_INVALID_BEGINS:
    cfi invalid
#if (__NUMBER_OF_DPTRS__ > 1)
	SELECT_DPTR0()
#endif ; __NUMBER_OF_DPTRS__

#if (__CORE__ == __CORE_EXTENDED1__)
	POP	?DPX
#elif defined(__EXTENDED_DPTR__)
	MOV	?DPX,#0
#endif
	POP	DPH		; Remove the library function return address
    cfi CFA_MACHINE MACHINE_SP - 3
    cfi ?RET_HIGH DPH0
	POP	DPL
    cfi CFA_MACHINE MACHINE_SP - 2
    cfi ?RET_LOW DPL0

	ADD	A,?PSP	        ; Allocate space on the stack
    cfi CFA_SPP A
	MOV	R0,A		; R0 = Start of the save area
	XCH	A,?PSP	        ; Save the new value of SP and get the old one
    cfi CFA_SPP SPP
    cfi Base    add(R0,sub(256,A))

	CLR	C		; Counter = end - start - 5
	SUBB	A,R0

	IF      '\1'='BANKED'
	ADD	A,#-6
	ELSE
#if (__CODE_MODEL__ == __CM_FAR__)
	ADD	A,#-6
#else
	ADD	A,#-5
#endif
	ENDIF

	XCH	A,R6		; R6 = counter
	MOVX	@R0,A		; R6 ==> PStack.
	INC	R0

        MOV     A,?VB
	MOVX	@R0,A           ; VB ==> PStack.
	INC	R0

	MOV	A,R1
	PUSH	A
    cfi CFA_MACHINE MACHINE_SP - 3

	MOV	R1,#?V0
Loop:	MOV	A,@R1		; Vn ==> PStack.
	INC	R1
	MOVX	@R0,A
	INC	R0
	DJNZ	R6,Loop

	POP	A
    cfi CFA_MACHINE MACHINE_SP - 2
	MOV	R1,A

	MOV	A,R7
	MOVX	@R0,A           ; R7 == > PStack.
	INC	R0
	
;=======================================;
; Move the function return address from ;
; the IDATA stack to the PDATA stack.	;
;=======================================;
	IF      '\1'='BANKED'
	POP	A
    cfi CFA_MACHINE MACHINE_SP - 2
	MOV	R7,A
	ELSE
#if (__CODE_MODEL__ == __CM_FAR__)
	POP	A
    cfi CFA_MACHINE MACHINE_SP -2
	MOV	R7,A
#endif
	ENDIF
	POP	A
    cfi CFA_MACHINE MACHINE_SP - 1
	MOV	R6,A
	POP	A
    cfi CFA_MACHINE MACHINE_SP
	
	MOVX	@R0,A           ; RetL_cc ==> PStack.
	INC	R0
	MOV	A,R6
	MOVX	@R0,A           ; RetH_cc ==> PStack.
	INC	R0

	IF      '\1'='BANKED'
	MOV	A,R7
	MOVX	@R0,A           ; RetE_cc ==> PStack.
	INC	R0
	ELSE
#if (__CODE_MODEL__ == __CM_FAR__)
	MOV	A,R7
	MOVX	@R0,A           ; RetE_cc ==> PStack.
	INC	R0
#endif
	ENDIF
	CLR	A
	JMP	@A+DPTR
    cfi valid
?\1_ENTER_PDATA_CFI_INVALID_ENDS:
    cfi ENDBLOCK ?\1_ENTER_PDATA
	ENDMOD
	ENDM

	enter_PSP BANKED
	enter_PSP FUNC

;-----------------------------------------------------------------------------
;
;	Function: ?FUNC_LEAVE_PDATA
;
;	Description:
;		Restore register R6 and R7 plus a specified number of virtual
;		registers from the PDATA stack.
;
;		+----------+
;               | Ret_cc_E |
;               + - - - - -+
;               | Ret_cc_H |
;               + - - - - -+
;               | Ret_cc_L |
;               + - - - - -+
;		|    R7    |
;		+ - - - - -+
;		|    VR    |
;		+ - - - - -+
;		|    VB    |
;		+ - - - - -+
;		|    R6    |
;		+ - - - - -+
;		|          | <-- ?PSP
;		+----------+
;
;	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: none     Returns  DPS: 0
;
;               Separate:       Requires DPTR: none     Requires DPS: none
;                               Modifies DPTR: none     Returns  DPS: 0
;	Stack usage: NA
;
;-----------------------------------------------------------------------------
leave_PSP MACRO retType

	MODULE	?\1_LEAVE_PDATA
	RSEG	RCODE:CODE:NOROOT	
	PUBLIC	?\1_LEAVE_PDATA
	EXTERN  ?VB	
	EXTERN	?V0
	EXTERN	?PSP
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()
	IF      '\1'='BANKED'
	EXTERN	?BRET
	ENDIF

    cfi BLOCK ?\1_LEAVE_PDATA USING cfi_common
    cfi NOFUNCTION
    cfi A     Undefined
?\1_LEAVE_PDATA:
?\1_LEAVE_PDATA_CFI_INVALID_BEGINS:
    cfi invalid
	MOV	R0,?PSP

;=======================================;
;       Restore the R6 register.	;
;=======================================;
	MOVX	A,@R0
	MOV	R6,A
	INC	R0

;=======================================;
;   Restore VB register.                ;
;=======================================;
	MOVX	A,@R0
	INC	R0
	MOV	?VB,A

;=======================================;
;       Preserve the R1 register.	;
;=======================================;
	MOV	A,R1		; Save R1, used as tmp
	PUSH 	A
    cfi CFA_MACHINE MACHINE_SP - 3
	

;=======================================;
;   Restore all the virtual registers.	;
;=======================================;
	MOV	R1,#?V0    ; R0 now points at the first virtual register to restore.
Loop:	MOVX	A,@R0
	INC	R0
	MOV	@R1,A
	INC	R1
	DJNZ	R7,Loop

;=======================================;
;       Restore the R7 register.	;
;=======================================;
	MOVX	A,@R0
	INC	R0
	MOV	R7,A

;=======================================;
;       Restore the R1 register.	;
;=======================================;
	POP	A
    cfi CFA_MACHINE MACHINE_SP - 0
	MOV	R1,A

;=======================================;
; Restore the function return address.	;
;=======================================;
	MOVX	A,@R0
	INC	R0
	PUSH 	A               ; RET_L ==> Machine stack.
    cfi CFA_MACHINE MACHINE_SP - 1
	MOVX	A,@R0
	INC	R0
	PUSH	A               ; RET_H ==> Machine stack.
    cfi CFA_MACHINE MACHINE_SP - 2

	IF      '\1'='BANKED'
	MOVX	A,@R0
	INC	R0
	PUSH	A               ; RET_E ==> Machine stack.
    cfi CFA_MACHINE MACHINE_SP - 2
	ELSE
#if ( (__CODE_MODEL__ == __CM_FAR__))
	MOVX	A,@R0
	INC	R0
	PUSH	A               ; RET_E ==> Machine stack.
    cfi CFA_MACHINE MACHINE_SP - 2
#endif
	ENDIF
	MOV	?PSP,R0

#if  (__NUMBER_OF_DPTRS__ > 1)
	SELECT_DPTR0()
#endif

	IF      '\1'='BANKED'
	LJMP	?BRET
	ELSE
	RET
	ENDIF

?\1_LEAVE_PDATA_CFI_INVALID_ENDS:
    cfi invalid

    cfi ENDBLOCK ?\1_LEAVE_PDATA
	ENDMOD

        ENDM


	leave_PSP BANKED
	leave_PSP FUNC

;-----------------------------------------------------------------------------
;
;	Function: ?FUNC_ENTER_XDATA
;
;	Description:
;		Saves register R6,R7,(DPX),DPH,DPL,VB,(RETX)RETH,RETL
;		plus a specified number of virtual
;		registers on the XDATA stack.
;
;               +----------+
;               |  ?DPX (if extended dptr)   |
;               + - - - - -+
;               |   DPH    |
;               + - - - - -+
;               |   DPL    |
;               + - - - - -+
;               | Ret_cc_E (if banked of far)|
;               + - - - - -+
;               | Ret_cc_H |
;               + - - - - -+
;               | Ret_cc_L |
;               + - - - - -+
;		|    R7    |
;		+ - - - - -+
;		|    VR    |
;		+ - - - - -+
;		|    VB    |
;		+ - - - - -+
;		|    R6    | <-- XSP
;		+----------+
;
;
;	Register input:
;		A  -(The number of bytes to push + 7/8).
;
;	Register output:
;		DPTR0  = XSTACK - 1
;		XSTACK = XSTACK - (-A)
;		R0     = R0 + (-A) - 2
;		A      = R7
;		R6     = Is undefined
;		CY     = 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 peak	:  5
;	Stack usage after return: -2
;
;-----------------------------------------------------------------------------
enter_XSP MACRO retType
	MODULE	?\1_ENTER_XDATA
	RSEG	XSTACK:NOROOT:XDATA
	RSEG	RCODE:CODE:NOROOT
	PUBLIC	?\1_ENTER_XDATA
	EXTERN  ?V0
	EXTERN  ?VB
	EXTERN	?XSP
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()

    cfi BLOCK ?\1_ENTER_XDATA Using cfi_common
    cfi NOFUNCTION
    cfi A     Undefined
?\1_ENTER_XDATA:
?\1_ENTER_XDATA_CFI_INVALID_BEGINS:
    cfi invalid
#if (__NUMBER_OF_DPTRS__ > 1)
	SELECT_DPTR0()
#endif ; __NUMBER_OF_DPTRS__

	ADD	A,XSP_L
	XCH	A,DPL
	PUSH	A
    cfi CFA_MACHINE MACHINE_SP - 5
	MOV	A,XSP_H
	ADDC	A,#255
	XCH	A,DPH
	PUSH	A
#ifdef __EXTENDED_DPTR__
	PUSH	?DPX
	MOV	?DPX,#BYTE3(SFB(XSTACK))
#endif
    cfi CFA_MACHINE MACHINE_SP - 6
	MOV	A,XSP_L
	CLR	C
	SUBB	A,DPL

	IF      '\1'='BANKED'
#if (defined (__EXTENDED_DPTR__))
	ADD	A,#-9
#else
	ADD	A,#-8
#endif
	ELSE
#if ((__CODE_MODEL__ == __CM_FAR__) && (defined (__EXTENDED_DPTR__)))
	ADD	A,#-9
#elif (defined (__EXTENDED_DPTR__))
	ADD	A,#-8
#else
	ADD	A,#-7
#endif
	ENDIF

	MOV	R0,A
	CLR	A
	;; Preserve the Interrupt Enable register
	;; Disable interrupts, max 6 cycles 	
	XCH	A,0xA8 /* IE */
	MOV	XSP_H,DPH
	MOV	XSP_L,DPL
	;; Restore interrupts	
	XCH	A,0xA8 /* IE */
	MOV	A,R0

;=======================================;
;  Preserve the R6 register.		;
;=======================================;
	XCH	A,R6		; R6 = Number of virtual registers to push
	MOVX	@DPTR,A
	INC	DPTR

;=======================================;
;    Move all the virtual registers	;
;    in IDATA to the XDATA stack.	;
;=======================================;
        MOV     A,?VB
	MOVX	@DPTR,A
	INC  	DPTR

	MOV	R0,#?V0
Loop:	MOV	A,@R0
	INC	R0
	MOVX	@DPTR,A
	INC	DPTR
	DJNZ	R6,Loop

;=======================================;
;       Preserve the R7 register.	;
;=======================================;
	MOV	A,R7
	MOVX	@DPTR,A
	INC	DPTR

;=======================================;
; Move the function return address from ;
; the IDATA stack to the XDATA stack.	;
;
;   IDATA stack
;
;  +----------+
;  |  ?DPX (if extended dptr)    | <-- SP
;  |   DPH    |
;  |   DPL    |
;  + - - - - -+
;  | Ret_lib_E (if far)|
;  | Ret_lib_H|
;  | Ret_lib_L|
;  + - - - - -+
;  | Ret_cc_E (if banked or far)|
;  | Ret_cc_H |
;  | Ret_cc_L | <-- R0
;  +----------+
;
; offset = 5
; if (CM = far) offest += 2
; else if (CM = banked) offset +=1
; if (extended_dptr) offset += 1
;
;
;=======================================;


	MOV	A,SP

	IF      '\1'='BANKED'
#if (defined (__EXTENDED_DPTR__))
	ADD	A,#-7
#else
	ADD	A,#-6
#endif
	ELSE
#if (__CODE_MODEL__ == __CM_FAR__)
  #if (defined (__EXTENDED_DPTR__))
	ADD	A,#-8
  #else
	ADD	A,#-7
  #endif
#else
  #if (defined (__EXTENDED_DPTR__))
	ADD	A,#-6
  #else
	ADD	A,#-5
  #endif
#endif
	ENDIF

	MOV	R0,A

	MOV	A,@R0
	INC	R0
	MOVX	@DPTR,A    ; Ret_cc_L ==> XStack
	INC	DPTR

	MOV	A,@R0
	INC	R0
	MOVX	@DPTR,A    ; Ret_cc_H ==> XStack
	INC	DPTR

	IF      '\1'='BANKED'
	MOV	A,@R0
	INC	R0
	MOVX	@DPTR,A    ; Ret_cc_E ==> XStack
	INC	DPTR
	ELSE
#if ((__CODE_MODEL__ == __CM_FAR__))
	MOV	A,@R0
	INC	R0
	MOVX	@DPTR,A    ; Ret_cc_E ==> XStack
	INC	DPTR
#endif
	ENDIF

	INC	R0
	INC	R0
#if (__CODE_MODEL__ == __CM_FAR__)
	INC	R0
#endif

	MOV	A,@R0
	INC	R0
	MOVX	@DPTR,A    ; DPL ==> XStack
	INC	DPTR

	MOV	A,@R0
	INC	R0
	MOVX	@DPTR,A    ; DPH ==> XStack
	INC	DPTR

#if (defined(__EXTENDED_DPTR__))
	MOV	A,@R0
	INC	R0
	MOVX	@DPTR,A    ; ?DPX ==> XStack
	INC	DPTR
#endif

#if (defined(__EXTENDED_DPTR__))
	DEC	SP
#endif
	DEC	SP
	DEC	SP

#if ( __CODE_MODEL__ == __CM_FAR__ )
	POP	A
	MOV	R7,A
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?