UEFI 学习 (2) —— 汇编 与 C 的调用
突然觉得很有意思,跌跌撞撞的解决了。
最近在研究怎么在 UEFI 的 .asm 文件中调用 C 函数,老是运行宕机,搞不懂出错在哪里。
后来洗澡的时候,想着应该是程序在 C 的时候没有返回到 汇编中,才出错,但是要怎么证实呢?也就需要对我的程序进行反汇编。那咋搞?????
废话不多说,看代码…
1. C 代码
extern UINT64 asm_sum (UINT64 v1, UINT64 v2, UINT64 v3, UINT64 v4);
void myprint(void)
{
Print(L"call c myprint test ok!\n");
return;
}
EFI_STATUS
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINT64 v1 = 0x0100000000; // p
UINT64 v2 = 0x011532E000; // pe
UINT64 v3 = 0x12230912; // p1
UINT64 v4 = 0x5555aaaa; // p2
UINT64 result;
result = asm_sum(v1, v2, v3, v4);
Print(L" %010llx \n", result);
return EFI_SUCCESS;
}
2. 汇编代码
extern myprint:near
.code
asm_sum PROC
mov rdi, rcx
mov rax, rdx
mov [rdi], r8
mov [rdi+4], r9
call myprint
ret 0
asm_sum ENDP
END
3. 问题
call c myprint test ok!
代码打印这句话后宕机,只能重启电脑或者虚拟器。
4. 怀疑点
在运行 myprint 时未能正确返回,如何证实?
5. 查看反汇编代码
myprint PROC ; COMDAT
; 16 : {
$LN4:
sub rsp, 40 ; 00000028H
; 17 : Print(L"call c myprint test ok!\n");
lea rcx, OFFSET FLAT:??_C@_1DC@LELNIGMI@?$AAc?$AAa?$AAl?$AAl?$AA?5?$AAc?$AA?5?$AAm?$AAy?$AAp?$AAr?$AAi?$AAn?$AAt?$AA?5?$AAt?$AAe?$AAs?$AAt?$AA?5?$AAo?$AAk?$AA?$CB?$AA?6?$AA?$AA@
call Print
myprint ENDP
_TEXT ENDS
END
代码在 call print 后没有返回,和之前的怀疑是符合的。
将 C 代码中的 myprint 子函数改为:
extern UINT64 asm_sum (UINT64 v1, UINT64 v2, UINT64 v3, UINT64 v4);
int myprint(void)
{
Print(L"call c myprint test ok!\n");
return 0;
}
反汇编代码正确:
myprint PROC ; COMDAT
; 16 : {
$LN4:
sub rsp, 40 ; 00000028H
; 17 : Print(L"call c myprint test ok!\n");
lea rcx, OFFSET FLAT:??_C@_1DC@LELNIGMI@?$AAc?$AAa?$AAl?$AAl?$AA?5?$AAc?$AA?5?$AAm?$AAy?$AAp?$AAr?$AAi?$AAn?$AAt?$AA?5?$AAt?$AAe?$AAs?$AAt?$AA?5?$AAo?$AAk?$AA?$CB?$AA?6?$AA?$AA@
call Print
; 18 : return 0;
xor eax, eax
; 19 : }
add rsp, 40 ; 00000028H
ret 0
myprint ENDP
_TEXT ENDS
END
UEFI 的反汇编代码如何查看?
我是参考罗宾大神的这个链接:https://zhuanlan.zhihu.com/p/343288239
链接: link