【Aurix/Tricore实验分享一-A11(RA)】

本文介绍了在嵌入式系统中,A11寄存器作为执行环境的返回地址和通用地址寄存器的作用。强调了在修改A11的代码时,必须确保其中只存放有效地址以避免引发错误。通过示例展示了不同函数调用阶段中A11的值变化和其在程序流程中的作用。
摘要由CSDN通过智能技术生成

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文件内容如下:

名称地址块大小
main0x800000be0x00000044
test_func_10x800001020x00000022
test_func_20x800001240x00000024
test_func_30x800001480x00000022
test_func_40x8000016a0x00000022
_lc_ue_ustack0x7000900016K

阶段一、

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

参考文档:Aurix/Tricore实验分享之108: 连接寄存器

  • 27
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值