PowerPC中的ABI及相关信息

ABI或EABI(Extend ABI)通常是处理器体系结构的一部分,它与平台是紧密相连的。我们可以把ABI理解为一套规则,这套规则一般包括定义了以下内容:

1:应用程序如何发出系统调用来trap到内核态。
2:如何使用机器的寄存器。比如,RISC处理器的ABI就要规定用那个通用寄存器来作stack pointer和frame pointer。
3:规定如何进行procedure call。

2, 3是最重要的。而且特定于那个平台的编译器和链接器实现都要遵循这些约定。

首先是寄存器的使用规则:
GPR0:普通用户不能使用此寄存器。GCC编译器使用此寄存器保存LR寄存器。Linux使用该寄存器传递系统调用号。
GPR1:该寄存器保存堆栈的栈顶指针,也就是SP指针。
GPR2:普通用户不能使用此寄存器。Linux用该寄存器保存当前进程的进程描述符指针。
GPR3-GPR4:使用这两个寄存器保存程序的返回值。
GPR3-GPR10:用于传递函数参数。当参数多于8个时,使用存储器传送。
GPR11-GPR12:一般用户不能使用此寄存器。Linux有时使用这两个寄存器存放临时变量。
GPR13:该寄存器用于保存sdata段的基地址指针。类似于MIPS中的$28(GP)寄存器。
GPR14-GPR31:程序可以自由使用这几个寄存器。

其次是运行的堆栈结构:以E500为例:
       ============================================
        |            Previous BacK Chain                                                     |  <---
        ============================================     |
        |     32-bit General Register Save Area                                        |     |
        ============================================     |
        |               CR Save Area                                                             |     |
        ============================================     |
        |       Padding to 8-byte Boundry                                                 |     |
        ============================================     |
        |     64-bit General Register Save Area                                        |     |
        ============================================     |
        |Local Variable Space(and required padding)                              |     |
        ============================================     |
        |          Parameter Save Area                                                      |     |
        ============================================     |
        |             LR Save Word                                                             |     |
        ============================================     |
        |     SP ->    Back Chain                                                             |   ---
        ============================================    
                                         
         
Back Chain:当前栈顶指针寄存器SP保存上一个栈桢的Back Chain的地址。当函数返回时,SP指回上一个栈桢。
LR Save Word:保存LR寄存器的值,用于函数返回。(MIPS也会保存RA寄存器)
Parameter Save Area:用于存放函数参数。当参数多于8个时才用此区域。
Local Variable Area:用于存放临时变量。E500会首先选择GPR14-GPR31保存临时变量,只有当寄存器不够用时才用此区域。
64-bit General Register Save Area:保存函数用到的64位寄存器。
CR Save Area:保存CR寄存器。
32-bit General Register Save Area:保存函数用到的32位寄存器。

注意,根据具体的函数不一样,栈桢的内容是不一样的,最小的栈桢只有Back Chain,LR Save Word和2个字的padding区域,共16字节。

最后PowerPC中的函数调用:

由于PowerPC中没有真正的堆栈指针SP以及堆栈指令push,pop等,所以这些都需要模拟。AB
I(Application Binary Interface)定义了相当的关于这方面的规范。查看汇编指令可以看
到,直接使用偏移地址存储数据来模拟这样的堆栈。进入一个函数,堆栈根据所需要的大小
向下增长,当前堆栈指针sp存入0位置,将LR存入原先堆栈+4位置,然后将非易失性寄存器
存入堆栈中,局部变量,包括参数都放在堆栈中。

以下使用一VxWorks的入口函数简单分析下,中间插入部分汇编。
void usrInit (int startType)
{
        stwu        r1,-0x20(r1);    /* 保存原先sp,同时更新sp */
        mflr        r0;                 /* LR 获取 */
        stw         r31, 0x1C(r1);   /* 非易失性reg保存,这只保存r31 */
        stw         r0,  0x24(r1);   /* LR存储在上个堆栈sp+4处 */
        mr          r31, r1            /* r31为当前sp值 */
        stw         r3,  0x8(r31)    /* 局部变量,也就是startType */
       
    sysStart (startType);            
        lwz         r3,  0x8(r31)
        crclr       0x6
        bl          0x1E11F8BC       /* 函数跳转 */
         
    cacheLibInit (USER_I_CACHE_MODE, USER_D_CACHE_MODE);
        li          r3, 01
        li          r4, 01
        bl          0x1E80EE0
 
    excVecInit ();                    
    sysHwInit ();                    
    usrCacheEnable ();                
    usrKernelInit ();                
}
        lwz         r11, 0x0(r1)      /* SP恢复 */
        lwz         r0,  0x4(r1)
        mtlr        r0                  /* LR 恢复 */
        lwz         r31, -0x4(r11)   /* R31恢复 */
        mr          r1,  r11
        blr                             /* usrInit函数返回 */

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值