You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCC编译EDK2 x64 Shell应用使用可变参数执行VA_ARG触发页错误

问题根因

EDK2 x64架构下,EFIAPI宏对应的是微软x64调用约定,你定义的PrintInts可变参数函数未添加EFIAPI修饰,Linux下GCC默认使用System V AMD64调用约定处理可变参数,和UEFI运行环境要求的调用约定不兼容,导致VA_ARG读取栈参数时地址计算错误,触发页错误。Windows下VS2015默认使用微软x64调用约定,因此代码运行正常。

修复方案
  • 给所有可变参数的UEFI函数增加EFIAPI修饰符,修改后的代码如下:
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/PrintLib.h>
#include <Library/ShellCEntryLib.h>

// 仅新增EFIAPI修饰即可
VOID EFIAPI PrintInts(UINTN n, ...)
{
    VA_LIST vl;
    VA_START(vl, n);
    Print(L"Printing integers:");
    for (UINTN i=0; i<n; i++) {
        UINTN val = 0;
        val = VA_ARG(vl, UINTN);
        Print(L" [%d]", val);
  }
  VA_END(vl);
  Print(L"\n");
}

INTN EFIAPI ShellAppMain(IN UINTN Argc, IN CHAR16 **Argv)
{
    UINTN a = 3;
    UINTN b = 10;
    UINTN c = 9;
    PrintInts(3, a, b, c);
    return 0;
}
  • 确认编译配置中x64架构的GCC编译参数已添加-mabi=ms选项,EDK2官方GCC工具链默认已携带该参数,自定义编译脚本需手动补加。
  • 检查项目头文件引用优先级,确保优先引用EDK2官方头文件,不要引入C标准库的stdarg.h等头文件,避免可变参数宏定义冲突。

内容的提问来源于stack exchange,提问作者davepet1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 16:18:01