基于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
修正说明:
- 把systable改为
.quad 0,确保能容纳8字节指针,避免内存越界。 - 调用OutputString时,先将ConOut指针放入RCX(this指针),字符串指针放入RDX,严格遵循MS_ABI成员函数调用规则。
- 添加栈对齐调整,避免因栈不对齐触发的异常。
- 修正字符串为标准UTF-16LE格式并添加空结尾,符合EFI函数要求。
内容的提问来源于stack exchange,提问作者lucas
相关产品推荐
相关产品推荐

