设为首页 加入收藏

TOP

4.2.4 汇编代码中调用C函数
2013-10-12 06:56:24 来源: 作者: 【 】 浏览:86
Tags:4.2.4 汇编 代码 调用 函数

4.2.4  汇编代码中调用C函数

汇编代码中调用C函数,关键是解决参数传递和函数返回问题。

1. 参数传递问题

如果所传递的参数少于四个,则直接使用R0~R3来进行传递,如果参数多于四个,则必须使用栈来传递多余的参数。

2. 函数返回问题

因为在编译C函数的时候,编译器会自动在函数入口的地方加上现场保护的代码(如部分寄存器入栈,返回地址入栈等),在函数出口的地方加入现场恢复的代码(即出栈代码)。

下面是来看汇编代码调用C函数中两个参数个数不同的例子。

例1. 参数个数为四个

asm_test1.asm代码如下:

  1. IMPORT c_test1                      ;声明c_test1函数  
  2. AREA TEST_ASM, CODE, READONLY   ;定义代码段TEST_ASM,属性只读  
  3. EXPORT asm_test1  
  4. 1  
  5. str lr, [sp, #-4]!                      ;保存当前lr  
  6. ldr r0,=0x01                        ;第一个参数r0  
  7. ldr r1,=0x02                            ;第二个参数r1  
  8. ldr r2,=0x03                            ;第三个参数r2  
  9. ldr r3,=0x04                        ;第四个参数r3  
  10. bl c_test1                              ;调用C函数  
  11. LDR pc, [sp], #4                    ;将lr装进pc,返回main函数  
  12. END 

c_test1.c代码如下:

  1. void c_test1(int a,int b,int c,int d)  
  2. {  
  3.         printk("c_test1:\n");               //输出结果到内核缓冲区  
  4.         printk("%0x %0x %0x %0x\n",a,b,c,d);  
  5. }  
  6.  
  7. main.c中的代码如下:  
  8. int main()  
  9. {  
  10.      asm_test1();                       //调用汇编程序  
  11.      for(;;);  

程序说明:

程序从main函数开始执行,main调用了asm_test1,asm_test1调用了c_test1,最后从asm_test1返回main。这里面有两个函数:一个是用ARM汇编语言写的arm_test1.asm程序;另一个是用C语言写的c_test1.c程序。其中汇编程序asm_test1.asm调用了C函数c_test1.c。这里的参数个数没有超过四个,所以只用了R0~R3四个寄存器进行传递。这里请注意asm_test1.asm中"asm_test1"标记下第一行代码,在调用c_test1之前必须把当前的lr保存到堆栈。在调用完c_test1之后再把刚才保存在堆栈中的lr写入到pc中去,这样才能返回到main函数中。

例2. 参数个数大于四个

arm_test2.asm代码如下:

  1.  IMPORT c_test2 ;声明c_test2函数  
  2.  AREA TEST_ASM, CODE, READONLY  
  3.  EXPORT arm_test2  
  4. t2  
  5. str lr, [sp, #-4]!      ;保存当前lr  
  6. ldr r0,=0x01            ;第一个参数r0  
  7. ldr r1,=0x02            ;第二个参数r1  
  8. ldr r2,=0x03            ;第三个参数r2  
  9. ldr r3,=0x04            ;第四个参数r3  
  10. ldr r4,=0x08  
  11. str r4,[sp,#-4]!        ;第八个参数,压入堆栈  
  12. ldr r4,=0x07  
  13. str r4,[sp,#-4]!        ;第七个参数,压入堆栈  
  14. ldr r4,=0x06  
  15. str r4,[sp,#-4]!        ;第六个参数,压入堆栈  
  16. ldr r4,=0x05  
  17. str r4,[sp,#-4]!        ;第五个参数,压入堆栈  
  18. bl c_test2              ;调用C函数  
  19. add sp, sp, #4      ;清除栈中第五个参数,
    执行完后sp指向第六个参数  
  20. add sp, sp, #4      ;清除栈中第六个参数
    ,执行完后sp指向第七个参数  
  21. add sp, sp, #4      ;清除栈中第七个参数,
    执行完后sp指向第八个参数  
  22. add sp, sp, #4      ;清除栈中第八个参数,
    执行完后sp指向lr  
  23. ldr pc, [sp],#4         ;将lr装进pc,返回main函数  
  24.  END 

c_test2.c代码如下:

  1. void c_test2(int a,int b,int c,int d,int e,int f,int g,int h)  
  2. {  
  3.        printk("c_test2_lots:\n");               //输出结果到内核缓冲区  
  4.        printk("%0x %0x %0x %0x %0x %0x %0x %0x\n",  
  5.               a,b,c,d,e,f,g,h);  

main.c代码如下:

  1. int main()  
  2. {  
  3.      arm_test2();           //调用汇编程序  
  4.      for(;;);  

程序说明:

这部分的代码和例1的代码大部分是相同的,主要区别在于参数的个数不同。这里的参数个数大于四个,需要使用堆栈来进行参数传递。第一个到第四个参数还是通过R0~R3四个寄存器进行传递的。第五个到第八个参数则是通过把其压入堆栈的方式进行传递,不过要注意第五个到第八个这四个入栈参数的入栈顺序,是以第八个参数、第七个参数、第六个参数、第五个参数的顺序入栈,出栈的顺序正好相反,依次为第五个参数、第六个参数、第七个参数、第八个参数。这里同样要注意调用汇编语言的开头保存好lr,以便在最后恢复pc,返回到main函数。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇4.2.5 C语言代码中调用汇编函数 下一篇4.3.2 Linux下的C开发工具

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: