全部博文(4)
分类:
2008-05-24 14:01:33
现在mips上支持3种函数调用约定。
1.被称为o32(old 32bit)的,现在被广泛应用的传统的约定
2.n64(new 64bit), 次模式中c语言常用的指针,和long 都会被看成是是64bit,这将会带来很大程度上的误解。也会带来很多现在的程序无法执行。
3.n32(new 32 bit),此模式能够很好的兼容现在广泛应用的代码。参数传递上和N64相同,但是c语言指针,和long 还会以32位来进行编译。
同时为了支持64位,采用long long类型。
下面介绍一下调用约定(除非特别提示,都是以o32为例)
mips的函数调用有点意思, 它会将函数的部分参数直接保存在寄存器中,一般是[a0,a3],来提高性能。
在继续之前,有必要说做一下名词解释 :)(不要怪偶罗嗦哈,慢慢来就知道了)
任何函数调用是都需要堆栈, 并有sp指向栈底。而以sp起始的至少16字节就被mips的标准叫做一个---“堆栈参数结构”的咚咚。
在使用堆栈参数结构的时候有相当多的规则。简单说一下。
1.除非第一个参数是浮点参数,否则不能够讲后续参数传递到FP寄存器中.
2.如果第一个参数是浮点参数,他会被传到FP中,并且后续的浮点参数也将会被传递到FP中 (my god,像费话了)
3.如果函数的结构类型过大,以至于v0,v1不够存放,此函数的调用这会做而外处理。
现在,结束枯燥的叙述,举例说明
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作为返回值。
因为如果返回值过大,无法装入v0,v1 此时额外动作花费很大时间,
需要在调用者的堆栈中分配一块空间,然后被调用这返回的大结构数据拷贝到这里。一般情况下,a0 存放调用的第一个参数, 返回的时候v0指向返回的结构。