【Aurix/Tricore实验分享三 - Stack】

1、概念

这里在架构文档内基本没找到栈的知识点。
栈用于局部变量的保存,或者用于超长参数传递(寄存器不足以传递).

1.1、栈管理寄存器

核架构中的堆栈管理支持用户堆栈和中断堆栈。地址寄存器A[10]、中断堆栈指针(ISP)和PSW位用于堆栈的管理。
使用[10]作为堆栈指针。该寄存器的初始内容通常由RTOS在创建任务时设置,这允许将专用堆栈区域分配给各个任务。
ISP有助于防止中断服务例程(ISR)访问专用堆栈区域,并可能干预软件管理任务的上下文。在核架构中实现了自动切换到使用ISP而不是专用堆栈指针。PSW.IS位指示哪个堆栈指针有效。
当发生中断并且中断的任务正在使用其专用堆栈(PSW.IS == 0)时,内容与中断任务的上层上下文一起保存,并且A[10](SP)与ISP的当前内容一起加载。
当发生中断或陷阱,并且中断的任务已经在使用中断堆栈(PSW.is==1)时,则不执行A[10](SP)的预加载。中断服务例程(ISR)在中断的例程离开时继续使用中断堆栈。
通常,在初始化例程期间只需要初始化ISP一次。但是,根据应用程序的需要,可以在执行过程中修改ISP。请注意,没有什么可以阻止ISR或系统服务例程在专用堆栈上执行。
注:在ISR中使用A[10](SP)由应用程序程序员自行决定。

1.1.1、地址寄存器A[10](SP)

A[10]栈指向寄存器(SP)的定义如下:
在这里插入图片描述

1.1.2、中断栈指向寄存器(ISP)

中断栈指向寄存器定义如下:
注:寄存器受ENDINIT保护。
在这里插入图片描述

2、局部变量数据类型为基础类型

2.1、测试代码,验证局部变量进行入栈和出栈的步骤

unsigned int test_SP_6(unsigned int paramA, unsigned int paramB, unsigned int paramC)
  0x80000142 20 10        SUB.A     a10,0x10
{
	volatile unsigned int tmp_param1 = 1;
//  0x80000144 DA 01        MOV       d15,0x1
//  0x80000146 74 AF        ST.W      [a10],d15
	volatile unsigned int tmp_param2 = 2;
//  0x80000148 DA 02        MOV       d15,0x2
//  0x8000014A 78 01        ST.W      [a10]0x4,d15
	volatile unsigned int tmp_param3 = 3;
//  0x8000014C DA 03        MOV       d15,0x3
//  0x8000014E 78 02        ST.W      [a10]0x8,d15

	tmp_param1 = paramA + paramB;
//  0x80000150 1A 54        ADD       d15,d4,d5
//  0x80000152 74 AF        ST.W      [a10],d15
	tmp_param2 = paramB + paramC;
//  0x80000154 42 65        ADD       d5,d6
//  0x80000156 89 A5 04 09  ST.W      [a10]0x4,d5
	tmp_param3 = paramA + paramC;
//  0x8000015A 42 64        ADD       d4,d6
//  0x8000015C 89 A4 08 09  ST.W      [a10]0x8,d4

	return 6;
}
//  0x80000160 82 62        MOV       d2,0x6
//  0x80000162 00 90        RET       
//  ...

unsigned int test_SP_5(unsigned int paramA)
//  0x8000010A 20 10        SUB.A     a10,0x10
{
	volatile unsigned int tmp_param1 = 1;
//  0x8000010C DA 01        MOV       d15,0x1
//  0x8000010E 74 AF        ST.W      [a10],d15
	volatile unsigned int tmp_param2 = 2;
//  0x80000110 DA 02        MOV       d15,0x2
//  0x80000112 78 01        ST.W      [a10]0x4,d15
	volatile unsigned int tmp_param3 = 3;
//  0x80000114 DA 03        MOV       d15,0x3
//  0x80000116 78 02        ST.W      [a10]0x8,d15
	volatile unsigned int tmp_param4 = 4;
//  0x80000118 DA 04        MOV       d15,0x4
//  0x8000011A 78 03        ST.W      [a10]0xC,d15

	tmp_param1 = tmp_param1 + paramA;
//  0x8000011C 54 AF        LD.W      d15,[a10]
//  0x8000011E 42 4F        ADD       d15,d4
//  0x80000120 74 AF        ST.W      [a10],d15
	tmp_param2 = tmp_param2 + paramA;
//  0x80000122 58 01        LD.W      d15,[a10]0x4
//  0x80000124 42 4F        ADD       d15,d4
//  0x80000126 78 01        ST.W      [a10]0x4,d15
	tmp_param3 = tmp_param3 + paramA;
//  0x80000128 58 02        LD.W      d15,[a10]0x8
//  0x8000012A 42 4F        ADD       d15,d4
//  0x8000012C 78 02        ST.W      [a10]0x8,d15
	tmp_param4 = tmp_param4 + paramA;
//  0x8000012E 58 03        LD.W      d15,[a10]0xC
//  0x80000130 42 4F        ADD       d15,d4
//  0x80000132 78 03        ST.W      [a10]0xC,d15

	test_SP_6(5, 5, 5);
//  0x80000134 82 54        MOV       d4,0x5
//  0x80000136 02 45        MOV       d5,d4
//  0x80000138 02 46        MOV       d6,d4
//  0x8000013A 6D 00 04 00  CALL      test_SP_6 (0x80000142)  

	return 5;
}
//  0x8000013E 82 52        MOV       d2,0x5
//  0x80000140 00 90        RET       
  ...

unsigned int test_SP_4(unsigned int paramB)
//  0x800000E6 20 10        SUB.A     a10,0x10
{
	volatile unsigned int tmp_param1 = 0;
//  0x800000E8 DA 00        MOV       d15,0x0
//  0x800000EA 74 AF        ST.W      [a10],d15
	volatile unsigned int tmp_param2 = 0;
//  0x800000EC 78 01        ST.W      [a10]0x4,d15
	volatile unsigned int tmp_param3 = 0;
//  0x800000EE 78 02        ST.W      [a10]0x8,d15

	tmp_param1 = paramB + 1;
//  0x800000F0 9A 14        ADD       d15,d4,0x1
//  0x800000F2 74 AF        ST.W      [a10],d15
	tmp_param2 = paramB + 2;
//  0x800000F4 9A 24        ADD       d15,d4,0x2
//  0x800000F6 78 01        ST.W      [a10]0x4,d15
	tmp_param3 = paramB + 3;
//  0x800000F8 9A 34        ADD       d15,d4,0x3
//  0x800000FA 78 02        ST.W      [a10]0x8,d15

	test_SP_5(4);
//  0x800000FC 82 44        MOV       d4,0x4
//  0x800000FE 6D 00 06 00  CALL      test_SP_5 (0x8000010A)  

	return (tmp_param1 + tmp_param2);
//  0x80000102 54 A2        LD.W      d2,[a10]
//  0x80000104 58 01        LD.W      d15,[a10]0x4
}
//  0x80000106 42 F2        ADD       d2,d15
//  0x80000108 00 90        RET       
  ...



unsigned int test_SP_3(unsigned int paramA)
//  0x800000CC 20 08        SUB.A     a10,0x8
{
	volatile unsigned int tmp_param1 = 0;
//  0x800000CE DA 00        MOV       d15,0x0
//  0x800000D0 74 AF        ST.W      [a10],d15
	volatile unsigned int tmp_param2 = 0;
//  0x800000D2 78 01        ST.W      [a10]0x4,d15

	tmp_param1 = paramA + 1;
//  0x800000D4 9A 14        ADD       d15,d4,0x1
//  0x800000D6 74 AF        ST.W      [a10],d15
	tmp_param2 = paramA + 2;
//  0x800000D8 9A 24        ADD       d15,d4,0x2
//  0x800000DA 78 01        ST.W      [a10]0x4,d15

	test_SP_4(3);
//  0x800000DC 82 34        MOV       d4,0x3
//  0x800000DE 6D 00 04 00  CALL      test_SP_4 (0x800000E6)  

	return 3;
}
//  0x800000E2 82 32        MOV       d2,0x3
//  0x800000E4 00 90        RET       
//  ...


unsigned int test_SP_2(void)
//  0x800000B6 DA 64        MOV       d15,0x64
//  0x800000B8 20 08        SUB.A     a10,0x8
//  ...
{
	volatile unsigned int tmp_var = 100;
//> 0x800000B6 DA 64        MOV       d15,0x64
//> ...
//> 0x800000BA 74 AF        ST.W      [a10],d15

	tmp_var *= 2;
//  0x800000BE 54 AF        LD.W      d15,[a10]
//  0x800000C0 06 1F        SH        d15,0x1
//  0x800000C2 74 AF        ST.W      [a10],d15
//  ...

	test_SP_3(2);
//  0x800000BC 82 24        MOV       d4,0x2
//> 0x800000C4 6D 00 04 00  CALL      test_SP_3 (0x800000CC)  

	return tmp_var;
//  0x800000C8 54 A2        LD.W      d2,[a10]
}
//  0x800000CA 00 90        RET       
//  ...

void test_SP_1(void)
{
	test_SP_2();
//  0x8000002C 1D 00 45 00  J         test_SP_2 (0x800000B6)  
//  ...
	return;
}

int main(void)
{
	test_SP_1();
//  0x800000AE 6D FF BF FF  CALL      test_SP_1 (0x8000002C)  
}
//  0x800000B2 82 02        MOV       d2,0x0
//  0x800000B4 00 90        RET    

2.2、调试代码,步骤记录

2.2.1、执行test_SP_1()接口

A10 - 0x70009000,指向栈底;

0x70008FF0: 00000000
0x70008FF4: 00000000
0x70008FF8: 800005C8	//上一次入栈残留的数据
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000

2.2.2、执行test_SP_2()接口

  • 进入接口前,A10地址减8,这是编译器根据局部变量分的,大小为8的倍数。
    A10 - 0x70008FF8。
  • 接口执行期间所有对局部变量的操作,都直接对栈内数据进行操作。
  • 初始化局部变量tmp_var时。
0x70008FF0: 00000000
0x70008FF4: 00000000
0x70008FF8: 80000064	//tmp_var初始化数据
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000
  • 对局部变量tmp_val数值进行*2操作
0x70008FF0: 00000000
0x70008FF4: 00000000
0x70008FF8: 800000C8	//tmp_var*2后数值
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000

2.2.3、执行test_SP_3()接口

  • 进入接口前,A10地址减8,这是编译器根据局部变量分的,大小为8的倍数。两个参数
    A10 - 0x70008FF0。
  • 初始化局部变量tmp_var1和tmp_var2后。
0x70008FF0: 00000000	//tmp_var1初始化值为0
0x70008FF4: 00000000	//tmp_var2初始化值为0
0x70008FF8: 800000C8	//tmp_var*2后数值
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000
  • 局部变量tmp_var1和tmp_var2执行操作后。
0x70008FF0: 00000003	//tmp_var1操作后值为3
0x70008FF4: 00000004	//tmp_var2操作后值为4
0x70008FF8: 800000C8	//tmp_var*2后数值
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000

2.2.4、执行test_SP_4()接口

  • 进入接口前,A10地址减16,这是编译器根据局部变量分的,大小为8的倍数。三个参数
    A10 - 0x70008FE0;
  • 初始化局部变量tmp_var1、tmp_var2和tmp_var3后。
0x70008FE0: 00000000    //tmp_var1初始化值0
0x70008FE4: 00000000    //tmp_var2初始化值0
0x70008FE8: 00000000    //tmp_var3初始化值0
0x70008FEC: 00000000    //预留的
0x70008FF0: 00000003	//tmp_var1操作后值为3
0x70008FF4: 00000004	//tmp_var2操作后值为4
0x70008FF8: 800000C8	//tmp_var*2后数值
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000
  • 局部变量tmp_var1、tmp_var2和tmp_var3操作后。
0x70008FE0: 00000004    //tmp_var1操作后值4
0x70008FE4: 00000005    //tmp_var2操作后值5
0x70008FE8: 00000006    //tmp_var3操作后值6
0x70008FEC: 00000000    //预留的
0x70008FF0: 00000003	//tmp_var1操作后值为3
0x70008FF4: 00000004	//tmp_var2操作后值为4
0x70008FF8: 800000C8	//tmp_var*2后数值
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000

2.2.5、执行test_SP_5()接口

  • 进入接口前,A10地址减16,这是编译器根据局部变量分的,大小为8的倍数。四个参数
    A10 - 0x70008FD0;
  • 初始化局部变量tmp_var1、tmp_var2、tmp_var3和tmp_var4后。
0x70008FD0: 00000001	//tmp_var1初始化值1
0x70008FD4: 00000002	//tmp_var2初始化值2
0x70008FD8: 00000003	//tmp_var3初始化值3
0x70008FDC: 00000004	//tmp_var4初始化值4
0x70008FE0: 00000004    //tmp_var1操作后值4
0x70008FE4: 00000005    //tmp_var2操作后值5
0x70008FE8: 00000006    //tmp_var3操作后值6
0x70008FEC: 00000000    //预留的
0x70008FF0: 00000003	//tmp_var1操作后值为3
0x70008FF4: 00000004	//tmp_var2操作后值为4
0x70008FF8: 800000C8	//tmp_var*2后数值
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000
  • 局部变量tmp_var1、tmp_var2、tmp_var3和tmp_var4操作后。
0x70008FD0: 00000005	//tmp_var1操作后值5
0x70008FD4: 00000006	//tmp_var2操作后值6
0x70008FD8: 00000007	//tmp_var3操作后值7
0x70008FDC: 00000008	//tmp_var4操作后值8
0x70008FE0: 00000004    //tmp_var1操作后值4
0x70008FE4: 00000005    //tmp_var2操作后值5
0x70008FE8: 00000006    //tmp_var3操作后值6
0x70008FEC: 00000000    //预留的
0x70008FF0: 00000003	//tmp_var1操作后值为3
0x70008FF4: 00000004	//tmp_var2操作后值为4
0x70008FF8: 800000C8	//tmp_var*2后数值
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000

2.2.6、执行test_SP_6()接口

  • 进入接口前,A10地址减16,这是编译器根据局部变量分的,大小为8的倍数。三个参数
    A10 - 0x70008FC0;
  • 初始化局部变量tmp_var1、tmp_var2、tmp_var3后。
0x70008FC0: 0000000A	//tmp_var1操作后值10
0x70008FC4: 0000000A	//tmp_var2操作后值10
0x70008FC8: 0000000A	//tmp_var3操作后值10
0x70008FCC: 00000000	//预留的
0x70008FD0: 00000005	//tmp_var1操作后值5
0x70008FD4: 00000006	//tmp_var2操作后值6
0x70008FD8: 00000007	//tmp_var3操作后值7
0x70008FDC: 00000008	//tmp_var4操作后值8
0x70008FE0: 00000004    //tmp_var1操作后值4
0x70008FE4: 00000005    //tmp_var2操作后值5
0x70008FE8: 00000006    //tmp_var3操作后值6
0x70008FEC: 00000000    //预留的
0x70008FF0: 00000003	//tmp_var1操作后值为3
0x70008FF4: 00000004	//tmp_var2操作后值为4
0x70008FF8: 800000C8	//tmp_var*2后数值
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000

2.2.7、出栈步骤

  • 退出test_SP_6()接口
    A10 - 0x70008FD0;
  • 退出test_SP_5()接口
    A10 - 0x70008FE0;
  • 退出test_SP_4()接口
    A10 - 0x70008FF0;
  • 退出test_SP_3()接口
    A10 - 0x70008FF8;
  • 退出test_SP_2()接口
    A10 - 0x70009000;
  • 退出test_SP_1()接口
    A10 - 0x70009000;
  • 栈内数据不变化
0x70008FC0: 0000000A	//上一次入栈残留的数据
0x70008FC4: 0000000A	//上一次入栈残留的数据
0x70008FC8: 0000000A	//上一次入栈残留的数据
0x70008FCC: 00000000	//预留的
0x70008FD0: 00000005	//上一次入栈残留的数据
0x70008FD4: 00000006	//上一次入栈残留的数据
0x70008FD8: 00000007	//上一次入栈残留的数据
0x70008FDC: 00000008	//上一次入栈残留的数据
0x70008FE0: 00000004    //上一次入栈残留的数据
0x70008FE4: 00000005    //上一次入栈残留的数据
0x70008FE8: 00000006    //上一次入栈残留的数据
0x70008FEC: 00000000    //预留的
0x70008FF0: 00000003	//上一次入栈残留的数据
0x70008FF4: 00000004	//上一次入栈残留的数据
0x70008FF8: 800000C8	//上一次入栈残留的数据
0x70008FFC: 80000652    //上一次入栈残留的数据
0x70009000: 00000000

2.2.8、疑问

1、退出接口,进行出栈时,A10是如何知道出栈块大小的?

3、局部变量数据类型为结构体

3.1、测试代码,验证局部变量进行入栈和出栈的步骤

void test_SP_8(TestParam_S paramA)
//  0x800000D4 20 10        SUB.A     a10,0x10
{
	volatile TestParam_S tmp_param1;
	volatile unsigned int tmp_param2 = 0;
//  0x800000D6 DA 00        MOV       d15,0x0
//  0x800000D8 78 03        ST.W      [a10]0xC,d15

	tmp_param1 = paramA;
//  0x800000DA 49 AF 10 0A  LEA       a15,[a10]0x10
//  0x800000DE 40 A2        MOV.AA    a2,a10
//  0x800000E0 A0 24        MOV.A     a4,0x2
//  0x800000E2 44 FF        LD.W      d15,[a15+]0x4
//  0x800000E4 64 2F        ST.W      [a2+]0x4,d15
//  0x800000E6 FC 4E        LOOP      a4,0x800000E2  
	tmp_param2 = 1;
//  0x800000E8 DA 01        MOV       d15,0x1
//  0x800000EA 78 03        ST.W      [a10]0xC,d15
}
//  0x800000EC 00 90        RET       
//  ...

int main(void)
//  0x800000AE 20 18        SUB.A     a10,0x18
{
	TestParam_S tmp_param;

	tmp_param.param1 = 1;
//  0x800000B0 DA 01        MOV       d15,0x1
//  0x800000B2 78 03        ST.W      [a10]0xC,d15
	tmp_param.param2 = 2;
//  0x800000B4 DA 02        MOV       d15,0x2
//  0x800000B6 78 04        ST.W      [a10]0x10,d15
	tmp_param.param3 = 3;
//  0x800000B8 DA 03        MOV       d15,0x3
//  0x800000BA 89 AF 14 08  ST.B      [a10]0x14,d15
	test_SP_8(tmp_param);
//  0x800000BE 49 AF 0C 0A  LEA       a15,[a10]0xC
//  0x800000C2 40 A2        MOV.AA    a2,a10
//  0x800000C4 A0 24        MOV.A     a4,0x2
//  0x800000C6 44 FF        LD.W      d15,[a15+]0x4
//  0x800000C8 64 2F        ST.W      [a2+]0x4,d15
//  0x800000CA FC 4E        LOOP      a4,0x800000C6  
//  0x800000CC 6D 00 04 00  CALL      test_SP_8 (0x800000D4)  
}
//  0x800000D0 82 02        MOV       d2,0x0
//  0x800000D2 00 90        RET  

3.2、调试代码,步骤记录

A10 - 0x70009000;

3.2.1、执行main()接口

  • 进入接口前,A10地址减0x18,这是编译器根据局部变量分的,大小为8的倍数。
    A10 - 0x70008FE8;
  • 初始化局部变量tmp_param后。
0x70008FE0: 00000000
0x70008FE4: 00000000
0x70008FE8: 00000000
0x70008FEC: 00000000
0x70008FF0: 00000000
0x70008FF4: 00000001	//tmp_param.param1初始化值
0x70008FF8: 00000002    //tmp_param.param2初始化值
0x70008FFC: 80000503    //tmp_param.param3,800005是上一次入栈数据未清理,03是初始化值
0x70009000: 00000000
  • 调用test_SP_8()接口前,栈内容
0x70008FE0: 00000000
0x70008FE4: 00000000
0x70008FE8: 00000001    //tmp_param.param1复制值
0x70008FEC: 00000002    //tmp_param.param2复制值
0x70008FF0: 80000503    //tmp_param.param3复制值
0x70008FF4: 00000001    //tmp_param.param1初始化值
0x70008FF8: 00000002    //tmp_param.param2初始化值
0x70008FFC: 80000503    //tmp_param.param3,800005是上一次入栈数据未清理,03是初始化值
0x70009000: 00000000

3.2.2、执行test_SP_8()接口

  • 进入接口时,A10地址减0x10,这是编译器根据局部变量分的,大小为8的倍数。
    A10 - 0x70008FD8;
  • 初始化局部变量tmp_param1和tmp_param2后。
0x70008FD0: 00000000
0x70008FD4: 00000000
0x70008FD8: 00000000	//test_SP_8()接口中tmp_param1.param1初始值
0x70008FDC: 00000000 	//test_SP_8()接口中tmp_param1.param2初始值
0x70008FE0: 00000000	//test_SP_8()接口中tmp_param1.param3初始值
0x70008FE4: 00000000	//test_SP_8()接口中tmp_param2初始值
0x70008FE8: 00000001    //tmp_param.param1复制值
0x70008FEC: 00000002    //tmp_param.param2复制值
0x70008FF0: 80000503    //tmp_param.param3复制值
0x70008FF4: 00000001    //tmp_param.param1初始化值
0x70008FF8: 00000002    //tmp_param.param2初始化值
0x70008FFC: 80000503    //tmp_param.param3,800005是上一次入栈数据未清理,03是初始化值
0x70009000: 00000000
  • 局部变量tmp_param1和tmp_param2赋值后。
0x70008FD0: 00000000
0x70008FD4: 00000000
0x70008FD8: 00000001	//test_SP_8()接口中tmp_param1.param1赋值值
0x70008FDC: 00000002 	//test_SP_8()接口中tmp_param1.param2赋值值
0x70008FE0: 80000503	//test_SP_8()接口中tmp_param1.param3赋值值
0x70008FE4: 00000001	//test_SP_8()接口中tmp_param2赋值值
0x70008FE8: 00000001    //tmp_param.param1复制值
0x70008FEC: 00000002    //tmp_param.param2复制值
0x70008FF0: 80000503    //tmp_param.param3复制值
0x70008FF4: 00000001    //tmp_param.param1初始化值
0x70008FF8: 00000002    //tmp_param.param2初始化值
0x70008FFC: 80000503    //tmp_param.param3,800005是上一次入栈数据未清理,03是初始化值
0x70009000: 00000000

3.2.3、出栈步骤

  • 退出test_SP_8()接口
    A10 - 0x70008FE8;
  • 退出main()接口
    A10 - 0x70009000;

4、接口参数传入为指针

4.1、测试代码,验证局部变量进行入栈和出栈的步骤

void test_SP_8(TestParam_S * paramA)
//  0x800000C6 20 10        SUB.A     a10,0x10
{
	volatile TestParam_S tmp_param1;
	volatile unsigned int tmp_param2 = 0;
//  0x800000C8 DA 00        MOV       d15,0x0
//  0x800000CA 78 03        ST.W      [a10]0xC,d15
	tmp_param1 = *paramA;
//  0x800000CC 40 AF        MOV.AA    a15,a10
//  0x800000CE A0 22        MOV.A     a2,0x2
//  0x800000D0 44 4F        LD.W      d15,[a4+]0x4
//  0x800000D2 64 FF        ST.W      [a15+]0x4,d15
//  0x800000D4 FC 2E        LOOP      a2,0x800000D0  
	tmp_param2 = 1;
//  0x800000D6 DA 01        MOV       d15,0x1
//  0x800000D8 78 03        ST.W      [a10]0xC,d15
}
//  0x800000DA 00 90        RET       
//  ...

int main(void)
//  0x800000AE 20 10        SUB.A     a10,0x10
{
	TestParam_S tmp_param;

	tmp_param.param1 = 1;
//  0x800000B0 DA 01        MOV       d15,0x1
//  0x800000B2 74 AF        ST.W      [a10],d15
	tmp_param.param2 = 2;
//  0x800000B4 DA 02        MOV       d15,0x2
//  0x800000B6 78 01        ST.W      [a10]0x4,d15
	tmp_param.param3 = 3;
//  0x800000B8 DA 03        MOV       d15,0x3
//  0x800000BA 2C A8        ST.B      [a10]0x8,d15
	test_SP_8(&tmp_param);
//  0x800000BC 40 A4        MOV.AA    a4,a10
//  0x800000BE 6D 00 04 00  CALL      test_SP_8 (0x800000C6)  
}
//  0x800000C2 82 02        MOV       d2,0x0
//  0x800000C4 00 90        RET     

4.2、调试代码,步骤记录

4.2.1、执行main()接口

  • 进入接口时,A10地址减0x10,这是编译器根据局部变量分的,大小为8的倍数。
    A10 - 0x70008FE0;
  • 初始化局部变量tmp_param后。
0x70008FF0: 00000001    //tmp_param.param1初始化值
0x70008FF4: 00000002    //tmp_param.param2初始化值
0x70008FF8: 80000503    //tmp_param.param3,800005是上一次入栈数据未清理,03是初始化值
0x70008FFC: 00000000    //预留
0x70009000: 00000000

4.2.2、执行test_SP_8()接口

  • 进入接口时,A10地址减0x10,这是编译器根据局部变量分的,大小为8的倍数。
    A10 - 0x70008FD0;
  • 局部变量tmp_param1和tmp_param2赋值后。
0x70008FE0: 00000001	//test_SP_8()接口中tmp_param1.param3赋值值
0x70008FE4: 00000002	//test_SP_8()接口中tmp_param2赋值值
0x70008FE8: 80000503    //tmp_param.param1赋值值
0x70008FEC: 00000001    //tmp_param.param2赋值值
0x70008FF0: 00000001    //tmp_param.param1初始化值
0x70008FF4: 00000002    //tmp_param.param2初始化值
0x70008FF8: 80000503    //tmp_param.param3,800005是上一次入栈数据未清理,03是初始化值
0x70008FFC: 800005CA    //上次入栈残留数据
0x70009000: 00000000

4.2.3、出栈步骤

  • 退出test_SP_8()接口
    A10 - 0x70008FF0;
  • 退出main()接口
    A10 - 0x70009000;

5、参考文档

Aurix/Tricore实验分享之六十二:Tricore 1.3内核Stack管理

  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值