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