跳到主要内容

4.4 C和C++中的栈使用

C 和 C++ 都会使用栈(stack)。例如,栈中通常保存以下内容:

  • 函数的返回地址。
  • 必须保存的寄存器,这些由 KF32编译器的调用约定决定。
  • 局部变量,包括局部数组、结构体和联合体。
  • C++ 中的类实例

有些栈使用情况并不直观,例如:

  • 如果局部整型或浮点变量溢出寄存器(spilled),也就是未分配到寄存器,它们会分配到栈上。
  • 结构体通常分配在栈上。栈上会保留一块大小为 sizeof(struct) 的空间。但是,编译器也可能尝试将结构体分配到寄存器中。
  • 如果数组的大小在编译时已知,编译器会将其分配到栈上。栈上会保留一块大小为 sizeof(array) 的空间
  • 一些优化可能会引入新的临时变量,用于保存中间结果。这些优化包括:公共子表达式消除(CSE, Common Subexpression Elimination)、活跃区间拆分(Live Range Splitting)、结构体拆分(Structure Splitting),编译器会尝试将这些临时变量分配到寄存器中。如果寄存器不足,则会将其溢出到栈上。
  • KF32编译器要求某些函数参数通过栈传递,而不是寄存器传递。具体取决于参数的类型、大小以及参数顺序。

4.4.1 减少栈使用量的方法​

在嵌入式系统中,栈空间有限,因此在编写应用程序时,尽量减少栈使用量可以提高系统的可靠性和性能。以下是常用方法:

  • 编写只需要少量变量的小函数
  • 避免使用大型局部结构体和数组
  • 避免递归
  • 尽量减少函数中每个时刻正在使用的变量数量
  • 使用 C 语言的块作用域语法,并仅在需要时声明变量,以便不同作用域可以共享同一块内存