PPC E500内核寄存器

ABI手册中规定用户编程是需要注意的:

1.r0  存放LR寄存器的值,即函数的返回地址。

2.r1  PPC处理器没有在指令级别上支持堆栈,没有专门的堆栈类寄存器,ABI规定使用r1保存栈顶指针。

3.r3-r4 存放程序的返回值。

4.r3-r10 用来传递函数的参数,不够则使用堆栈进行传递,尽量控制在8个参数范围内这样可以提高函数的调用效率。

5.r13 用来存放数据段的基地址。

6.r14-r31 用来存放临时变量的,程序员可以自用使用。

 

如下是一个测试函数:

#include <stdio.h>

#define ONE 1
int justForTest(int a,int b,int c)
{
 int t1=0,t2=0,t3=0;
 
 t1 += a;
 t2 += b;
 t3 += c; 
 t3 += ONE;
 
 return t3;
}

 

执行ccppc -E d:/test.c 进行预编译后的结果:

/*头文件进行了展开*/

int justForTest(int a,int b,int c)
{
        int t1=0,t2=0,t3=0;


        t1 += a;
        t2 += b;
        t3 += c;
        t3 += 1 ;  //只是对宏进行了简单的替换

        return t3;
}

 

执行ccppc -S d:/test.c生成的汇编代码:

 .file "test.c"
gcc2_compiled.:
 .section ".text"
 .align 2
 .globl justForTest
 .type  justForTest,@function
justForTest:
 stwu 1,-48(1)  /*stwu RS,D(RA)与stw RS,D(RA)格式一样,只是它执行后会将RA寄存器的值更新为RA+D。这里可以看出来

                          每一个帧栈结构占有48个字节,把r1的值存到了栈顶*/
 stw 31,44(1)  /*r31中存放了指向前一个帧栈的指针,即上一个帧栈的栈顶*/
 mr 31,1         /*把栈顶指针拷贝到r31中*/
 stw 3,8(31)    /*r3、r4、r5用来保存函数的参数,把三个参数压入堆栈*/
 stw 4,12(31)
 stw 5,16(31)
 li 0,0
 stw 0,20(31)
 li 0,0
 stw 0,24(31)
 li 0,0
 stw 0,28(31)
 lwz 0,20(31)
 lwz 9,8(31)
 add 0,0,9
 stw 0,20(31)
 lwz 0,24(31)
 lwz 9,12(31)
 add 0,0,9
 stw 0,24(31)
 lwz 0,28(31)
 lwz 9,16(31)
 add 0,0,9
 stw 0,28(31)
 lwz 9,28(31)
 addi 0,9,1
 stw 0,28(31)
 lwz 0,28(31)
 mr 3,0           /*把函数的返回值写入到r3*/
 b .L2
.L2:
 lwz 11,0(1)
 lwz 31,-4(11)    /*保留指向当前帧栈的指针到r31,以便下一个帧栈用来形成一个帧栈链表用*/
 mr 1,11
 blr
.Lfe1:
 .size  justForTest,.Lfe1-justForTest
 .ident "GCC: (GNU) gcc-2.96 (2.96+ MW/LM) 19990621 AltiVec VxWorks 5.5"

 

还可以通过反汇编的方式获取汇编代码objdumpppc -d test.o > 1这样获得的汇编代码看起来更容易懂

test.o:     file format elf32-powerpc

Disassembly of section .text:

00000000 <justForTest>:
   0: 94 21 ff d0  stwu r1,-48(r1)
   4: 93 e1 00 2c  stw r31,44(r1)
   8: 7c 3f 0b 78  mr r31,r1
   c: 90 7f 00 08  stw r3,8(r31)
  10: 90 9f 00 0c  stw r4,12(r31)
  14: 90 bf 00 10  stw r5,16(r31)
  18: 38 00 00 00  li r0,0
  1c: 90 1f 00 14  stw r0,20(r31)
  20: 38 00 00 00  li r0,0
  24: 90 1f 00 18  stw r0,24(r31)
  28: 38 00 00 00  li r0,0
  2c: 90 1f 00 1c  stw r0,28(r31)
  30: 80 1f 00 14  lwz r0,20(r31)
  34: 81 3f 00 08  lwz r9,8(r31)
  38: 7c 00 4a 14  add r0,r0,r9
  3c: 90 1f 00 14  stw r0,20(r31)
  40: 80 1f 00 18  lwz r0,24(r31)
  44: 81 3f 00 0c  lwz r9,12(r31)
  48: 7c 00 4a 14  add r0,r0,r9
  4c: 90 1f 00 18  stw r0,24(r31)
  50: 80 1f 00 1c  lwz r0,28(r31)
  54: 81 3f 00 10  lwz r9,16(r31)
  58: 7c 00 4a 14  add r0,r0,r9
  5c: 90 1f 00 1c  stw r0,28(r31)
  60: 81 3f 00 1c  lwz r9,28(r31)
  64: 38 09 00 01  addi r0,r9,1
  68: 90 1f 00 1c  stw r0,28(r31)
  6c: 80 1f 00 1c  lwz r0,28(r31)
  70: 7c 03 03 78  mr r3,r0
  74: 48 00 00 04  b 78 <justForTest+0x78>
  78: 81 61 00 00  lwz r11,0(r1)
  7c: 83 eb ff fc  lwz r31,-4(r11)
  80: 7d 61 5b 78  mr r1,r11
  84: 4e 80 00 20  blr

 

     总之,使用C语言时不需要考虑对帧栈的维护,整个帧栈机构的维护由C编译器完成。但是汇编语言中必须自己来维护,可以先使用C语言写一个函数的基本架子,将所有的函数参数、变量都写进去,然后使用C编译器生成汇编代码,此时生成的汇编代码将能自动维护帧栈结构了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值