ARM与C语言的混合编程【嵌入式系统】

简介: ARM与C语言的混合编程【嵌入式系统】

前言

以下内容源自《【嵌入式系统】》

仅供学习交流使用

推荐

Keil 4 安装教程及简单使用【嵌入式系统】

ARM简单程序设计【嵌入式系统】

ARM与C语言的相互调用

说明

需要下载Keil for C51

可以看Keil 4 安装教程及简单使用【嵌入式系统】

ARM7汇编语言与C语言间的模块接口

ARM7汇编程序与C程序间变量互访

①汇编程序访问C程序中的变量

具体操作步骤:

在C程序中,将供汇编程序访问的变量用关键字extern声明为全局外部变量;

汇编程序中,用伪指令IMPORT引入C程序中声明的全局变量;

使用伪指令LDR读取这个全局变量的地址;

使用指令LDR读取这个全局变量的值;

在汇编程序中使用这个全局变量;


②C程序访问汇编程序中的变量

具体操作步骤:

在汇编语言程序中,用伪指令“global”定义全局变量,变量名必须是下划线“_”为首字符的字母数字串;

C程序中将该变量声明为外部变量,即可访问汇编程序定义的全局变量。


例:汇编程序和C程序间变量互访

/* print.c 定义全局变量,并作为主程序 */
#include <stdio.h>
extern int g_var = 124; /* 全局变量 */
extern asmVisit(void);  /* 汇编程序中声明的全局函数 */
extern int _multiple; /* 声明汇编程序中的全局变量_multiple为外部变量 */
int main()
{
printf("Original value of g_var is: %d  \n ", g_var);
asmVisit();   /* 调用汇编程序中的函数,访问全局变量g_var */
printf("mult is %d",_multiple);   /* 访问汇编程序中全局变量_multiple */
printf(" Modified value of g_var is: %d", g_var);
return 0;
} 
; visit.s文件
  AREA asmfile, CODE, READONLY
  EXPORT asmVisit ; 声明全局函数,供C程序调用??
  IMPORT g_var    ; 引入在C程序中声明定义的全局变量
  GLOBAL _multiple  ; 声明全局变量,供C程序访问
asmVisit
  LDR R0, =g_var
  LDR R1, [R0]
  LDR R2,   =_multiple
  LDR R2,   [R2]
  MOV R3,     R1,   LSL R2  ; 将R1中的值扩大指定的倍数
  STR R3, [R0]
  MOV PC, LR
  AREA asmData, DATA, READWRITE
_multiple DCD 2
  END 

ARM7汇编程序调用C程序

汇编程序中调用C函数,只需在汇编程序中用伪指令IMPORT将需要调用的C函数名引用即可,然后将C函数放在一个独立的C文件中进行编译,剩下的工作就由链接器来处理。

汇编程序与C函数间参数的传递规则遵守ATPCS(ARM Thumb Procedure Call Standard)规则:用ARM处理器寄存器组中的{R0 - R3}作为参数传递和结果返回寄存器;如果参数数目超过4个,则使用堆栈进行传递。

; asmfile.s文件
  AREA asmfile, CODE, READONLY
  IMPORT cFun     ; 声明引用外部函数
  ENTRY
  CODE32
start
  MOV R0, #1
  MOV R1, #2
  MOV R2, #3
  BL  cFun      ; 此时结果和在R0中
stop
  MOV R0, #0x18   ; 程序结束返回编译器调试环境
  LDR R1, =0x20026
  SWI 0x123456
  END
/* cFun.c文件,由asmFile.s文件调用 */
int cFun(int a, int b, int c)
{
return a + b + c;
}

C程序调用汇编程序

C程序调用汇编程序子程序,要做的主要工作有两个:

一是在C程序中用关键字extern声明汇编子程序的函数原型(C程序是函数结构的程序设计风格),声明该函数的实现代码在其他文件中;

二是在汇编程序中用伪指令EXPORT导出子程序名,并且用该子程序名作为汇编代码段的标识,最后用mov pc, lr返回。

这样,在C程序中就可以像调用C函数一样调用该汇编子程序了。


具体操作步骤:

汇编程序中,用该子程序名作为汇编代码段的标识,定义程序代码,最后用“MOV PC, LR”指令返回;

汇编程序中用伪指令EXPORT导出子程序名;

C程序中用关键字extern声明该汇编子程序的函数原型;然后就可在C程序中访问该函数;

函数调用时的参数传递规则:寄存器组中的{R0 - R3}作为参数传递而返回值用寄存器R0返回;如果参数数目超过4个,则使用堆栈进行传递。

/* cfile.c */
#include <stdio.h>
extern void  strcpy(const char *src, char *dest);
int main()
{
char *s = "this string is in C file";
char temp[32];
strcpy(s, temp);
printf("Source   string : %s \n", s);
printf("Destination sting: %s", temp);
return 0;
}
; asmfile.s
  AREA strcpy,CODE, READONLY
  EXPORT  strcpy  ; 完成源字符串R0到目的字符串R1的拷贝
loop
  LDRB    R5,  [R0],  #1
  CMP       R5,  #0   ; 是否到字符串结束
  BEQ       exit
  STRB    R5,   [R1],     #1
  B           loop
exit
  MOV       PC,   LR
  END

C程序中内嵌ARM7汇编代码

C 程序中内嵌的汇编代码可使用大部分的ARM 和Thumb 指令,存在一些限制,主要有下面几个方面:

不能直接向寄存器PC赋值,程序跳转要使用指令B或者BL;

在访问物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突;

R12和R13常被编译器用来存放中间编译结果,计算表达式值时可能将R0~R3、R12及R14用于子程序调用,因此要避免直接使用这些物理寄存器;


在C程序中使用“__asm”关键字标记内嵌汇编代码,

格式如下:

__asm   ; 注意是双下划线
{
  ......    ; 汇编指令编写的代码
}
#include <stdio.h>
void  strcpy(const char *src, char *dest) 
{
  char ch;      ; 检查字符串是否结束的标志
  __asm
  { ; 功能:完成将源字符串src中的数据拷贝到目的字符串dest中
  LOOP: 
    LDRB  ch, [src],   #1
    STRB  ch, [dest], #1
    CMP ch, #0
    BNE LOOP
  }
}
int main()
{
    char *s= "this is a example AsmInC !";
    char temp[64];
    strcpy(s , temp);
    printf("Original string:  %s \n ",  s);
    printf("Copyed string:  %s",  temp);
    return 0;
}

最后

2023-4-11 20:06:34

你对我百般注释,并不能构成万分之一的我,却是一览无余的你。

祝大家逢考必过

点赞收藏关注哦

相关文章
|
2月前
|
存储 安全 数据管理
C语言之考勤模拟系统平台(千行代码)
C语言之考勤模拟系统平台(千行代码)
58 4
|
2月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别
pymalloc 和系统的 malloc 有什么区别
|
27天前
|
IDE 编译器 开发工具
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
在本文中,我们系统地讲解了常见的 `#pragma` 指令,包括其基本用法、编译器支持情况、示例代码以及与传统方法的对比。`#pragma` 指令是一个强大的工具,可以帮助开发者精细控制编译器的行为,优化代码性能,避免错误,并确保跨平台兼容性。然而,使用这些指令时需要特别注意编译器的支持情况,因为并非所有的 `#pragma` 指令都能在所有编译器中得到支持。
102 41
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
|
5月前
|
Ubuntu Linux
查看Linux系统架构的命令,查看linux系统是哪种架构:AMD、ARM、x86、x86_64、pcc 或 查看Ubuntu的版本号
查看Linux系统架构的命令,查看linux系统是哪种架构:AMD、ARM、x86、x86_64、pcc 或 查看Ubuntu的版本号
1021 3
|
8天前
|
Ubuntu 芯片 开发者
Ubuntu 25 ARM 桌面系统抢先版发布:第一个Ubuntu ARM桌面系统
Ubuntu 25.04 将于2025年发布,首次支持ARM Desktop桌面版系统,为ARM架构设备如Mac M系列芯片、Raspberry Pi等带来全新的桌面体验。用户可通过虚拟机或双系统安装在Mac上运行Ubuntu ARM,抢先体验版已开放下载:[链接](https://www.baihezi.com/ubuntu/arm/desktop)。此版本不仅扩展了Ubuntu的硬件兼容性,还提供了丰富的功能和流畅的操作体验,适合开发者和技术爱好者尝试。
68 9
|
22天前
|
存储 编译器 C语言
【C语言】C语言的变量和声明系统性讲解
在C语言中,声明和定义是两个关键概念,分别用于告知编译器变量或函数的存在(声明)和实际创建及分配内存(定义)。声明可以多次出现,而定义只能有一次。声明通常位于头文件中,定义则在源文件中。通过合理组织头文件和源文件,可以提高代码的模块化和可维护性。示例包括全局变量、局部变量、函数、结构体、联合体、数组、字符串、枚举和指针的声明与定义。
46 12
|
2月前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
51 1
|
2月前
|
人工智能 安全 算法
基于C语言的嵌入式系统开发,涵盖嵌入式系统概述、C语言的优势、开发流程、关键技术、应用实例及面临的挑战与未来趋势。
本文深入探讨了基于C语言的嵌入式系统开发,涵盖嵌入式系统概述、C语言的优势、开发流程、关键技术、应用实例及面临的挑战与未来趋势。C语言因其高效、可移植、灵活及成熟度高等特点,在嵌入式系统开发中占据重要地位。文章还介绍了从系统需求分析到部署维护的完整开发流程,以及中断处理、内存管理等关键技术,并展望了嵌入式系统在物联网和人工智能领域的未来发展。
77 1
|
2月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别?
pymalloc 和系统的 malloc 有什么区别?
|
3月前
|
存储 编译器 C语言
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)