阅读 309

ARM32汇编语言之汇编和C语言交互(汇编语言与c语言)

汇编语言和C语言交互

  • 内嵌汇编

  • 外链汇编

1.引入其他源文件函数

使用import或者extern伪指令

;使用import伪指令 AREA code, CODE import fun1 ;导入其他源文件中名为fun1的函数 END ;使用extern伪指令 AREA code, CODE extern fun1        END 复制代码

两者区别:

  • import:不管当前文件是否使用该引入的函数,该标签都会加入当前文件符号表,即为静态引用

  • extern:只有当前文件使用了该函数,才会将此标签加入符号表,即为动态引用

2.导出当前源文件中函数供其他文件访问

使用export或者global伪指令

;使用import伪指令 AREA code, CODE export fun         ;导出fun函数供其他源文件使用 fun  mov R0,#4 bx lr END 复制代码

3.外链汇编之C语言调汇编函数

第一步,在汇编原文件中将函数暴露出来给供外部调用,使用export或者global伪指令:

AREA code, CODE export arm_strcpy  ;或者使用global arm_strcpy loop  ldrb R4,[R0],#1 ;如果使用ldr 那么将偏移值改成4 cmp R4,#0 beq over strb R4,[R1],#1 b loop over END 复制代码

第二步,在C文件中引用汇编中的函数,C文件中只能使用extern伪指令:

extern arm_strcpy(char *src,char*des); int main2(){ char *a="hello pangshu"; char b[64]; arm_strcpy(a,b); } 复制代码

4.外链汇编之汇编调c语言函数

第一步,在C文件中编写好函数

int c_sum(int a,int b){ return a+b; } 复制代码

第二步, 在汇编文件中引入函数,使用import或者extern伪指令

AREA code, CODE import c_sum   mov R0,#1 ;第一个参数 mov R1,#2 ;第二个参数 END 复制代码

第三步, 使用BL指令调用函数

AREA code, CODE import c_sum   mov R0,#1 ;第一个参数 mov R1,#2 ;第二个参数 BL c_sum END 复制代码

在ARM中函数参数使用R0~R3这四个寄存器来进行传递,最多传递4个参数,超过4个参数使用栈进行处理,函数返回值通过R0进行传递

由于keil软件的特殊性,我们可以通过以下方式进行互调测试

C文件中代码:

#include<stdio.h> extern arm_strcpy(char *src,char*des); int main2(){ char *a="hello pangshu" ; char b[64]; arm_strcpy(a,b); //调汇编中函数 return 0; } int c_sum(int a,int b){ return a+b; } 复制代码

汇编文件中代码:

 AREA code, CODE  import c_sum     export arm_strcpy   arm_strcpy mov R0,#1 ;第一个参数 mov R1,#2 ;第二个参数 BL c_sum  ;结果存放至R0中 END 复制代码

5.内嵌汇编

在C语言中嵌入汇编代码,格式如下:

int main2(){     int a=4;     int b=4;     int c=4;    __asm__{         //使用__asm或者__asm__ mov R5,#0x00000005   //在大括号内部直接写入汇编代码即可 mov R6,#0x00000005 } return 0; } 复制代码

内嵌汇编的注意事项:

  • 不能直接给PC寄存器赋值,如果想改变pc值需要借助转移指令

  • 由于R0 ~ R3用于存放函数参数和返回值,R12 ~ R15有特殊用途,因此我们能操作的寄存器只有R4~R11, 又因为编译器会优先将寄存器分配给函数中的局部变量,因此我们一般无法在内嵌汇编环境中准确地修改某个寄存器的值,比如我想修改R5寄存器的值,由于函数有个变量占用了R5这个寄存器,那么编译器会自动将你写的这个R5改成R6或者其他,所以,在内嵌汇编时我们需要把寄存器当作变量来看待,把局部变量也当成寄存器看待,就好理解了

void c_strcopy(char *src,char *des){ char ch __asm__{         loop:      ldrb ch,[src],#1  //局部变量当成寄存器看待      strb ch,[des],#1      cmp,ch,#0      bne loop } }

 伪原创工具 SEO网站优化  https://www.237it.com/ 

作者:乱码三千
链接:https://juejin.cn/post/7036170272973520927


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐