在嵌入式程序设计中,有些场合(如对具体的硬件资源进行访问)必须用汇编语言来实现,可以采用在嵌入式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 ;子程序返回
因篇幅问题不能全部显示,请点此查看更多更全内容