Pet*_*ost 5 x86 assembly 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
...
Run Code Online (Sandbox Code Playgroud)
section .data
ptrSystemTable dq 0
ptrTimerEvent dq 0
Run Code Online (Sandbox Code Playgroud)
; 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
Run Code Online (Sandbox Code Playgroud)
根据 UEFI 规范中的 2.3.4.2 详细调用约定:
整数值在 Rcx、Rdx、R8 和 R9 寄存器中从左到右传递。调用者将参数 5 及以上传递到堆栈上。
所以我传递的参数应该是:
Type --> EVT_TIMER
NotifyTpl --> TPL_APPLICATION
NotifyFunction --> 0
*NotifyContext --> 0
*Event --> &ptrTimerEvent
Run Code Online (Sandbox Code Playgroud)
规范给出了CreateEvent可能 return 的多种原因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
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
223 次 |
| 最近记录: |