assembly - UEFI引导服务CreateEvent()返回状态EFI_INVALID_PARAMETER

标签 assembly x86 x86-64 nasm uefi

我正在NASM程序集中编写一个简单的UEFI应用程序,并且试图为一个自由运行的计时器创建一个事件,但是对CreateEvent的调用始终返回EFI_INVALID_PARAMETER,我不确定为什么。

section .text

_start:
    mov [ptrSystemTable], rdx
...
    mov rcx, EVT_TIMER
    mov rdx, TPL_APPLICATION
    mov r8, 0
    mov r9, 0
    lea rbx, [ptrTimerEvent]
    push rbx

    mov rax, [ptrSystemTable]
    mov rax, [rax + EFI_SYSTEM_TABLE.BootServices]
    call [rax + EFI_BOOT_SERVICES.CreateEvent]

    cmp rax, EFI_SUCCESS
    jne errorCode
...
section .data    
    ptrSystemTable  dq  0          
    ptrTimerEvent   dq  0
; Include file with a bunch of definitions and structures

EVT_TIMER               equ 0x80000000
TPL_APPLICATION         equ 4

%macro POINTER 0
    RESQ 1
    alignb 8
%endmacro

struc EFI_SYSTEM_TABLE
...
    .BootServices       POINTER
...
endstruc

struc EFI_BOOT_SERVICES
...
    .CheckEvent         POINTER
...
endstruc


根据UEFI规范中的2.3.4.2详细调用约定:

The integer values are passed from left to right in Rcx, Rdx, R8, and R9 registers. The caller passes arguments five and above onto the stack.



所以我要传递的参数应该是:
 Type --> EVT_TIMER
 NotifyTpl --> TPL_APPLICATION
 NotifyFunction --> 0
 *NotifyContext --> 0
 *Event --> &ptrTimerEvent  

该规范给出了CreateEvent可以返回EFI_INVALID_PARAMETER的多种原因,但我看不到它们中的任何一个在代码中如何发生。任何指针或问题将不胜感激。

最佳答案

UEFI的调用约定在调用之前始终在堆栈顶部具有0x20字节的可用空间。如果存在第五个及后续参数,则从堆栈的偏移量0x20开始。

它与Windows/Microsoft x64调用约定相同。

同样,在调用之前,堆栈必须与0x10的倍数对齐。输入该函数时,堆栈将对齐为8的奇数倍,因此必须在函数内将堆栈指针调整为8的奇数倍。

default rel          ; Use RIP-relative symbol addressing, not absolute

section .text

_start:
    sub rsp, 0x28              ; 0x20 bytes of shadow space + 8 to align the stack
    mov [ptrSystemTable], rdx
...
    mov rcx, EVT_TIMER
    mov rdx, TPL_APPLICATION
    mov r8, 0
    mov r9, 0
    lea rax, [ptrTimerEvent]
    mov [rsp+0x20], rax         ; 5th arg on the stack above the shadow space

    mov rax, [ptrSystemTable]
    mov rax, [rax + EFI_SYSTEM_TABLE.BootServices]
    call [rax + EFI_BOOT_SERVICES.CreateEvent]

    cmp rax, EFI_SUCCESS
    jne errorCode
...

关于assembly - UEFI引导服务CreateEvent()返回状态EFI_INVALID_PARAMETER,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60582920/

相关文章:

assembly - 分析 AVX2 中的比较结果

c++ - 从 vc++ 调用存储在堆中的代码

linux - nasm x86 初学者使用 C 调用 - printf scanf

c - 为什么我能够在 Linux 内核模块中执行浮点运算?

linux - 为什么x86-64 Linux系统调用会修改RCX,这个值是什么意思?

c++ - 这个指令错了吗? (movabs %al,0xe400000000004049)

assembly - x86 指令 PCLMULQDQ 中的 "P"前缀代表什么?

x86 - 在 64 位 ASM 中。有没有一种只注意寄存器底部 32 位的好方法

gcc - 了解汇编列表输出中的 GCC 浮点常量

linux x64加法程序