UEFI ASM_PFX 简介
在UEFI中,asm_pfx
是一个宏定义,用于指定汇编代码中的前缀。它的作用是为了在不同的编译器和不同的体系结构上生成正确的汇编代码。具体来说,asm_pfx
会根据编译器和体系结构的不同,生成不同的前缀,以确保汇编代码的正确性和可移植性。在UEFI中,asm_pfx
通常用于定义汇编代码中的指令,例如 mov
或 jmp
等指令。
UEFI中的汇编代码,目前支持的有
.S
、.asm
和.nasm
格式的汇编:
- 第一个是 AT&T 汇编;
- 后两个是 Intel 汇编,只是使用的汇编样式稍有不同。
在 ARM 体系结构中,asm_pfx宏通常用于定义汇编代码中的指令前缀。例如,在ARMv8架构中,asm_pfx可以被定义为 “.arch armv8-a
”,以确保汇编代码能够正确地在ARMv8处理器上运行。此外,asm_pfx 还可以用于定义其他指令前缀,例如".thumb
"或".fpu neon
",以支持不同的指令集和处理器特性。总之,asm_pfx在UEFI中的使用与在ARM中的使用是相似的,都是用于确保汇编代码的正确性和可移植性。
UEFI 汇编调用C函数
如下代码所示,在汇编代码中可以使用下面语句调用C文件中读去CPU ID的函数:
//el1_entry:
el1_entry_func:
bl ASM_PFX(get_cpu_id)
- 读取 CPU ID 的函数实现如下:
uint64_t get_cpu_id(void)
{
uint64_t mpidr_el1;
asm volatile("mrs %0, mpidr_el1" : "=r" (mpidr_el1));
return mpidr_el1;
}
UEFI 汇编调用带参数的C函数
- 一、汇编代码传一个参数给C函数
mrs x0, mpidr_el1
ldr x4, =ASM_PFX(debug_info)
blr x4
dfd_info
函数实现如下:
void debug_info(uint64_t val)
{
Print(L"---line:%d val:0x%016x ---\n", __LINE__, val);
}
- 二、汇编代码传2个参数给C函数
以判断Armv8/v9 当前系统所处EL为例,在ARMv9架构中,可以通过读取CurrentEL寄存器的值来确定系统当前所处的EL级别,例如,如果CurrentEL寄存器的值为0x2,则表示系统当前处于EL2,要访问它,可以使用MRS(Move to Register from System)指令,将其值加载到通用寄存器中。例如,使用以下汇编代码可以将CurrentEL寄存器的值加载到x0寄存器中:
MOV x0, #0
MOV x1, #1
MRS x0, CurrentEL
ldr x4, =ASM_PFX(dfd_info)
blr x4
对应的 debub_info
函数实现如下:
void dfd_info(uint64_t val, uint64_t val1)
{
Print(L"---line:%d val:0x%016x mark:%d---\n", __LINE__, val, val1);
}
CurrentEL 寄存器:
UEFI 添加头文件搜索路径
需要再对应的 dec 文件中添加include目录,以edk2/ArmPkg/ArmPkg.dec
为例:
Library/ArmLib/test/include
这样 test 目录下的include 目录会添加到头文件的搜索路径中。