分享

一起学习计算机第0012篇【UEFI中64位汇编的常识】

 黄昌易 2019-03-30

为什么要写这个呢?因为有时候要看64位的汇编代码,如果不知道这些常识的话,看64位汇编代码会很困难的。

32位和16位就不提了,因为大学本科的教材中都有。下面补充一点64位的。

01、寄存器的长度发生了变化,相应的名称也变化了。比如:EAX,EBX,ECX,EDX 这些仍然存在,只是扩展成了新的64位寄存器RAX,RBX,RCX,RDX等。

02、新增了很多64位寄存器。例如:R8,R9,R10,R11,R12,R13,R14,R15。

03、调用方式发生了变化。第1个参数到第4个参数,用 RCX,RDX,R8,R9 传递,从第5个参数开始,用堆栈来传递。

04、有一个奇特的现象:被调用的函数会把传来的参数暂存到主调函数的堆栈中。因此,主调函数在调用一个函数之前,会在堆栈中多留出一些空间。

下面还是拿之前的汇编代码来讲解:

mov [rsp+10h], rdx ;SystemTable

mov [rsp+8], rcx ;句柄ImageHandle

sub rsp, 28h

mov rax, [rsp+28h+10h]

mov rax, [rax+40h] ;获取ConOut

lea rdx, [szOK] ;要显示的字符串

mov rcx, [rsp+28h+10h]

mov rcx, [rcx+40h] ;获取ConOut

call QWORD[rax+8] ;调用OutputString

xor eax, eax

add rsp, 28h

retn

第1行和第2行是把传来的参数 rdx,rcx 暂存到主调函数的堆栈里。

第4行又到主调函数的堆栈中,取出刚才暂存的值。

为什么第4行不直接用 rdx 呢?多此一举干什么呢?本人猜测原因可能是:编译器把传来的参数,也就是 rdx,rcx往主调函数的堆栈里存起来。这样 rdx,rcx 就可以当临时变量使用了,也就是说, rdx,rcx可以放其它的值,等到想用之前的值,就到主调函数的堆栈里去取出来。

最后补充一点:为什么要写成[rsp+28h+10h]?不写成[rsp+38h]?原因是:为了方便理解程序。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多