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