MIPS 栈

    参数传递:如果参数少于4个,通过a0-a3寄存器传递参数,否则其余通过堆栈传递。

    参数作为调用者(caller)栈帧的一部分,4个32bits空间为a0~a3预留(即使参数通过寄存器传递)。被调者(callee)在函数前言部分分配自己的栈空间分配(返回地址/栈帧指针/局部变量),同时栈帧指针(fp)将指向最新的栈空间,并且所有局部变量通过栈帧指针偏移寻址,堆栈指针(sp)不再发生变化。

以下代码调用栈结构如下图所示:

int FunA()
{
    return FunB();
}
int FunB()
{
    return FunC();
}


     

在函数前言部分,往往有如下语句:

00400264 <fun5>:
 400264:      27bdffe0        addiu sp,sp,-32   //分配栈帧
 400268:      afbf001c        sw    ra,28(sp)   //保存返回地址
 40026c:      afbe0018        sw    s8,24(sp)   //保存堆帧指针
 400270:      03a0f021        move  s8,sp       //更新栈帧指针   


    编译器在编译函数时,能够计算出其局部变量以及参数需要的存储空间,在函数前言部分通过偏移sp指针为这些变量分配空间。例如funB()分配的栈空间为:ra+fp+local variables+arguments。

 

///

int fun5(int a,int b, int c,int d,int e)
{
    int abc = e;
    return fun4(a,b,c,d)+ abc;  
}
int main(void)
{
    int ret;
    int a;
    int b;
    int c;
    int d;
    a = 1;
    b = 2;
    c = 3;
    d = 4;
    ret = fun5(a,b,c,d,5);
    return 0;   
}


 

其反汇编代码(无优化选项)

00400264 <fun5>:
  400264:	27bdffe0 	addiu	sp,sp,-32     /*1个局部变量+4个参数+ ra +fp + 1个pad = 32*/
  400268:	afbf001c 	sw	ra,28(sp)
  40026c:	afbe0018 	sw	s8,24(sp)
  400270:	03a0f021 	move	s8,sp
  400274:	afc40020 	sw	a0,32(s8)
  400278:	afc50024 	sw	a1,36(s8)
  40027c:	afc60028 	sw	a2,40(s8)
  400280:	afc7002c 	sw	a3,44(s8)
  400284:	8fc20030 	lw	v0,48(s8)
  400288:	00000000 	nop
  40028c:	afc20010 	sw	v0,16(s8)
  400290:	8fc40020 	lw	a0,32(s8)
  400294:	8fc50024 	lw	a1,36(s8)
  400298:	8fc60028 	lw	a2,40(s8)
  40029c:	8fc7002c 	lw	a3,44(s8)
  4002a0:	0c100084 	jal	400210 <fun4>
  4002a4:	00000000 	nop
  4002a8:	8fc30010 	lw	v1,16(s8)
  4002ac:	00000000 	nop
  4002b0:	00431021 	addu	v0,v0,v1
  4002b4:	03c0e821 	move	sp,s8
  4002b8:	8fbf001c 	lw	ra,28(sp)
  4002bc:	8fbe0018 	lw	s8,24(sp)
  4002c0:	03e00008 	jr	ra                   /*jump reg*/
  4002c4:	27bd0020 	addiu	sp,sp,32

004002c8 <main>:
  4002c8:	27bdffc8 	addiu	sp,sp,-56
  4002cc:	afbf0034 	sw	ra,52(sp)
  4002d0:	afbe0030 	sw	s8,48(sp)
  4002d4:	03a0f021 	move	s8,sp
  4002d8:	24020001 	li	v0,1       /*没有采用优化选项,所以对每个变量的操作均会访问内存*/
  4002dc:	afc2001c 	sw	v0,28(s8)
  4002e0:	24020002 	li	v0,2
  4002e4:	afc20020 	sw	v0,32(s8)
  4002e8:	24020003 	li	v0,3
  4002ec:	afc20024 	sw	v0,36(s8)
  4002f0:	24020004 	li	v0,4
  4002f4:	afc20028 	sw	v0,40(s8)
  4002f8:	24020005 	li	v0,5
  4002fc:	afa20010 	sw	v0,16(sp)
  400300:	8fc4001c 	lw	a0,28(s8)
  400304:	8fc50020 	lw	a1,32(s8)
  400308:	8fc60024 	lw	a2,36(s8)
  40030c:	8fc70028 	lw	a3,40(s8)
  400310:	0c100099 	jal	400264 <fun5>       /* jal:jump and link*/
  400314:	00000000 	nop
  400318:	afc20018 	sw	v0,24(s8)
  40031c:	00001021 	move	v0,zero
  400320:	03c0e821 	move	sp,s8
  400324:	8fbf0034 	lw	ra,52(sp)
  400328:	8fbe0030 	lw	s8,48(sp)
  40032c:	03e00008 	jr	ra
  400330:	27bd0038 	addiu	sp,sp,56






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值