《UEFI内核导读》如果没有内存,程序代码还能不能执行?

文章介绍了在冯洛伊曼架构的计算机中,即使没有内存,如何通过IntelStreamingSIMDExtensions(SSE)支持的XMM和MMX寄存器进行子过程的调用。通过将通用寄存器的数据存储在这些寄存器中,可以模拟call/ret调用,使得在堆栈未准备好时仍能执行代码和过程调用。
摘要由CSDN通过智能技术生成

==============================

敬请关注:“固件C字营

    ==============================

       首先思考一个问题,冯洛伊曼架构的计算机如果没有内存,代码能被否正常执行?过程(函数)能不能被相互调用?答案是肯定的,其中的一个实现方法如下。这里只介绍汇编语言的相互调用,如果要用高级语言比如C语言,需要自己实现编译器和ABI才行。

      IA-32支持Intel Streaming SIMD Extensions (Intel SSE),不同版本的SSE支持不同的编程模型和指令。SSE支持8个128bit的XMM寄存器,8个64bit MMX寄存器可以在UEFI环境下使用特定的pinsrd/ pinsrw/ pshufd/movd指令在通用寄存器之间传递数据,进而可以把XMM、MMX寄存器当做普通32bit数据暂存器来使用。如此,我们就可以在堆栈没有准备好的情况下使用JMP跳转指令来模拟一般的call/ret方式调用子过程。

       128bit的XMM寄存器可以被拆分成4个slot,分别与通用寄存器(如:EAX)进行数据传递,参考实现如下。

XMM7:EBP - slot 0, EBX - slot 1, ESI - slot 2, EDI - slot 3

XMM6:ESP - slot 0, EAX - slot 1, EDX - slot 2, ECX - slot 3

XMM5:slot 0 for calling stack,slot 1 for uCode status

MM0: BIST State

MM5: Save time-stamp counter value high32bit

MM6: Save time-stamp counter value low32bit.

MM7: calling stack

例1:

       子过程Function是需要被调用的过程,在堆栈还没有准备好的情况下,可以使用如下代码来实现,只要在Function内部保持通用寄存器不被修改(具体方法是把通用寄存器保存在MMX和XMM寄存器当中)就可以保证Function的调用不会破坏执行环境。

CALL_MMX Function  ;调用子过程,返回地址保存在MM7寄存器

RET_ESI                       ;返回到主过程

例2:

       其中SXMMN和LXMMN宏分别为存储和读取ReturnAddress即调用CALL_XMM指令之后的下一条指令的地址。

CALL_XMM Function  ;调用子过程,返回地址保存在XMM5-Slot0寄存器

RET_XMM                   ;返回到主过程

例3:同理我们也可以使用ebp暂存过程返回地址。

更多导读,尽情期待!

==============================

   敬请猛戳下面链接,关注&转发

敬请关注we-hat“:“固件C字营

点击左下角“分享”,快乐更多人

==============================

we-chat固件C字营

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值