下面 LCR _main运行完后,EntryAddr不是应该放在RPC里吗,为何在ACC里?PUSH ACC, POP RPC又是何意?
_InitBoot:
; Initalize the stack pointer.
__stack: .usect ".stack",0
MOV SP, #__stack ; Initalize the stack pointer
; Initalize the device for running in C28x mode.
C28OBJ ; Select C28x object mode
C28ADDR ; Select C27x/C28x addressing
C28MAP ; Set blocks M0/M1 for C28x mode
CLRC PAGE0 ; Always use stack addressing mode
MOVW DP,#0 ; Initialize DP to point to the low 64 K
CLRC OVM
; Set PM shift of 0
SPM 0
; Decide which boot mode to use
LCR _main
; Cleanup and exit. At this point the EntryAddr
; is located in the ACC register
BF _ExitBoot,UNC
;———————————————–
; _ExitBoot
;———————————————–
;———————————————–
;This module cleans up after the boot loader
;
; 1) Make sure the stack is deallocated.
; SP = 0x400 after exiting the boot
; loader
; 2) Push 0 onto the stack so RPC will be
; 0 after using LRETR to jump to the
; entry point
; 2) Load RPC with the entry point
; 3) Clear all XARn registers
; 4) Clear ACC, P and XT registers
; 5) LRETR – this will also clear the RPC
; register since 0 was on the stack
;———————————————–
_ExitBoot:
;———————————————–
; Insure that the stack is deallocated
;———————————————–
MOV SP,#__stack
;———————————————–
; Clear the bottom of the stack. This will endup
; in RPC when we are finished
;———————————————–
MOV *SP++,#0
MOV *SP++,#0
;———————————————–
; Load RPC with the entry point as determined
; by the boot mode. This address will be returned
; in the ACC register.
;———————————————–
PUSH ACC
POP RPC
;———————————————–
; Put registers back in their reset state.
;
; Clear all the XARn, ACC, XT, and P and DP
; registers
;
; NOTE: Leave the device in C28x operating mode
; (OBJMODE = 1, AMODE = 0)
;———————————————–
ZAPA
MOVL XT,ACC
MOVZ AR0,AL
MOVZ AR1,AL
MOVZ AR2,AL
MOVZ AR3,AL
MOVZ AR4,AL
MOVZ AR5,AL
MOVZ AR6,AL
MOVZ AR7,AL
MOVW DP, #0
MOV *SP++,#0
MOV *SP++,#0x0A0B
POP ST1
POP ST0
;————————————————
; Jump to the EntryAddr as defined by the
; boot mode selected and continue execution
;———————————————–
LRETR
;eof ———-
囧:
并不是把ACC的值放到RPC,而是把原来LCR指令压倒堆栈的RPC值pop回来,具体请看SPRU430F的220页。
Long call using return PC pointer (RPC). The current RPC value is pushed onto thesoftware stack, pointed to by SP register, in two 16-bit operations. Next, the RPCregister is loaded with the return address. Next, the 22-bit immediate destination addressis loaded into the PC:[SP] = RPC(15:0);SP = SP + 1;[SP] = RPC(21:16);SP = SP + 1;RPC = PC + 2;PC = 22bit;Note: The LCR and LRETR operations, enable 4 cycle call and 4 cycle return. Thestandard LC and LRET operations only enable a 4 cycle call and 8 cycle return. TheLCR and LRETR operations can be nested and can freely replace the LC and LREToperations. This is the case on interrupts also. Only on a task switch operation, does theRPC need to be manually saved and restored.
下面 LCR _main运行完后,EntryAddr不是应该放在RPC里吗,为何在ACC里?PUSH ACC, POP RPC又是何意?
_InitBoot:
; Initalize the stack pointer.
__stack: .usect ".stack",0
MOV SP, #__stack ; Initalize the stack pointer
; Initalize the device for running in C28x mode.
C28OBJ ; Select C28x object mode
C28ADDR ; Select C27x/C28x addressing
C28MAP ; Set blocks M0/M1 for C28x mode
CLRC PAGE0 ; Always use stack addressing mode
MOVW DP,#0 ; Initialize DP to point to the low 64 K
CLRC OVM
; Set PM shift of 0
SPM 0
; Decide which boot mode to use
LCR _main
; Cleanup and exit. At this point the EntryAddr
; is located in the ACC register
BF _ExitBoot,UNC
;———————————————–
; _ExitBoot
;———————————————–
;———————————————–
;This module cleans up after the boot loader
;
; 1) Make sure the stack is deallocated.
; SP = 0x400 after exiting the boot
; loader
; 2) Push 0 onto the stack so RPC will be
; 0 after using LRETR to jump to the
; entry point
; 2) Load RPC with the entry point
; 3) Clear all XARn registers
; 4) Clear ACC, P and XT registers
; 5) LRETR – this will also clear the RPC
; register since 0 was on the stack
;———————————————–
_ExitBoot:
;———————————————–
; Insure that the stack is deallocated
;———————————————–
MOV SP,#__stack
;———————————————–
; Clear the bottom of the stack. This will endup
; in RPC when we are finished
;———————————————–
MOV *SP++,#0
MOV *SP++,#0
;———————————————–
; Load RPC with the entry point as determined
; by the boot mode. This address will be returned
; in the ACC register.
;———————————————–
PUSH ACC
POP RPC
;———————————————–
; Put registers back in their reset state.
;
; Clear all the XARn, ACC, XT, and P and DP
; registers
;
; NOTE: Leave the device in C28x operating mode
; (OBJMODE = 1, AMODE = 0)
;———————————————–
ZAPA
MOVL XT,ACC
MOVZ AR0,AL
MOVZ AR1,AL
MOVZ AR2,AL
MOVZ AR3,AL
MOVZ AR4,AL
MOVZ AR5,AL
MOVZ AR6,AL
MOVZ AR7,AL
MOVW DP, #0
MOV *SP++,#0
MOV *SP++,#0x0A0B
POP ST1
POP ST0
;————————————————
; Jump to the EntryAddr as defined by the
; boot mode selected and continue execution
;———————————————–
LRETR
;eof ———-
user4706449:
回复 囧:
2.2.8 Return Program Counter (RPC)When a call operation is performed using the LCR instruction, the return address is saved in the RPCregister and the old value in the RPC is saved on the stack (in two 16-bit operations). When a returnoperation is performed using the LRETR instruction, the return address is read from the RPC register andthe value on the stack is written into the RPC register (in two 16-bit operations). Other call instructions donot use the RPC register. For more information, see the instructions in Chapter 6.
读了上面一段还是不解,是不是跟函数嵌套有关, EntryAddr是作为RPC的 old value压入stack,而运行完LCR _main RPC放的是SCI_Boot的地址
LCR _main
Uint32 mian()
{……
return SCI_Boot();
}
Uint32 SCI_Boot()
{……
return EntryAddr;
}