S3C2440 C语言函数编译出的汇编指令解读

1.C语言函数调用的汇编代码

void main()
{
.....
.....
delay();
语句1;
语句2;
}

delay函数调用的时候,编译成的汇编代码是:

STMDB     R13!,{R4-R5};R4和R5入栈,因为delay函数中用到了R4和R5
.......
LDMIA       R13!,{R4-R5};退出函数的时候,在将R4和R5原来的值恢复

BX             R14              ;返回原来的地方

我们发现规律就是所有函数调用代码编译成汇编的时候,首先会将要使用到的寄存器压栈,在最后即将返回main函数的时候,再将R14和R15原来的值从栈里面恢复出来。根据观察,发现所有的函数调用都是这个套路,所有大家要记住这个特点。

2.参数传递

2.1参数少于4个,包括4个

比如说下面这种情况:

void main()
{
.....
.....
delay(1,2,3,4);
语句1;
语句2;
}

传递4个参数:1,2,3,4。大家看看汇编代码是怎么样的。
MOV       R3,#0x00000004
MOV       R2,#0x00000003
MOV       R1,#0x00000002
MOV       R0,#0x00000001

大家看到这四个参数是通过R0,R1,R2,R3四个寄存器传递到delay函数中的。

2.2参数为5个,多于4个情况

比如说下面这种情况:

void main()
{
.....
.....
delay(1,2,3,4,5);
语句1;
语句2;
}

传递4个参数:1,2,3,4,5。大家看看汇编代码是怎么样的。

MOV       R0,#0x00000005
MOV       R3,#0x00000004
MOV       R2,#0x00000003
MOV       R1,#0x00000002
STR        R0,[R13] ;第5个参数放到堆栈中传递
MOV       R0,#0x00000001

大家看到第5个参数被压入了栈中,就是通过栈空间来传递第5个参数,我在delay函数中看到了对应的汇编指令是LDR  R12,[R13,#0x0008],就是将第5个参数取出来放到R12中,供后面代码使用。所以得出的结论是,函数传递参数是通过R0到R3完成,超过4个参数就放到栈里面来传递。

3.函数中的局部变量放到哪里

比如说下面的程序:

void dely(int a, int b, int c, int d, int e)
{
    int sum = a + b + c + d + e;
    int t1 = 21;
    int t2 = 22;
    int t3 = 23;
    int t4 = 24;
    int t5 = 25;
    int t6 = 26;
    int t7 = 27;
    int t8 = 28;
    int t9 = 29;
    int t10 = 30;
    int t11 = 31;
    int t12 = 32;
    int t13 = 33;
    int t14 = 34;
    int t15 = 35;
    int t16 = 36;
    int t17 = 37;
    int t18 = 38;
    int t19 = 39;
    int t20 = 40;
    int t21 = 41;
    int t22 = 42;
    int t23 = 43;
    int t24 = 44;
    int t25 = 45;
    int t26 = 46;
    sum = t1+t2+t3+t4+t5+t6+t7+t8+t9+t10+t11+t12+t13+t14+t15+t16;
}

void main()
{
    .....
    .....
    delay(1,2,3,4,5);
    语句1;
    语句2;
}

大家觉得t1,t2,t3,t4...t26都放到哪里了呢?我们看看汇编代码:

上图中是debug模式的界面,当前PC已经走到34行语句处,我们主要是观察上图中我标红框的几个地方。第一个处R0到R3的值是我传递的形参值1,2,3,4,第二处R4到R12的值是22,23,24,25,26,27,28,21,也就是我们的局部变量t1到 t8,这些局部变量的值都用R寄存器来保存。再看第三处红框处,地址从0x40000FBC到0x40000F78都在栈空间中,这里面存放的值是t9:29,t10:30,t11:31,t12:32,t13:33,t14:34,t15:35,t16:36,t17:37,t18:38,t19:39,t20:40,t21:41,t22:42,t23:43,t24:44,t25:45,t26:46,这些局部变量的值都被存放到了栈空间,主要是变量太多,寄存器不够用了,就将多余的变量开辟到了栈空间。我们最后在看看这个sum求和的汇编代码。 

ADD       R11,R12,R4
ADD       R11,R11,R5
ADD       R11,R11,R6
ADD       R11,R11,R7
ADD       R11,R11,R8
ADD       R11,R11,R9
ADD       R14,R11,R10
LDR       R11,[R13,#0x0044]
ADD       R14,R14,R11
LDR       R11,[R13,#0x0040]
ADD       R14,R14,R11
LDR       R11,[R13,#0x003C]
ADD       R14,R14,R11
LDR       R11,[R13,#0x0038]
ADD       R14,R14,R11
LDR       R11,[R13,#0x0034]
ADD       R14,R14,R11
LDR       R11,[R13,#0x0030]
ADD       R14,R14,R11
LDR       R11,[R13,#0x002C]
ADD       R14,R14,R11
LDR       R11,[R13,#0x0028]
ADD       R11,R11,R14
STR       R11,[R13,#0x0048]
ADD       R13,R13,#0x0000004C
LDMIA    R13!,{R4-R11,R14}
BX          R14

是不是觉得很清晰了。得出的结论就是函数局部变量开辟的空间要么在寄存器里,要么在栈空间里。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大白2009

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值