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