Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30595
  • 博文数量: 4
  • 博客积分: 280
  • 博客等级: 二等列兵
  • 技术积分: 70
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-19 13:42
文章分类
文章存档

2009年(1)

2008年(3)

我的朋友

分类:

2008-05-24 14:01:33

现在mips上支持3种函数调用约定。
1.
被称为o32old 32bit)的,现在被广泛应用的传统的约定
2.n64
new 64bit, 次模式中c语言常用的指针,和long 都会被看成是是64bit,这将会带来很大程度上的误解。也会带来很多现在的程序无法执行。
3.n32
new 32 bit,此模式能够很好的兼容现在广泛应用的代码。参数传递上和N64相同,但是c语言指针,和long 还会以32位来进行编译。 同时为了支持64位,采用long long类型。


下面介绍一下调用约定(除非特别提示,都是以o32为例)

mips
的函数调用有点意思, 它会将函数的部分参数直接保存在寄存器中,一般是[a0a3],来提高性能。

在继续之前,有必要说做一下名词解释 :)(不要怪偶罗嗦哈,慢慢来就知道了)
任何函数调用是都需要堆栈, 并有sp指向栈底。而以sp起始的至少16字节就被mips的标准叫做一个---“堆栈参数结构的咚咚。

在使用堆栈参数结构的时候有相当多的规则。简单说一下。
1.
除非第一个参数是浮点参数,否则不能够讲后续参数传递到FP寄存器中.
2.
如果第一个参数是浮点参数,他会被传到FP,并且后续的浮点参数也将会被传递到FP (my god,像费话了)
3.
如果函数的结构类型过大,以至于v0v1不够存放,此函数的调用这会做而外处理。

现在,结束枯燥的叙述,举例说明
1.
一般调用时的情景。

count = memcpy(pd,ps,count);

堆栈描述图                       寄存器描述
|        |                      |        |                               
|        |                      |        | a3    
没用到
|        |                      |        |
|        | sp+12
|        |                      |        |a2    count
个数               
|        |                      |        |                          
|        | sp+8
|        |                      |        |a1    ps
指针的内容            
|        |                      |        |                    
|        | sp+4
|        |                      |        |a0    pd
指针的内容
|        |                      |        |
|        | sp+0              |        |

注:此时的内存堆栈中的数据是无意义的,

 

2.涉及到大小端及对齐的情况

 

Struc thing

{

Char a;

Short s;

Int value;

} ={“z”,46,10000}

 

Void  dosmothing(thing);

 

堆栈描述图                       寄存器描述
|        |                      |        | a3    
|        |                      |        |
|        | sp+12
|        |                      |        |a2   
|        |                      |        |
|        | sp+8
|        |                      |        |a1  10000 
|        |                      |        |
|        | sp+4
|        |                      |        |a0  46 
|        |                      |        | 

|        |                      |       |  填充物           
|        | sp+0              |        |    z                      

 

大端:就是高位字节的存储在低地址上

32位的寄存器来表示的话,如下

 

 Z     xxxx           46

31-24  23-16          15 – 0  (bit)

不建议直接将struct的东西作为参数传递, 也不建议直接将一个struct作为返回值。

因为如果返回值过大,无法装入v0v1  此时额外动作花费很大时间, 需要在调用者的堆栈中分配一块空间,然后被调用这返回的大结构数据拷贝到这里。一般情况下,a0 存放调用的第一个参数, 返回的时候v0指向返回的结构。

 








阅读(4712) | 评论(0) | 转发(0) |
0

上一篇:linux device driver 之安全休眠

下一篇:MIPS_TLB

给主人留下些什么吧!~~