Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104882
  • 博文数量: 49
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2015-07-03 19:38
文章分类

全部博文(49)

文章存档

2016年(37)

2015年(12)

我的朋友

分类: 嵌入式

2016-01-25 21:43:26

摘要:

    本文深入反汇编代码,分析了IAR MSP430普通函数参数传递详情,得出参数传递,前4个寄存器传递,其余的用堆栈传递。


    前几天,还很天真以为函数参数传递是从右向左压栈,经过今天的调试看反汇编代码才知道,原来并没有那么简单。事实上,IAR for MSP430环境下,函数参数传递是寄存器和栈混用,即前四个参数用寄存器传递(结构体或联合类型的另外别论),其他的用堆栈传递。

    注:本文实验环境是IAR for MSP430 5.51,我在百度文库看到一文档,说是参数传递,前2个是寄存器传递,其余的是堆栈传递,而我实验室得出的是前4个寄存器传递。也许是环境版本差异。另,以下所调试的结果是在关闭优化情况下进行的。


一、普通参数传递

    普通参数传递(指不包括结构体或联合类型),前4个参数分别由寄存器R12~R15传递,其他的由堆栈传递。举例如下:

点击(此处)折叠或打开

  1. void test(int d, char c, char *s, int array[], char buf[], int e, int f)
  2. {
  3.   d += 1;
  4. }

  5. int d = 1;
  6. char c = 'c';
  7. char *s = "xyz";
  8. int array[32];
  9. char buf[32];
  10. int e = 5;
  11. int f = 6;
  12. test(d, c, s, array, buf, e, f);

1.1 寄存器传递部分

反汇编及相关变量观察窗口如下:

图1 反汇编及相关变量观察窗口

    注:细心的话,从观察窗口还可以另一个信息,函数内部局部变量并不是在栈上分配空间,而是寄存器(想想,跟课程所学到的是不是不一样?!)

    由此可见,R12~R13分别对应于前4个参数d,c,s,array。值得一提的是,array[32]是在堆栈上分配的空间,而地址0x9B4恰是数组的首地址(传递数组实际上传递指针),如下堆栈所示:

图2 堆栈示意图

1.2 堆栈传递部分

    接下来的3个参数,则会被压入栈(因压栈是编译器自动完成,无法单步调试),压栈顺序是从右向左,即f --> e --> buf。执行test函数时,把堆栈的3个参数(buf, e ,f)存放在寄存器。结合SP指针的值及反汇编很容易还原出整个堆栈结构,如下图:

图3 参数入栈示意图

由此,可以推导出R8、R11、R10值,与观察窗口的值一致,如下图:

图4 参数入栈观察窗口参数值

二、我的问题

    那如何实现所有参数都是通过堆栈传递呢?这点在处理变参的时候显得很重要,我最近就碰到这个问题。我知道IAR for MCS-51可以在声明函数前加关键字__ext_stack_reentrant达到该目的,但我一直没找IAR for MSP430相对应的关键字。求指点:


附:MSP430寄存器[1]


参考资料:

[1]. MSP430经典讲解.pdf MSP430经典讲解.pdf   

阅读(983) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~