A11作为当前执行环境的返回地址, 除此之外也可以作为通用的地址寄存器使用。
在正常使用中,A11将始终包含下一个RET或RFE指令的目标。
处理器使用这个事实在执行RET/RFE指令之前推测性地加载返回目标。修改A11的代码(例如测试代码)应该知道存储在A11中的任何值都可能被用作这种推测的目标。如果A11中的值不是有效地址,则推测可能导致总线和存储器系统触发错误条件和警报。
因此,建议A11只能包含有效的地址值。
unsigned int gA10Val[6];
unsigned int gA11Val[6];
unsigned int gPCVal[6];
__attribute__((always_inline))static inline unsigned int get_A10(void)
{
register unsigned int result;
__asm( "mov.d %0, a10" :"=d"(result)::);
return(result);
}
__attribute__( ( always_inline ) ) static inline unsigned int get_A11(void)
{
register unsigned int result;
__asm("mov.d %0, a11": "=d"(result)::);
return(result);
}
void test_func_4(void)//阶段六
{
gA10Val[5] = get_A10();
gA11Val[5] = get_A11();
gPCVal[5] = __mfcr(CPU_PC);
}
void test_func_3(void) //阶段五
{
gA10Val[4] = get_A10();
gA11Val[4] = get_A11();
gPCVal[4] = __mfcr(CPU_PC);
}
void test_func_2(void)//阶段四
{
gA10Val[3] = get_A10();
gA11Val[3] = get_A11();
gPCVal[3] = __mfcr(CPU_PC);
test_func_3();
}
void test_func_1(void) //阶段二
{
gA10Val[1] = get_A10();
gA11Val[1] = get_A11();
gPCVal[1] = __mfcr(CPU_PC);
}
int main(void)
{
gA10Val[0] = get_A10(); //0x800000C0-0x800000C8
gA11Val[0] = get_A11(); //0x800000CC-0x800000D4
gPCVal[0] = __mfcr(CPU_PC); //0x800000D6-0x800000E2//阶段一
test_func_1(); //0x800000E4
gA10Val[2] = get_A10(); //0x800000EA
gA11Val[2] = get_A11(); //0X800000EE
gPCVal[2] = __mfcr(CPU_PC);//0x800000F0-0x800000F4//阶段三
test_func_2(); //0x800000F6
test_func_4(); //0x800000FA
}
我这里使用的是Tasking编译器和UAD2-Pro调试器
工程生成的.map文件内容如下:
名称 | 地址 | 块大小 |
---|---|---|
main | 0x800000be | 0x00000044 |
test_func_1 | 0x80000102 | 0x00000022 |
test_func_2 | 0x80000124 | 0x00000024 |
test_func_3 | 0x80000148 | 0x00000022 |
test_func_4 | 0x8000016a | 0x00000022 |
_lc_ue_ustack | 0x70009000 | 16K |
阶段一、
A10[SP] ---- 0x70009000 //Core0的用户堆栈起始地址。
A11[RA] ---- 0x80000682 //由Cstart跳转到Main记录的返回地址。
PC ---- 0x800000DE //main接口中“gPCVal[1] = __mfcr(CPU_PC);”指令的当前地址。
阶段二、
A10[SP] ---- 0x70009000 //阶段一跳转到阶段二未产生堆栈。
A11[RA] ---- 0x800000E8 //调用test_func_1()接口指令地址为0x800000E4,A11记录的是下一条指令的地址0x800000E8。
PC ---- 0x8000011A
阶段三、
A10[SP] ---- 0x70009000//阶段二跳转阶段三未产生堆栈。
A11[RA] ---- 0x80000682 //由于再次返回到main接口执行,由Cstart跳转到Main记录的返回地址。
PC ---- 0x800000F0
阶段四、
A10[SP] ---- 0x70009000//阶段三跳转阶段四未产生堆栈。
A11[RA] ---- 0x800000FA //调用test_func_2()接口指令地址为0x800000F6,A11记录的是下一条指令的地址0x800000FA。
PC ---- 0x8000013C
阶段五、
A10[SP] ---- 0x70009000//阶段四跳转阶段五未产生堆栈。
A11[RA] ---- 0x800000FA //调用test_func_3)接口指令地址为0x800000FA,此指令后直接返回main-0x800000FA 。
PC ---- 0x80000160
阶段六、
A10[SP] ---- 0x70009000//阶段五跳转阶段六未产生堆栈。
A11[RA] ---- 0x800000FE //调用test_func_4)接口指令地址为0x800000FA,A11记录的是下一条指令的地址0x800000FE。
PC ---- 0x80000182