c语言嵌入arm汇编语言,arm汇编语言与嵌入式c语言混合编程————内嵌汇编

arm汇编语言与嵌入式c语言混合编程————内嵌汇编

ARM 汇编语言与嵌入式 C 语言混合编程内嵌汇编 在嵌入式程序设计中,有些场合(如对具体的硬件资源进行访问)必须用汇编语言来实 现,可以采用在嵌入式 C 语言程序中嵌入汇编语言或嵌入式 C 语言调用汇编语言来实现。 内嵌汇编内嵌汇编 内嵌的汇编指令与通常的 ARM 指令有所区别,是在嵌入式 C 程序中嵌入一段汇编代码, 这段汇编代码在形式上表现为独立定义的函数体,遵循过程调用标准。 1语法格式语法格式 在嵌入式 C 程序中内嵌汇编使用关键字“__asm”。在 ARM 开发工具编译环境下与 GNU ARM 编译环境下的内嵌汇编在格式上略有差别。 (1)ARM 开发工具编译环境下内嵌汇编语法格式开发工具编译环境下内嵌汇编语法格式 在 ARM 开发工具编译环境下的内嵌汇编语言程序段,可以直接引用 C 语言中的变量定 义。具本的语法格式如下: __asm 指令;指令 指令;指令 /注释 指令 示例:示例: /* main.c */ void __main(void) int var=0xAA; __asm /内嵌汇编标识 MOV R1,var CMP R1,#0xAA while(1); (2)GNU ARM 环境下内嵌汇编语法格式环境下内嵌汇编语法格式 在 GNU ARM 编译环境下内嵌汇编语言程序段,不能直接引用 C 语言中的变量定义。 如果有多条汇编指令需要嵌入,则可用“”将它们归为一条语句。具本的语法格式如下: __asm ( “指令;指令; 指令;指令; 指令;” ) ; 示例:示例: /* main.c */ void __main(void) int var=0xAA; __asm ( “ MOV R5,#0xAA; /*注意:这里不要直接使用 C 代码中提供的变量*/ MOV R6,#0xBB; CMP R1,#0;“ ); while(1); ARM 汇编语言调用嵌入式 C 语言(汇编程序调用 C 程序) 2010-04-15 14:50 这里要特别注意参数的传递规则,程序设计时要严格遵守 ATPCS。在 GNU ARM 编译环境下,汇编程序中要使用.extern 伪操作声明将要调用的 C 程序;在 ARMADS 开发工具编译环境下,汇编程序中要使用 IMPORT 伪操作声明将要调用的 C 程序。 示例解析示例解析 (1) 在 GNU ARM 编译环境下设计程序,用 ARM 汇编语言调用 C 语言实现20!的 阶乘操作,并将64位结果保存到寄存器 R0、R1中,其中 R1中存放高32位结果。 首先建立汇编源文件 start.s /* start.s */ .global _start .extern Factorial 声明 Factorial 是一个外部函数 .equ Ni, 20 要计算的阶乘数 .text _start: MOV R0,#Ni 将参数装入 R0 BL Factorial 调用 Factorial,并通过 R0传递参数 Stop: B Stop .end 然后建立 C 语言源文件 factorial.c /* factorial.c */ long long Factorial(char N) char i; long long Nx=1; for(i=1;i=N;i+)Nx=Nx*i; return Nx; /通过 R0,R1返回结果 (2) 在 ARMADS 开发工具编译环境下设计程序,用 ARM 汇编语言调用 C 语言 实现20!的阶乘操作,并将64位结果保存到寄存器 R0、R1中,其中 R1中存放高32 位结果。 首先建立汇编源文件 start.s /* start.s */ IMPORT Factorial ;声明 Factorial 是一个外部函数 Ni EQU 20 ;要计算的阶乘数 AREA Fctrl,CODE,READONLY ;声明代码 Fctrl ENTRY ;标识程序入口 start MOV R0,#Ni ;将参数装入 R0 BL Factorial ;调用 Factorial,并通过 R0传递 参数 /*注:在此处观察结果*/ Stop B Stop END ;文件结束 然后建立 C 语言源文件 factorial.c /* factorial.c */ long long Factorial(char N) char i; long long Nx=1; for(i=1;i=N;i+)Nx=Nx*i; return Nx; /通过 R0,R1返回结果 程序运行结果如下:程序运行结果如下: R0 = 0x82B40000 R1 = 0x21C3677C 嵌入式 C 语言调用 ARM 汇编语言(C 程序调用汇编程序) 2010-04-15 14:56 C 程序调用汇编程序也要特别注意参数的传递规则,程序设计时要严格遵守 ATPCS。在 GNU ARM 编译环境下,在汇编程序中要使用.global 伪操作声明汇编程序 为全局的函数,可被外部函数调用,同时在 C 程序中要用关键字 extern 声明要调用的 汇编语言程序。 在 ARM 开发工具编译环境下,汇编程序中要使用 EXPORT 伪操作声明本程序可 以被其他程序调用。同时也要在 C 程序中要用关键字 extern 声明要调用的汇编语言程 序。 示例解析示例解析 (1)在 GNU ARM 编译环境下设计程序,用用 C 语言调用 ARM 汇编语言 C 语言实现20的 阶乘(20!)操作,并将64位结果保存到0xFFFFFFF0开始的内存地址单元,按照小端格式 低位数据存放在低地址单元。 每一步:建立启动 C 程序的代码,请读者参阅前面的章节自行建立。 每二步:建立 C 语言源文件 main.c /* main.c */ extern void Factorial(char Nx); /声明 Factorial 是一个外部函数 Main() char N =20; Factorial(N); /调用汇编文件实现 N!操作 /*注:在此处观察结果*/ while(1); 每三步:建立汇编源文件 Factorial.s /* Factorial.s */ .global Factorial 声明 Factorial 为一个全局 函数 Factorial: MOV R8 , R0 取参数 MOV R9 , #0 高位初始化 SUB R0,R8,#1 初始化计数器 Loop: MOV R1 , R9 暂存高位值 UMULL R8 , R9 , R0 , R8 R9:R8=R0*R8 MLA R9 , R1 , R0 , R9 R9=R1*R0+R9 SUBS R0 , R0 , #1 计数器递减 BNE Loop 计数器不为0继续循环 LDR R0,=0xFFFFFFF0 STMIA R0, R8,R9 结果保存到0xFFFFFFF0开始 的内存单元 MOV PC,LR 子程序返回 (2)在 ARM 开发工具编译环境下设计程序,用 C 语言调用 ARM 汇编语言实现20的阶乘 (20!)操作,并将64位结果保存到0xFFFFFFF0开始的内存地址单元,按照小端格式低位 数据存放在低地址单元。 每一步:建立启动 C 程序的代码,请读者参阅前面的章节自行建立。 每二步:建立 C 语言源文件 main.c,与 GNU ARM 编译环境下相同。 /* main.c */ extern void Factorial(char Nx); /声明 Factorial 是一个外部函数 __main() char N =20; Factorial(N); /调用汇编文件实现 N!操作 /*注:在此处观察结果*/ while(1); 每三步:建立汇编源文件 Factorial.s /* Factorial.s */ AREA Fctrl, CODE, READONLY ;声明代码段 Fctrl EXPORT Factorial Factorial MOV R8 , R0 ;取参数 MOV R9 , #0 ;高位初始化 SUB R0,R8,#1 ;初始化计数器 Loop MOV R1 , R9 ;暂存高位值 UMULL R8 , R9 , R0 , R8 ;R9:R8=R0*R8 MLA R9 , R1 , R0 , R9 ;R9=R1*R0+R9 SUBS R0 , R0 , #1 ;计数器递减 BNE Loop ;计数器不为0继续循环 LDR R0,=0xFFFFFFF0 STMIA R0,R8,R9 ;结果保存到0xFFFFFFF0开 始的内存单元 MOV PC,LR MOV PC,LR ;子程序返回

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言汇编语言混合编程可以实现高效的系统编程,尤其是在嵌入式系统中,常常需要使用汇编语言来控制硬件,而C语言则更适合进行高层次的逻辑处理。下面介绍一个简单的C语言汇编语言混合编程实例。 C语言部分: ```c #include <stdio.h> int sum(int a, int b); int main() { int a = 10; int b = 20; int c = sum(a, b); printf("The sum of %d and %d is %d.\n", a, b, c); return 0; } int sum(int a, int b) { int c; __asm__ __volatile__( "add %1, %2; \n\t" "mov %2, %0; \n\t" : "=r"(c) /* 输出 */ : "r"(a), "r"(b) /* 输入 */ : "memory" /* c 变量可能会被修改,需要加入 memory 限制 */ ); return c; } ``` 汇编语言部分: ```asm section .text global sum sum: add eax, ebx mov ecx, ebx ret ``` 这个程序中,C语言部分调用了一个汇编语言函数`sum`,这个函数的作用是计算两个整数的和。在C语言部分,`sum`函数的定义包含了`__asm__`指令,这个指令告诉编译器将下面的代码转换成汇编语言插入到程序中。在汇编语言部分,定义了一个全局函数`sum`,它将两个整数相加,并将结果存储到寄存器`ecx`中,最后返回结果。 需要注意的是,在C语言部分调用汇编语言函数时,需要使用`__asm__`指令将汇编语言代码嵌入C语言程序中,并使用`volatile`修饰符告诉编译器不要优化这部分代码。同时,需要使用`register`修饰符将寄存器作为输入输出参数传递给汇编语言函数,使用`memory`限制符告诉编译器,汇编语言函数可能会修改内存中的变量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值