我正在用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详细呼叫约定:
整数值在Rcx,Rdx,R8和R9寄存器中从左到右传递。调用者将五个及以上的参数传递到堆栈上。
所以我要传递的参数应该是:
Type --> EVT_TIMER
NotifyTpl --> TPL_APPLICATION
NotifyFunction --> 0
*NotifyContext --> 0
*Event --> &ptrTimerEvent
该规范给出了CreateEvent
可以返回EFI_INVALID_PARAMETER
的多种原因,但是我看不到它们中的任何一个在代码中如何发生。任何指针或问题将不胜感激。
UEFI的调用约定在调用之前,堆栈顶部始终具有0x20字节的可用空间。如果存在第五个及后续参数,则从堆栈的偏移量0x20开始。
而且,在调用之前,堆栈必须对齐0x10的倍数。输入该函数时,堆栈将对齐为8的奇数倍,因此必须在函数内将堆栈指针调整为8的奇数倍。]
section .text
_start:
sub rsp, 0x28
mov [ptrSystemTable], rdx
...
mov rcx, EVT_TIMER
mov rdx, TPL_APPLICATION
mov r8, 0
mov r9, 0
lea rax, [ptrTimerEvent]
mov [rsp+0x20], rax
mov rax, [ptrSystemTable]
mov rax, [rax + EFI_SYSTEM_TABLE.BootServices]
call [rax + EFI_BOOT_SERVICES.CreateEvent]
cmp rax, EFI_SUCCESS
jne errorCode
...