c文件的局部变量不是在堆栈中创建的,它的GCC编译代码,

c文件的局部变量不是在堆栈中创建的,它的GCC编译代码,,c,gcc,stack,bios,uefi,C,Gcc,Stack,Bios,Uefi,我在UEFI EDK2 Bios源代码中工作。我们在EDK2源代码中创建了一个与平台相关的新包。我发现我们添加的平台相关代码有一个奇怪的问题 当我进行源代码级调试时,我注意到 C函数中的局部变量在使用GCC编译时不会在堆栈中创建 当使用VisualStudio编译相同的UEFI代码时,将在堆栈中创建C函数中的局部变量 我在一个模拟环境中执行这段代码,在那里我可以看到堆栈库、所有段寄存器、当前执行的代码、内存等 它是一个多核系统,但只启用了引导处理器。如果你阅读C11语言规范,你会发现它从来没有提

我在UEFI EDK2 Bios源代码中工作。我们在EDK2源代码中创建了一个与平台相关的新包。我发现我们添加的平台相关代码有一个奇怪的问题

当我进行源代码级调试时,我注意到 C函数中的局部变量在使用GCC编译时不会在堆栈中创建

当使用VisualStudio编译相同的UEFI代码时,将在堆栈中创建C函数中的局部变量

我在一个模拟环境中执行这段代码,在那里我可以看到堆栈库、所有段寄存器、当前执行的代码、内存等


它是一个多核系统,但只启用了引导处理器。如果你阅读C11语言规范,你会发现它从来没有提到堆栈或堆栈帧,也没有在堆栈上放置变量。在C语言中,不需要将自动变量放入任何类型的堆栈中

程序如何存储自动变量(即那些在函数范围内定义但没有
static
关键字的变量)完全取决于编译器。在过去,大多数编译器在系统堆栈上为参数、返回地址和局部变量创建空间。在现代,这已经不受欢迎了,因为处理器通常有很多寄存器,如果可能的话,将局部变量和函数参数保存在寄存器中会更有效

编译器需要在堆栈上存储自动变量的原因只有两个:

  • 变量和参数太多,无法全部放入寄存器

  • 函数获取变量的地址(不能有指向寄存器的指针)

  • 所以gcc可能决定不需要为变量创建堆栈空间,而是将其放入寄存器中。visualstudioc编译器一直因被微软忽视而臭名昭著,因此它可能不太符合关于自动变量的现代思想

    此外,您会发现编译器经常优化变量。如果对变量不做任何有用的操作,编译器可能会决定它根本不需要它。例如,在下面的代码中

    int f()
    {
        int i;
    
        for (i = 0 ; i < 10 ; ++i);
        return 0;
    }
    
    intf()
    {
    int i;
    对于(i=0;i<10;++i);
    返回0;
    }
    

    循环是空的,所以编译器知道它可以扔掉它,然后它不需要变量,所以它也会扔掉它

    也许GCC将变量放在寄存器中,或者优化它,因为它没有被使用?您没有描述为什么这是一个问题(当然也没有显示任何代码)。也许这是一个优化问题?局部变量(又称自动变量)不必在堆栈上。