This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Compiler/tms320c6713b:Stack,Stack Frame和Max Stack Calculation

Guru**** 2406730 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/593022/compiler-tms320c6713b-stack-stack-frame-and-max-stack-calculation

部件号:TMS320C6713B

工具/软件:TI C/C++编译器

您好,

我正在处理TMS320C6713 dsk板上的应用程序。 我有几个问题:

1)我知道,调用函数时,其返回地址,参数和本地自动变量将被推送到称为堆栈帧的帧中堆栈。请考虑以下函数:

void foo (){

int x,y,z,;

}

堆栈:

|  z    |

-------------------

|  y   |

-------------------

|  x   |

-------------------

现在,如果x,y和z被推入堆栈,如上所示,则如何随机访问它们,即使是堆栈也遵循LIFO机制。 我的意思是,我可以随机访问任何变量,但在栈中,只有最后推入的变量可以访问,或者在每次随机使用变量时,栈应该弹出所有条目,直到到达该变量,我认为可能不是这样。 那么,在将变量推入堆栈后,如何随机访问这些变量???

2)如何计算应用中使用的最大堆栈以及在哪个点使用???? 嵌入式系统中用于堆栈计算的常用方法是什么?? 我认为CCS中有一个选项,但我要求使用与平台无关的方法。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这不是那种堆栈。 您正在考虑RPN堆栈,例如HP计算器或forth。

    您不会在C堆栈上推入和弹出,它只是增加了一定的数量,变量可以通过其地址访问,就像RAM的任何区域一样。

    它被称为"堆栈",因为当您继续从内部函数调用函数时,各种堆栈帧相互"堆叠"。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    x,y和z是"局部"变量。 它们存储在函数的"帧"中,也称为"激活记录"。 变量(以及临时变量)是相对于栈指针(SP,C6x上的B15)访问的。 即,使用*SP+(IMM)寻址访问帧中的值。 编译器可以并确实对局部变量重新排序,因此不能依赖x,y和z在框架中相邻,也不能以任何特定顺序进行计算。 优化器实际上可能会完全优化它们。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    幸运的是,我无法理解您的答案。 我知道变量是相对于栈指针访问的,但是如果我们必须相对地访问变量,为什么栈指针会递增/递减,为什么不只存储与固定内存位置相关的变量,而相对地访问它呢??? 如果我们可以访问堆栈指针所在堆栈中的任何内存,为什么即使这样它也被称为堆栈内存...我们不能只访问堆栈所指向的元素吗?????
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果是这样,正如您所说的Keith Barkley,那么为什么需要堆栈指针??? 不是指向顶部元素。 如果我们可以像RAM中的任何区域一样访问变量,我们可以将其称为数组或链接列表而不是栈,并且不需要在硬件中放置寄存器来用作栈指针!!! 我们只需要声明一个大小(而不是堆栈大小)的数组,然后将变量放入该数组中,我们就可以对数组基本地址进行随机访问!!!

    此外,如果我们可以将变量视为ram中的一个区域,那么为什么不能从另一个函数中的一个函数访问局部变量???? 这意味着,除非您从堆栈中弹出当前帧,否则请返回到原始函数,然后您可以访问其变量。 它实际上是堆栈,在任何意义上都不是,而是实际的堆栈内存。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能否建议应用程序在计算堆栈大小时使用的方法??
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    因为它使编译器更容易跟踪它。 看看这个片段:

    void foo (void){int x,y,z;return}

    .....

    如果(getGPIOPinValue()== true) foo()

    ...

    编译器不知道是否会调用foo()。 为每个函数的自动变量分配RAM空间是极其浪费的,尤其是在内存有限的嵌入式处理器上。 因此,编译器使用栈(内存中的相对区域)来存储自动变量,并使用栈指针+偏移来引用它们。

    它还允许编写编译器的计算机科学家所喜爱的递归。 如果编译器在内存中为auto变量留出特定区域,则foo调用自身时将覆盖这些变量。

    当然,你可以通过使所有变量都是静态的而不是自动来克服这一问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    堆栈LIFO的另一个方面是析构函数的调用顺序,即它们的构造顺序。  您可以设计构造函数/析构函数和对象创建,以便按特定顺序执行操作,如果以LIFO方式执行,这些操作将是正确的。  我认为编译器的优化器应该尊重这样一种依赖性(如果存在),但这方面可能有一些限制。  此外,也可能有一些已知的角部情况(如临时)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    aimal Khan 说:
    另外,您能否建议应用程序在计算堆栈大小时使用的方法??[/QUOT]

    TI提供了CG_xml软件包,其中包含几个对目标文件运行的实用程序,其中包括一个计算最坏情况堆栈大小的实用程序。  请参阅

    processors.wiki.ti.com/.../Stack_and_Heap_size_requirements

    processors.wiki.ti.com/.../Stack_issues

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这不是解决问题吗? 它如何处理递归?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当然,它会使您打卡。 它告诉您函数是递归的,您需要手动确定。 间接函数调用也必须由用户指定。