我在UEFI EDK2 Bios源工作。我们在EDK2源中创建了一个与平台相关的新包。我发现我们添加的平台相关代码存在一个奇怪的问题。
当我进行源代码级调试时,我注意到了 当使用GCC编译时,C函数中的局部变量不会在堆栈中创建。
使用visual studio编译相同的UEFI代码然后在C函数中创建局部变量将在堆栈中创建。
我在Simulation环境中执行此代码,我可以看到堆栈库,所有段寄存器,当前执行代码,内存等。
它是一个多核系统,但只启用了启动带处理器
答案 0 :(得分:0)
如果您阅读C11语言规范,您会发现它从未提及堆栈或堆栈帧或将变量放在堆栈上。 C中没有要求将自动变量放入任何类型的堆栈中。
程序如何存储自动变量(即在函数范围内定义但没有static
关键字的变量)完全取决于编译器。在过去,大多数编译器在系统堆栈上为参数,返回地址和局部变量创建了空间。在现代,这已经不再受欢迎,因为处理器通常具有大量寄存器,并且如果可能的话,将局部变量和函数参数保存在寄存器中会更有效。
编译器需要在堆栈上存储自动变量的原因只有两个:
有太多的变量和参数将它们全部放在寄存器中
该函数获取变量的地址(您不能指向寄存器)
因此,gcc可能会决定不需要为变量创建堆栈空间,而是将其放入寄存器中。 Visual Studio C编译器总是因为被微软忽视而臭名昭着,所以它可能不是关于自动变量的现代想法。
此外,您会发现编译器通常会优化变量。如果你没有对你的变量做任何有用的事情,编译器可能会认为它根本不需要它。例如,在以下代码中
int f()
{
int i;
for (i = 0 ; i < 10 ; ++i);
return 0;
}
循环是空的,因此编译器知道它可以抛弃它然后它不需要变量,因此它也会抛弃它。