首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

入门ARM实例 test5

入门ARM实例 test5

  • #include <stdio.h>
  • void f1(int p1)  
  • {  
  • }  
  • void main()  
  • {  
  •   int d = 4;  
  •   f1(d);  
  • }  
   然后编译:arm-linux-gnueabihf-gcc test.c -o test5
   然后看看汇编代码:arm-linux-gnueabihf-objdump -D test5


0000835c <f1>:
1    835c:       b480            push    {r7}
嚯,栈还预留这么多!真奢侈。
2   835e:       b083            sub     sp, #12
3    8360:       af00            add     r7, sp, #0
子函数f1来取主函数通过寄存器r0传过来的参数p1,并把它放到自己的栈上--也是一段内存:
4    8362:       6078            str     r0, [r7, #4]
由于函数f1什么也没干,接下来就恢复盏指针,再恢复r7寄存器并返回:
5    8364:       f107 070c       add.w   r7, r7, #12
6    8368:       46bd            mov     sp, r7
7    836a:       bc80            pop     {r7}
因为,f1自始至终都没有碰这个美少女lr,所以她还是主函数的:
8    836c:       4770            bx      lr
9    836e:       bf00            nop

00008370 <main>:
10    8370:       b580            push    {r7, lr}
11   8372:       b082            sub     sp, #8
12    8374:       af00            add     r7, sp, #0
13    8376:       f04f 0304       mov.w   r3, #4
14   837a:       607b            str     r3, [r7, #4]
把栈上的变量值搬到寄存器r0:
15    837c:       6878            ldr     r0, [r7, #4]
16    837e:       f7ff ffed       bl      835c <f1>
17    8382:       f107 0708       add.w   r7, r7, #8
18    8386:       46bd            mov     sp, r7
19   8388:       bd80            pop     {r7, pc}
20   838a:       bf00            nop
        读者会发现,10行-14行与《从最简单的实例学习ARM 指令集(三)》里的test4.c是一样的。15行是新加的,目的是为了参数传递:
       14行是把变量d的值,从寄存器r3搬到内存里--即栈上:

14   837a:       607b            str     r3, [r7, #4]
       15行是把栈上的变量值搬到寄存器r0,以供子函数f1来取,你说这多折腾哪!直接用r3来传递不就少折腾一次吗,真是的!

15    837c:       6878            ldr     r0, [r7, #4]

      分析到这里,大家就明白了,arm使用寄存器r0来传递参数的。我们知道arm有r0-r16总共17个寄存器,他们都能用来传递参数吗? 看下面的例子:test6.c




  • #include <stdio.h>
  • void f1(int p1, int p2, int p3, int p4)  
  • {  
  • }  
  • void main()  
  • {  
  •   int d = 4;  
  •   f1(d, d, d, d);  
  • }  


   然后编译:arm-linux-gnueabihf-gcc test.c -o test6
   然后看看汇编代码:arm-linux-gnueabihf-objdump -D test6
0000835c <f1>:
    835c:       b480            push    {r7}
    835e:       b085            sub     sp, #20
    8360:       af00            add     r7, sp, #0
    8362:       60f8            str     r0, [r7, #12]
    8364:       60b9            str     r1, [r7, #8]
    8366:       607a            str     r2, [r7, #4]
    8368:       603b            str     r3, [r7, #0]
    836a:       f107 0714       add.w   r7, r7, #20
    836e:       46bd            mov     sp, r7
    8370:       bc80            pop     {r7}
    8372:       4770            bx      lr

00008374 <main>:
    8374:       b580            push    {r7, lr}
    8376:       b082            sub     sp, #8
    8378:       af00            add     r7, sp, #0
    837a:       f04f 0304       mov.w   r3, #4
    837e:       607b            str     r3, [r7, #4]
    8380:       6878            ldr     r0, [r7, #4]
    8382:       6879            ldr     r1, [r7, #4]
    8384:       687a            ldr     r2, [r7, #4]
    8386:       687b            ldr     r3, [r7, #4]
    8388:       f7ff ffe8       bl      835c <f1>
    838c:       f107 0708       add.w   r7, r7, #8
    8390:       46bd            mov     sp, r7
    8392:       bd80            pop     {r7, pc}
    看看,蓝色文字标注的main函数和f1函数,果然main函数的四个参数(d, d, d, d)是通过r0, r1, r2, r3 传递到子函数f1里的!
返回列表