您的当前位置:首页正文

ARM汇编语言与嵌入式C语言混合编程————内嵌汇编

2021-01-27 来源:钮旅网
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程序;在ARM—ADS开发工具编译环境下,汇编程序中要使用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) 在ARM—ADS开发工具编译环境下设计程序,用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 ;子程序返回

因篇幅问题不能全部显示,请点此查看更多更全内容