iar_stack_enter_leave.s51

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

S51
2,959
字号
#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 A, PSW
	POP	A
	POP	PSW

	RETI

    cfi ENDBLOCK ?SMALL_INTERRUPT_LEAVE_OVERLAY
	ENDMOD


;-----------------------------------------------------------------------------
;
;	Function: ?INTERRUPT_ENTER_SP
;
;	Description:
;		Saves register PSW, B, VB, DPL, DPH, (DPX), DPS, R0-R7 plus
;		a specified number of virtual registers on
;		the machine stack.
;
;               +----------+
;		|    Vn    | <-- SP
;		|    :     |
;		|    V0    |
;		+ - - - - -+
;		|    ?VB   |
;		+ - - - - -+
;		|    B     |
;		+ - - - - -+
;		|    PSW   |
;               + - - - - -+
;               |    R7    |
;               + - - - - -+
;               |    R6    |
;               + - - - - -+
;		|    R5    |
;		+ - - - - -+
;		|    R4    |
;		+ - - - - -+
;		|    R3    |
;		+ - - - - -+
;		|    R2    |
;		+ - - - - -+
;               |    R1    |
;               + - - - - -+
;               |    R0    |
;               + - - - - -+
;               |   ?DPX   | (if extended dptr and NOT far code model)
;               + - - - - -+
;               |   ?DPS   | (if nr of DPTRs > 1)
;               + - - - - -+
;               |   ?DPX   | (if far code model)
;               + - - - - -+
;               |   DPH    |
;               + - - - - -+
;               |   DPL    |
;		+----------+
;
;	Register input:
;		A  = Number of virtual registers to save.
;
;	Register output:
;		SP = SP+(A+12)
;		A  = Undefined
;		R1 = Undefined
;		R0 = Undefined.
;		DPTR0 Is the return address from this function.
;
;       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: NA
;
;-----------------------------------------------------------------------------
	MODULE	?INTERRUPT_ENTER_SP
	RSEG	RCODE:CODE:NOROOT
	PUBLIC	?INTERRUPT_ENTER_SP
	EXTERN  ?VB
	EXTERN  ?V0
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()

    cfi BLOCK ?INTERRUPT_ENTER_SP Using cfi_common
    cfi NOFUNCTION
    cfi A     Undefined

?INTERRUPT_ENTER_SP:
#if (__NUMBER_OF_DPTRS__ > 1)
	EXTERN	?DPS
	PUSH	?DPS
	SELECT_DPTR0()
#endif

#if defined(__EXTENDED_DPTR__)
#if (__CODE_MODEL__ != __CM_FAR__)
	PUSH	?DPX
	MOV	?DPX,#0
#endif
#endif

	; save R0-R1
	XCH	A,R0	; loop count in R0
	PUSH	A
	MOV	A,R1
	PUSH	A

	; exchange DPTR and return address located on stack
	MOV	R1,SP
	DEC	R1
	DEC	R1
#if defined(__EXTENDED_DPTR__)
#if (__CODE_MODEL__ != __CM_FAR__)
	DEC	R1
#endif
#endif

#if (__NUMBER_OF_DPTRS__ > 1)
        DEC     R1
#endif

#if (__CODE_MODEL__ == __CM_FAR__)
	MOV	A,?DPX
	XCH	A,@R1
	MOV	?DPX,A
	DEC	R1
#endif

	MOV	A,DPH
	XCH	A,@R1
	MOV	DPH,A
	DEC	R1
	MOV	A,DPL
	XCH	A,@R1
	MOV	DPL,A

	; save R1-R7
	MOV	A,R2
	PUSH	A
	MOV	A,R3
	PUSH	A
	MOV	A,R4
	PUSH	A
	MOV	A,R5
	PUSH	A
	MOV	A,R6
	PUSH	A
	MOV	A,R7
	PUSH	A
	
	; save ,PSW, B, VB, DPS
	PUSH	PSW
	PUSH	B
	PUSH	?VB

	; save virtual registers
	MOV	R1,#?V0
Loop:	MOV	A,@R1
	INC	R1	
	PUSH	A
	DJNZ	R0,Loop

	CLR	A
	JMP	@A+DPTR

    cfi ENDBLOCK ?INTERRUPT_ENTER_SP
	ENDMOD

;-----------------------------------------------------------------------------
;
;	Function: ?INTERRUPT_LEAVE_SP
;
;	Description:
;		Restore register R0-R1,A,B,PSW,?VB,?DPS,DPL,DPH,(DPX) plus a specified
;		number of virtual registers from the machine stack.
;
;	Register input:
;		R7 = Number of virtual registers to restore.
;
;	Register output:
;		SP = SP-R7
;		R0 = R0-R7
;		R6 = Restored value
;		R7 = Restored value
;		A  = R6
;
;       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_SP
	EXTERN  ?VB
	EXTERN	?V0
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()

	RSEG	RCODE:CODE:NOROOT
	PUBLIC	?INTERRUPT_LEAVE_SP

    cfi BLOCK ?INTERRUPT_LEAVE_SP USING cfi_common
    cfi NOFUNCTION
    cfi A     Undefined

?INTERRUPT_LEAVE_SP:
#if (__NUMBER_OF_DPTRS__ > 1)
#ifdef __DPTR_SHADOWED__
        SELECT_DPTR0()
#endif
#endif
	; restore virtual registers
	MOV	A,#?V0-1
	ADD	A,R7
	MOV	R0,A
Loop:	
	POP	A
	MOV	@R0,A
	DEC	R0
	DJNZ	R7,Loop

	POP	?VB
	; restore PSW, B, ?VB, ?DPS
	POP	B
	POP	PSW

	; restore R0-R7
	POP	A
	MOV	R7,A
	POP	A
	MOV	R6,A
	POP	A
	MOV	R5,A
	POP	A
	MOV	R4,A
	POP	A
	MOV	R3,A
	POP	A
	MOV	R2,A
	POP	A
	MOV	R1,A
	POP	A
	MOV	R0,A

	; restore DPTR (and DPS)

#if (defined(__EXTENDED_DPTR__) && (__CODE_MODEL__ != __CM_FAR__))
	POP	?DPX
#endif

#if (__NUMBER_OF_DPTRS__ > 1)
        POP     A
#endif

#if (__CODE_MODEL__ == __CM_FAR__)
	POP	?DPX
#endif
	POP	DPH
	POP	DPL

#if (__NUMBER_OF_DPTRS__ > 1)
        EXTERN  ?DPS
	MOV	?DPS,A
#endif

	; restore A
	POP	A

	RETI

    cfi ENDBLOCK ?INTERRUPT_LEAVE_SP
	ENDMOD

;-----------------------------------------------------------------------------
;
;	Function: ?SMALL_INTERRUPT_ENTER_SP
;
;	Description:
;		This interrupt enter shuld be used when the register bank
;		have been changed. Saves register DPL, DPH, (DPX), B, VB, DPS, plus
;		a specified number of virtual registers on
;		the machine stack.
;
;               The below picture shows the most trivial case (i.e. no DPS and no extended core)
;
;                         FF
;                         :
;                      +-------+
;              CFA --> |   Vn  | <-- SP End, n = (R7 begin) - 1
;                      + - - - +
;                       :  :  :
;                      + - - - +
;                      |   V1  |
;                      + - - - +
;                      |   V0  |
;                      + - - - +
;                      |   VB  |
;                      + - - - +
;                      |   B   |
;          + - - - +   + - - - +
;          | retH  |   |  DPH0 | <-- SP begin
;          + - - - +   + - - - +
;          | retL  |   |  DPL0 |
;          +-------+   +-------+
;                       :
;                       00
;
;	Register input:
;		R7  = Number of virtual registers to save.
;
;	Register output:
;		SP = SP+(A+12)
;		A  = Undefined
;		R1 = Undefined
;		R7 = Undefined.
;		DPTR0 Is the return address from this function.
;
;       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: NA
;
;-----------------------------------------------------------------------------
	MODULE	?SMALL_INTERRUPT_ENTER_SP
	RSEG	RCODE:CODE:NOROOT
	PUBLIC	?SMALL_INTERRUPT_ENTER_SP
	EXTERN  ?VB
	EXTERN  ?V0
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()

    cfi BLOCK ?SMALL_INTERRUPT_ENTER_SP Using cfi_common
    cfi NOFUNCTION
    cfi A     Undefined
#if (__CORE__ == __CORE_EXTENDED1__)
    cfi CFA_MACHINE  add(add(MACHINE_SP, R7),1)
    cfi ?RET_EXT  load(1, IDATA, sub(sub(CFA_MACHINE, R7), 2))
    cfi ?RET_HIGH load(1, IDATA, sub(sub(CFA_MACHINE, R7), 3))
    cfi ?RET_LOW  load(1, IDATA, sub(sub(CFA_MACHINE, R7), 4))
#else
    cfi CFA_MACHINE  add(add(MACHINE_SP, R7),2)
    cfi ?RET_HIGH load(1, IDATA, sub(sub(CFA_MACHINE, R7), 2))
    cfi ?RET_LOW  load(1, IDATA, sub(sub(CFA_MACHINE, R7), 3))
#endif

?SMALL_INTERRUPT_ENTER_SP:
#if (__NUMBER_OF_DPTRS__ > 1)
	EXTERN	?DPS
	PUSH	?DPS
	SELECT_DPTR0()
#endif
	; exchange DPTR and return address located on stack
	MOV	R1,SP
#if (__NUMBER_OF_DPTRS__ > 1)
        DEC     R1
#endif

#if (__CODE_MODEL__ == __CM_FAR__)
	MOV	A,?DPX
	XCH	A,@R1
    cfi ?RET_EXT A
	MOV	?DPX,A
    cfi ?RET_EXT DPX0
	DEC	R1
#elif (defined(__EXTENDED_DPTR__))
	PUSH	?DPX
	MOV	?DPX,#0
#endif
	MOV	A,DPH
	XCH	A,@R1
    cfi ?RET_HIGH A
	MOV	DPH,A
    cfi ?RET_HIGH DPH0
	DEC	R1
	MOV	A,DPL
	XCH	A,@R1
    cfi ?RET_LOW A
	MOV	DPL,A
    cfi ?RET_LOW DPL0

	; save B, VB
	PUSH	B
    cfi CFA_MACHINE  add(add(MACHINE_SP, R7),1)
	PUSH	?VB
    cfi CFA_MACHINE  add(MACHINE_SP, R7)
	; save virtual registers
	MOV	R1,#?V0
Loop:	MOV	A,@R1
	INC	R1
	PUSH	A
    cfi CFA_MACHINE sub(add(MACHINE_SP, R7), 1)
	DJNZ	R7,Loop

    cfi CFA_MACHINE MACHINE_SP + 0
	CLR	A
	JMP	@A+DPTR

    cfi ENDBLOCK ?SMALL_INTERRUPT_ENTER_SP
	ENDMOD

;-----------------------------------------------------------------------------
;
;	Function: ?SMALL_INTERRUPT_LEAVE_SP
;
;	Description:
;		This interrupt enter routine shoul dbe used when the
;		register bank is switched.
;		Restore registers A,B,PSW,?VB,?DPS,DPL,DPH,(DPX) plus a specified
;		number of virtual registers from the machine stack.
;
;               The below picture shows the most trivial case (i.e. no DPS and no extended core)
;
;              FF
;              :
;          +-------+
;          |   Vn  | <-- SP begin, n = (R7 begin) - 1
;          + - - - +
;           :  :  :
;          + - - - +
;          |   V1  |
;          + - - - +
;          |   V0  |
;          + - - - +
;          |   VB  |
;          + - - - +
;          |   B   |
;          + - - - +
;        ( |  DPX0 | ) DPX0 exists only if __EXTENDED_DPTR__
;        ( + - - - + )
;          |  DPH0 |
;          + - - - +
;          |  DPL0 |
;          + - - - +
;        ( |  DPS  | ) DPS exists only if __NUMBER_OF_DPTRS__ > 1
;        ( + - - - + )
;          |  PSW  |
;          + - - - +
;          |   A   |
;          + - - - +
;        ( |  retx | ) retx exists only if __CODE_MODEL__ == __CM_FAR__
;        ( + - - - + )
;          |  reth | <-- SP End      (note, SP points on retx, if retx exists).
;          + - - - +
;          |  retl |   This return address is to the jumpers caller.
;          + - - - +
;  CFA --> | xxxxx |
;          +-------+
;              :
;              00
;
;	Register input:
;		R7 = Number of virtual registers to restore.
;
;	Register output:
;		SP = SP-R7
;		R0 = R0-R7
;		R6 = Restored value
;		R7 = Restored value
;		A  = R6
;
;       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 (restoerd)     Returns  DPS: restored
;
;	Stack usage: NA
;
;-----------------------------------------------------------------------------
	MODULE	?SMALL_INTERRUPT_LEAVE_SP
	EXTERN  ?VB
	EXTERN	?V0
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()

	RSEG	RCODE:CODE:NOROOT
	PUBLIC	?SMALL_INTERRUPT_LEAVE_SP

    cfi BLOCK ?SMALL_INTERRUPT_LEAVE_SP USING cfi_common
    cfi NOFUNCTION
    cfi A     samevalue
    cfi CFA_MACHINE  sub(MACHINE_SP,add(add(6,__SIZE_OF_RETADDR__),R7))
#if (__CORE__ == __CORE_EXTENDED1__)
    cfi ?RET_EXT  load(1, IDATA, add(CFA_MACHINE, 3))
    cfi ?RET_HIGH load(1, IDATA, add(CFA_MACHINE, 2))
    cfi ?RET_LOW  load(1, IDATA, add(CFA_MACHINE, 1))
#else
    cfi ?RET_HIGH load(1, IDATA, add(CFA_MACHINE, 2))
    cfi ?RET_LOW  load(1, IDATA, add(CFA_MACHINE, 1))
#endif

?SMALL_INTERRUPT_LEAVE_SP:
#if (__NUMBER_OF_DPTRS__ > 1)
#ifdef __DPTR_SHADOWED__
        SELECT_DPTR0()
#endif
#endif
	; restore virtual registers
	MOV	A,#?V0-1
	ADD	A,R7
	MOV	R0,A
Loop:	
	POP	A
    cfi CFA_MACHINE  sub(MACHINE_SP,add(add(5,__SIZE_OF_RETADDR__),R7))
	MOV	@R0,A
	DEC	R0
	DJNZ	R7,Loop
    cfi CFA_MACHINE  sub(MACHINE_SP,add(6,__SIZE_OF_RETADDR__))
	POP	?VB
    cfi CFA_MACHINE  sub(MACHINE_SP,add(5,__SIZE_OF_RETADDR__))
	; restore B, ?VB, ?DPS
	POP	B
    cfi CFA_MACHINE  sub(MACHINE_SP,add(4,__SIZE_OF_RETADDR__))

	; restore DPTR (and DPS)

#if (defined(__EXTENDED_DPTR__) && (__CODE_MODEL__ != __CM_FAR__))
	POP	?DPX
#endif

#if (__NUMBER_OF_DPTRS__ > 1)
        POP     A
#endif

#if (__CODE_MODEL__ == __CM_FAR__)
	POP	?DPX
#endif
	POP	DPH
   cfi CFA_MACHINE  sub(MACHINE_SP,add(3,__SIZE_OF_RETADDR__))
	POP	DPL
   cfi CFA_MACHINE  sub(MACHINE_SP,add(2,__SIZE_OF_RETADDR__))
#if (__NUMBER_OF_DPTRS__ > 1)
        EXTERN  ?DPS
	MOV	?DPS,A
#endif
	; restore PSW and A
	POP	PSW
   cfi CFA_MACHINE  sub(MACHINE_SP,add(1,__SIZE_OF_RETADDR__))
	POP	A
   cfi CFA_MACHINE  sub(MACHINE_SP, __SIZE_OF_RETADDR__)
	RETI

    cfi ENDBLOCK ?SMALL_INTERRUPT_LEAVE_SP
	ENDMOD

;-----------------------------------------------------------------------------
;
;	Function: ?SMALL_INTERRUPT_ENTER_PSP
;
;	Description:
;		Saves register DPL,DPH,(DPX),B,V0,(DPS) plus a specified
;		number of virtual registers on the PDATA stack.
;
;	Register input:
;		A  = -(#Vregs  + 4/5/6)
;
;	Register output:
;		?PSP   = ?PSP - (-A)
;
;       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:
;
;-----------------------------------------------------------------------------
	MODULE	?SMALL_INTERRUPT_ENTER_PSP

⌨️ 快捷键说明

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