iar_stack_enter_leave.s51

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

S51
2,959
字号
/*******************************************************************************
 *
 * Description:	Save registers on stack.
 *
 * Calling convention:
 * -------------------
 *
 * 	Scratch registers:
 * 		A	Destroyed at enter & leave
 * 		B	Contains bit parameters (if any)
 * 		Carry	Destroyed at enter
 * 		R0	Destroyed at enter & leave
 * 		R1-R5	Can be register parameters (if any)
 *
 * 	Preserved registers:
 * 	       *DPTR	Avoid re-load
 * 		R6-R7	Register variables
 * 		V0-Vx	Register variables in IDATA
 *
 * 	* DPTR is only preserved in XDATA memory models.
 *
 * ATTENTION!!! Carry bit MUST be preserved in leave routines.
 * 
 *
 * Copyright 2002-2005 IAR Systems. All rights reserved.
 *
 * $Revision: 4427 $
 *
 ******************************************************************************/

#include "iar_common.h"

;-----------------------------------------------------------------------------
;
;	Function: ?FUNC_ENTER_OVERLAY
;
;	Description:
;		Saves register R6 and R7 plus a specified number of virtual
;		registers on the machine stack.
;
;
;		+------+
;		|      | <-- FRAME
;		+ - - -+
;		|  Vn  |
;		|  :   |
;		|  V0  |
;		+ - - -+
;		|  VB  |
;		+ - - -+
;		|  R6  |
;		+ - - -+
;		|  R7  |
;		+------+
;
;
;	Register input:
;		R0 Points to parameter (PRM) area, where to save registers.
;		A  The number of Virtual regs to push.
;
;	Register output:
;		A  = 0
;		R6 = 0
;		R0   Is undefined.
;
;       Multiple DPTR
;               DPTR/DPS: unchanged
;
;	Stack usage: NA
;
;-----------------------------------------------------------------------------
;
;                           FF
;                           :
;                           +------+
; [Base(2), CFA_SP - A - 2] | RetH | (holds high part of return address from start)
;                           + - - -+
; [Base(1), CFA_SP - A - 3] | RetL | (holds low part of return address from start)
;                           +------+
; [Base(0)]                 |  xx  | <-- SP <-- CFA_SP
;                           +------+
;                           :
;                           0
;

	MODULE	?FUNC_ENTER_OVERLAY
	RSEG	RCODE:CODE:NOROOT
	PUBLIC	?FUNC_ENTER_OVERLAY
	EXTERN	?V0
	EXTERN	?VB
        EXTERNS_FOR_ALL_DPTR_SYMBOLS()

    cfi BLOCK ?FUNC_ENTER_OVERLAY Using cfi_common
    cfi NOFUNCTION
    cfi R0 Undefined
    cfi R1 Undefined
    cfi R2 Undefined
    cfi R3 Undefined
    cfi R4 Undefined
    cfi R5 Undefined
    cfi R6 Undefined
    cfi R7 Undefined
    cfi A  Undefined

?FUNC_ENTER_OVERLAY:
#if (__NUMBER_OF_DPTRS__ > 1)
	SELECT_DPTR0()
#endif ; __NUMBER_OF_DPTRS__

	XCH	A,R7		; save R6 and R7
	MOV	@R0,A
	INC 	R0
	MOV	A,R6
	MOV	@R0,A
	INC 	R0

	MOV	@R0,?VB 	; save Bit register
	INC	R0

	MOV	A,R1		; save tmp reg
	PUSH	A
    cfi CFA_MACHINE MACHINE_SP - 3

	MOV	R1,#?V0
Loop:	
	MOV	A,@R1
	MOV	@R0,A
	INC	R0
	INC	R1
	DJNZ	R7,Loop

	POP	A
    cfi CFA_MACHINE MACHINE_SP - 2
	MOV	R1,A

	RET

#ifdef __BACKTRACE_TESTER__
       PUBLIC  ?FUNC_ENTER_OVERLAY_ENDS
?FUNC_ENTER_OVERLAY_ENDS:
#endif ; __BACKTRACE_TESTER__

    cfi ENDBLOCK ?FUNC_ENTER_OVERLAY
	ENDMOD

;-----------------------------------------------------------------------------
;
;	Function: ?FUNC_LEAVE_OVERLAY
;
;	Description:
;		Restore register R6, R7 and ?BREG_SEG plus a specified
;		number of virtual registers on the machine stack.
;
;		+------+
;		|      | <-- FRAME
;		+ - - -+
;		|  Vn  |
;		|  :   |
;		|  V0  |
;		+ - - -+
;		|  VB  |
;		+ - - -+
;		|  R6  |
;		+ - - -+
;		|  R7  |
;		+------+
;
;
;	Register input:
;		R0  Points to parameter (PRM) area, from where to restore registers.
;		A  The number of Virtual regs to push.
;
;	Register output:
;		A  = undefined.
;		R7 = restored value.
;		R0   Is undefined.
;
;       Multiple DPTR
;               DPTR/DPS: unchanged
;
;	Stack usage: NA
;
;-----------------------------------------------------------------------------
	MODULE	?FUNC_LEAVE_OVERLAY
	RSEG	RCODE:CODE:NOROOT
	PUBLIC	?FUNC_LEAVE_OVERLAY
	EXTERN	?V0
	EXTERN	?VB
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()

    cfi BLOCK ?FUNC_LEAVE_OVERLAY Using cfi_common
    cfi NOFUNCTION
    cfi A     Undefined

?FUNC_LEAVE_OVERLAY:
	XCH	A,R2
	PUSH	A
    cfi CFA_MACHINE MACHINE_SP - 3
	MOV	A,R1		; save tmp reg
	PUSH	A
    cfi CFA_MACHINE MACHINE_SP - 4

	MOV	A,@R0
	MOV	R7,A
	INC	R0
	MOV	A,@R0
	MOV	R6,A
	INC	R0

	MOV	?VB,@R0	; restore Bit register
	INC	R0

	MOV	R1,#?V0
Loop:	
	MOV	A,@R0
	MOV	@R1,A
	INC	R1
	INC	R0
	DJNZ	R2,Loop

	POP	A
    cfi CFA_MACHINE MACHINE_SP - 3
	MOV	R1,A
	POP	A
    cfi CFA_MACHINE MACHINE_SP - 2
	MOV	R2,A

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

#ifdef __BACKTRACE_TESTER__
       PUBLIC  ?FUNC_LEAVE_OVERLAY_ENDS
?FUNC_LEAVE_OVERLAY_ENDS:
#endif ; __BACKTRACE_TESTER__

    cfi ENDBLOCK ?FUNC_LEAVE_OVERLAY
	ENDMOD


;-----------------------------------------------------------------------------
;
;	Function: ?FUNC_ENTER_SP
;
;	Description:
;		Saves register R6 and R7 plus a specified number of virtual
;		registers on the machine stack.
;
;                  FF
;                  :
;		+------+
;       CFA --> |  Vn  | <-- SP end, n = A in
;		+ - - -+
;		 :  :  :
;		+ - - -+
;		|  V1  |
;		+ - - -+
;		|  V0  |
;		+ - - -+
;		|  VB  |
;		+ - - -+
;		|  R7  | <-- SP begin
;		+ - - -+
;		|  R6  |
;		+ - - -+
;		| xxxx |
;		+------+
;                  :
;                  0
;
;	Register input:
;		A  = Number of virtual registers to save.
;
;	Register output:
;		SP = SP+A
;		A  = 0
;		R6 = 0
;		R0 = Undefined.
;		DPTR0  = 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	?FUNC_ENTER_SP
	RSEG	RCODE:CODE:NOROOT
	PUBLIC	?FUNC_ENTER_SP
	EXTERN  ?VB
	EXTERN  ?V0
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()

    cfi BLOCK ?FUNC_ENTER_SP Using cfi_common
    cfi NOFUNCTION
    cfi A     Undefined
    cfi B     Undefined
    cfi VB    Undefined
    cfi R0    Undefined
    cfi R1    Undefined
    cfi R2    Undefined
    cfi R3    Undefined
    cfi R4    Undefined
    cfi R5    Undefined
    cfi R6    Undefined
    CFI_COMMON_DECLARE_UNDEFINED_FOR_ALL_DPTR_REGISTERS()
#if (__CORE__ == __CORE_EXTENDED1__)
  cfi CFA_MACHINE  add(MACHINE_SP,A)
  #if (defined(__EXTENDED_STACK__))
    cfi ?RET_EXT  load(1, XDATA, sub(CFA_MACHINE, A))
    cfi ?RET_HIGH load(1, XDATA, sub(sub(CFA_MACHINE, A), 1))
    cfi ?RET_LOW  load(1, XDATA, sub(sub(CFA_MACHINE, A), 2))
  #else
    cfi ?RET_EXT  load(1, IDATA, sub(CFA_MACHINE, A))
    cfi ?RET_HIGH load(1, IDATA, sub(sub(CFA_MACHINE, A), 1))
    cfi ?RET_LOW  load(1, IDATA, sub(sub(CFA_MACHINE, A), 2))
  #endif
#else
  cfi CFA_MACHINE  add(MACHINE_SP,add(A,1))
  #if (defined(__EXTENDED_STACK__))
    cfi ?RET_HIGH load(1, XDATA, sub(sub(CFA_MACHINE, A), 1))
    cfi ?RET_LOW  load(1, XDATA, sub(sub(CFA_MACHINE, A), 2))
  #else
    cfi ?RET_HIGH load(1, IDATA, sub(sub(CFA_MACHINE, A), 1))
    cfi ?RET_LOW  load(1, IDATA, sub(sub(CFA_MACHINE, A), 2))
  #endif
#endif

?FUNC_ENTER_SP:

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

#if (__CORE__ == __CORE_EXTENDED1__)
	POP	?DPX
    cfi CFA_MACHINE ADD(SUB(MACHINE_SP, 2), ADD(A, 3))
    cfi ?RET_EXT DPX0
	POP	DPH
    cfi CFA_MACHINE ADD(SUB(MACHINE_SP, 1), ADD(A, 3))
    cfi ?RET_HIGH DPH0
	POP	DPL
    cfi CFA_MACHINE ADD(SUB(MACHINE_SP, 0), ADD(A, 3))
    cfi ?RET_LOW DPL0
#else
#if ( defined(__EXTENDED_DPTR__))
	MOV	?DPX,#0
#endif
	POP	DPH
    cfi CFA_MACHINE ADD(SUB(MACHINE_SP, 1), ADD(A, 3))
    cfi ?RET_HIGH DPH0
	POP	DPL
    cfi CFA_MACHINE ADD(SUB(MACHINE_SP, 0), ADD(A, 3))
    cfi ?RET_LOW DPL0
#endif

	XCH	A,R6
    cfi CFA_MACHINE ADD(SUB(MACHINE_SP, 0), ADD(R6, 3))

	PUSH	A
    cfi CFA_MACHINE ADD(SUB(MACHINE_SP, 1), ADD(R6, 3))
	MOV	A,R7
	PUSH	A
    cfi CFA_MACHINE ADD(SUB(MACHINE_SP, 2), ADD(R6, 3))

	PUSH	?VB
    cfi CFA_MACHINE ADD(SUB(MACHINE_SP, 3), ADD(R6, 3))
	MOV	R0,#?V0

Loop:	MOV	A,@R0
	INC	R0
	PUSH	A
    cfi CFA_MACHINE add(sub(MACHINE_SP, 4), add(R6, 3))
	DJNZ	R6,Loop
    cfi CFA_MACHINE MACHINE_SP + 0
	CLR	A
	JMP	@A+DPTR

#ifdef __BACKTRACE_TESTER__
       PUBLIC  ?FUNC_ENTER_SP_ENDS
?FUNC_ENTER_SP_ENDS:
#endif ; __BACKTRACE_TESTER__

    cfi ENDBLOCK ?FUNC_ENTER_SP
	ENDMOD

;-----------------------------------------------------------------------------
;
;	Function: ?FUNC_LEAVE_SP
;
;	Description:
;		Restore register R6 and R7 plus a specified number of virtual
;		registers from the machine stack.
;
;                   FF
;                   :
;		+------ +
;		|  Vn   | <-- SP begin, n = R7 in
;		+ - - - +
;		 :  :  :
;		+ - - - +
;		|  V1   |
;		+ - - - +
;		|  V0   |
;		+ - - - +
;		|  VB   |
;		+ - - - +
;		|  R7   |
;		+ - - - +
;               |  R6   |
;	        + - - - +
;	      ( |  retx | ) retx may or may not exist.
;	      ( + - - - + )
;		|  reth | <-- SP end (before return)
;		+ - - - +
;		|  retl |
;		+ - - - +
;       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: none     Returns  DPS: 0
;
;               Separate:       Requires DPTR: none     Requires DPS: none
;                               Modifies DPTR: none     Returns  DPS: 0
;
;	Stack usage: NA
;
;-----------------------------------------------------------------------------

leave_SP MACRO retType
	MODULE	?\1_LEAVE_SP
	EXTERN  ?VB
	EXTERN	?V0
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()
	IF      '\1'='BANKED'
	EXTERN	?BRET
	ENDIF

	RSEG	RCODE:CODE:NOROOT
	PUBLIC	?\1_LEAVE_SP
    cfi BLOCK ?\1_LEAVE_SP USING cfi_common
    cfi NOFUNCTION
    cfi A     Undefined
    cfi B     Undefined
    cfi VB    Undefined
    cfi R0    Undefined
    cfi R1    Undefined
    cfi R2    Undefined
    cfi R3    Undefined
    cfi R4    Undefined
    cfi R5    Undefined
    cfi R6    Undefined
    cfi R7    Undefined
    CFI_COMMON_DECLARE_UNDEFINED_FOR_ALL_DPTR_REGISTERS()
#if   (__CODE_MODEL__ == __CM_BANKED__)
    cfi CFA_MACHINE  sub(MACHINE_SP,add(add(4,__SIZE_OF_RETADDR__),R7))
#else
    cfi CFA_MACHINE  sub(MACHINE_SP,add(add(3,__SIZE_OF_RETADDR__),R7))
#endif
#if (__CORE__ == __CORE_EXTENDED1__)
  #if (defined(__EXTENDED_STACK__))
    cfi ?RET_EXT  load(1, XDATA, add(CFA_MACHINE, 3))
    cfi ?RET_HIGH load(1, XDATA, add(CFA_MACHINE, 2))
    cfi ?RET_LOW  load(1, XDATA, add(CFA_MACHINE, 1))
  #else
    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))
  #endif
#else
  #if (defined(__EXTENDED_STACK__))
    cfi ?RET_HIGH load(1, XDATA, add(CFA_MACHINE, 2))
    cfi ?RET_LOW  load(1, XDATA, 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
#endif

?\1_LEAVE_SP:
;; Here we describe if Vx has been pushed yet.
;; R6 goes from NrOfVRegs to 0
;; R0 - VStart goes from 0 to NrOfVRegs
;;
	PUSH	PSW     ; Preserves carry
#if   (__CODE_MODEL__ == __CM_BANKED__)
   cfi CFA_MACHINE  sub(MACHINE_SP,add(add(5,__SIZE_OF_RETADDR__),R7))
#else
   cfi CFA_MACHINE  sub(MACHINE_SP,add(add(4,__SIZE_OF_RETADDR__),R7))
#endif
	MOV	A,#?V0 - 1
	ADD	A,R7
	POP	PSW     ; Preserves carry
#if   (__CODE_MODEL__ == __CM_BANKED__)
   cfi CFA_MACHINE  sub(MACHINE_SP,add(add(4,__SIZE_OF_RETADDR__),R7))
#else
   cfi CFA_MACHINE  sub(MACHINE_SP,add(add(3,__SIZE_OF_RETADDR__),R7))
#endif
	MOV	R0,A    ; R0 now points at the last virtual register to restore.
Loop:	POP	A
#if   (__CODE_MODEL__ == __CM_BANKED__)
   cfi CFA_MACHINE  sub(MACHINE_SP,add(add(3,__SIZE_OF_RETADDR__),R7))
#else
   cfi CFA_MACHINE  sub(MACHINE_SP,add(add(2,__SIZE_OF_RETADDR__),R7))
#endif
	MOV	@R0,A
	DEC	R0
	DJNZ	R7,Loop
#if   (__CODE_MODEL__ == __CM_BANKED__)
   cfi CFA_MACHINE  sub(MACHINE_SP,add(4,__SIZE_OF_RETADDR__)) ; R7 is now 0
#else
   cfi CFA_MACHINE  sub(MACHINE_SP,add(3,__SIZE_OF_RETADDR__)) ; R7 is now 0
#endif
	POP	?VB
#if   (__CODE_MODEL__ == __CM_BANKED__)
   cfi CFA_MACHINE  sub(MACHINE_SP,add(3,__SIZE_OF_RETADDR__))
#else
   cfi CFA_MACHINE  sub(MACHINE_SP,add(2,__SIZE_OF_RETADDR__))
#endif
	POP	A
#if   (__CODE_MODEL__ == __CM_BANKED__)
   cfi CFA_MACHINE  sub(MACHINE_SP,add(2,__SIZE_OF_RETADDR__))
#else
   cfi CFA_MACHINE  sub(MACHINE_SP,add(1,__SIZE_OF_RETADDR__))
#endif
	MOV	R7,A
	POP	A
#if   (__CODE_MODEL__ == __CM_BANKED__)
   cfi CFA_MACHINE  sub(MACHINE_SP, add(__SIZE_OF_RETADDR__,1))
#else
   cfi CFA_MACHINE  sub(MACHINE_SP, __SIZE_OF_RETADDR__)
#endif
	MOV	R6,A

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

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

#ifdef __BACKTRACE_TESTER__
       PUBLIC  ?\1_LEAVE_SP_ENDS
?\1_LEAVE_SP_ENDS:
#endif ; __BACKTRACE_TESTER__

    cfi ENDBLOCK ?\1_LEAVE_SP
	ENDMOD

	ENDM

	leave_SP BANKED
	leave_SP FUNC


;-----------------------------------------------------------------------------
;
;	Function: ?FUNC_ENTER_PDATA
;
;	Description:
;		Saves register R6 and R7 plus a specified number of virtual
;		registers on the PDATA stack.
;
;               FF
;               :
;          +----------+
;          | xxxxxxxx |  <-- ?PSP begin
;          + - - - - -+
;        ( | Ret_cc_E | )
;        ( + - - - - -+ )

⌨️ 快捷键说明

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