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

基于EFI的OS开发中MS_ABI参数传递问题求助

修复EFI汇编代码中的MS_ABI调用问题

你的代码存在几个关键问题,直接导致了系统冻结:

  • systable内存分配错误:用.byte 122只分配了1字节,但x86_64下EFI_SYSTEM_TABLE指针是8字节,存储rcx时会越界覆盖后续内存,破坏系统数据。必须把systable定义为8字节存储单元,比如.quad 0。

  • 字符串不符合EFI要求:EFI文本输出函数需要UTF-16LE编码且以空字符结尾的字符串。你只定义了单个'H'且没有结尾空字符,会导致函数读取非法内存。

  • MS_ABI成员函数调用规则错误:EFI协议函数是成员函数,调用时必须把协议实例指针(ConOut地址)作为第一个参数放入RCX(MS_ABI的this指针),字符串指针作为第二个参数放入RDX。你的代码没设置RCX,直接调用函数会导致参数完全错误。

  • 栈未对齐:MS_ABI要求调用函数前栈必须16字节对齐。efimain被EFI调用时栈是对齐的,但执行call rax前,栈因之前操作偏移了8字节,需要手动调整。

修正后的代码:

.intel_syntax noprefix
.global efimain 

efimain:
    # 保存EFI_SYSTEM_TABLE指针(8字节,避免越界)
    mov [systable], rcx 

    # 获取ConOut协议指针:EFI_SYSTEM_TABLE->ConOut(偏移0x40)
    mov rcx, [systable]
    mov rcx, [rcx + 0x40]

    # 获取OutputString函数地址:EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL->OutputString(偏移0x18)
    mov rax, [rcx + 0x18]

    # 设置第二个参数:UTF-16LE字符串指针
    mov rdx, Msg 

    # 调整栈到16字节对齐(call会压入8字节返回地址,当前rsp偏移8字节,减8后对齐)
    sub rsp, 8
    call rax
    add rsp, 8

    # 返回EFI_SUCCESS(0)
    mov rax, 0 
    ret

# 存储EFI_SYSTEM_TABLE指针(8字节)
systable: 
    .quad 0 

# UTF-16LE字符串:"Hello" + 空结尾
Msg:
    .word 'H', 'e', 'l', 'l', 'o', 0

修正说明:

  1. 把systable改为.quad 0,确保能容纳8字节指针,避免内存越界。
  2. 调用OutputString时,先将ConOut指针放入RCX(this指针),字符串指针放入RDX,严格遵循MS_ABI成员函数调用规则。
  3. 添加栈对齐调整,避免因栈不对齐触发的异常。
  4. 修正字符串为标准UTF-16LE格式并添加空结尾,符合EFI函数要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:06:23