ARM中C语言调用汇编语言方法浅析

合集下载

C语言与汇编语言互相调用

C语言与汇编语言互相调用

浅谈C程序中调用汇编模块的方法C语言是目前非常流行的一种编程语言,除具有高级语言使用方便灵活、数据处理能力强、编程简单等优点外,还可实现汇编语言的大部分功能,如可直接对硬件进行操作、生成的目标代码质量较高且执行的速度较快等。

所以在工程上对硬件处理速度要求不很高的情况下,基本可以用C代替汇编语言,编写接口电路的控制软件。

但C也不能完全取代汇编语言,如在一些对速度要求很高的实时控制系统中,以及对硬件的特殊控制方面,C有时也不能完全很好胜任,还需要汇编语言来编写。

因为汇编语言目标代码更精练,对硬件直接控制能力更强和执行速度更快,但汇编语言编程烦难、表达能力差也显而易见。

比较好的解决办法是C与汇编语言混合编程,即用C编写软件的调度程序、用户界面以及速度要求不高的控制部分,而用汇编语言对速度敏感部分提供最高速度的处理模块,供C调用。

这种方法提供了最佳的软件设计方案,做到了兼顾速度效率高和灵活方便。

由于本人的毕业设计需要C 程序中调用汇编模块的方法来提高ARM定点指令的执行速度,故对这方面进行了学习。

学习心得如下:对于C和汇编语言的接口主要有两个问题需要解决。

一、调用者与被调用者的参数传递这种数据传递通过堆栈完成,在执行调用时从调用程序参数表中的最后一个参数开始,自动依次压入堆栈;将所有参数压入堆栈后,再自动将被调用程序执行结束后的返回地址(断点)压入堆栈,以使被调程序结束后能返回主调程序的正确位置而继续执行。

例如一调用名为add汇编程序模块的主函数:main( ){...... add(dest,op1,op2,flages);......}。

在此例中对主函数进行反汇编,主函数在调用add函数前自动组织的堆栈。

...lea 0xfffffffe8(%ebp),%eax #flages数组的首地址入栈push %eaxpushl 0xfffffff8(%ebp) #OP2入栈pushl 0xfffffffc(%ebp) #OP1 入栈pushl 0xfffffff0(%ebp) #dest地址入栈call 0x80483f0 <add> #调用add函数..执行完add调用语句后,栈内数据结果如图一所示。

arm汇编调用c语言

arm汇编调用c语言

arm汇编调用c语言在嵌入式系统开发中,ARM汇编语言是一种重要的编程语言,它可以直接操作硬件资源,提高系统的性能和效率。

然而,ARM汇编语言的编写相对复杂,可读性较差,因此在实际开发中,我们通常会使用C语言来编写大部分的代码。

那么,如何在ARM汇编中调用C语言函数呢?本文将介绍一种常用的方法。

首先,我们需要了解一些基本的概念。

在ARM架构中,函数调用的过程可以简化为以下几个步骤:保存寄存器、传递参数、调用函数、恢复寄存器、返回结果。

在ARM汇编中,我们可以使用一些特殊的指令来完成这些操作。

首先,我们需要保存寄存器。

在ARM架构中,R0-R3寄存器用于传递参数,R4-R11寄存器用于保存临时变量。

在调用C语言函数之前,我们需要将这些寄存器的值保存起来,以免被C语言函数修改。

可以使用STMFD指令将这些寄存器的值保存到栈中。

接下来,我们需要传递参数。

在ARM架构中,函数的参数通常通过寄存器传递。

如果参数的个数超过了寄存器的数量,多余的参数将通过栈传递。

可以使用MOV指令将参数的值保存到相应的寄存器中。

然后,我们可以调用C语言函数。

在ARM汇编中,可以使用BL指令来调用函数。

BL指令会将当前函数的返回地址保存到LR寄存器中,并跳转到目标函数的地址。

在C语言函数执行完毕后,可以使用BX LR指令返回到调用函数的地址。

最后,我们需要恢复寄存器。

在调用C语言函数之前,我们将寄存器的值保存到了栈中,因此在函数执行完毕后,需要将这些值从栈中恢复出来。

可以使用LDMFD指令将这些值恢复到相应的寄存器中。

除了上述的基本操作,还需要注意一些细节。

例如,栈的大小需要根据实际情况进行调整,以免发生栈溢出的情况。

另外,C语言函数的返回值通常保存在R0寄存器中,可以使用MOV指令将其保存到其他寄存器中,以便后续的操作。

总结起来,ARM汇编调用C语言函数的过程可以简化为以下几个步骤:保存寄存器、传递参数、调用函数、恢复寄存器、返回结果。

ARMC语言调用汇编函数实现冒泡排序

ARMC语言调用汇编函数实现冒泡排序

ARMC语⾔调⽤汇编函数实现冒泡排序使⽤冒泡排序将指定数组排序后输出排序函数使⽤汇编语⾔编写,C语⾔调⽤汇编语⾔在控制台显⽰排序前后的结果⼀、问题分析本程序的关键是如何使⽤汇编语⾔实现冒泡排序算法。

可以仿照C语⾔的代码流程,分步骤写出汇编的代码。

⾸先要写出最内层的代码部分,也就是数据交换的汇编代码,数据交换可以使⽤str数据装载指令实现。

之后要考虑内层循环的代码,可以通过cmp指令控制循环次数。

最后是编写最外层的循环代码,也是使⽤cmp指令,来控制整个排序的次数。

⼆、代码编写2.1 C语⾔代码#include <stdio.h>extern void sort(char* num, int count);int main(){char number[10] = {'a', 'c', 'b', 'e', 'd', 'f', 'h', 'g', 'j', 'i'};printf("Before: %s\n", number);sort(number, 10);printf("After: %s\n", number);return 0;}C语⾔中⽐较重要的是,⾸先要声明外部函数sort,也就是由汇编代码实现的函数。

其代码流程为:初始化1个10字节的char类型的数组在控制台输出初始化的数据调⽤汇编函数进⾏排序显⽰排序后的结果2.2 汇编代码area sort, code, readonlyglobal sortstartmov r2, #-1 ; r2->i, i=-1sub r8, r1, #1 ; r1->countloopcmp r2, r8 ; 控制外层循环bge stopadd r2,r2, #1 ; i=i+1mov r3, #-1 ; r3=j, j=-1loop0add r3, r3, #1 ; j=j+1add r4, r3, #1 ; r4=j+1sub r7, r8, r2 ; 控制内层循环cmp r3, r7bge loopldrb r5, [r0, r3] ; r5=a[j]ldrb r6, [r0, r4] ; r6=a[j+1]cmp r5, r6 ; ⽐较 a[j] 和 a[j+1]blt loop0swapstrb r5, [r0, r4] ; 交换 a[j] 和 a[j+1]strb r6, [r0, r3]b loop0stopend汇编语⾔代码是仿照的C语⾔的冒泡排序流程实现的,其⼤致流程为:⾸先初始化R2,R2⽤来控制外层循环的次数。

C程序访问ARM汇编程序中的函数

C程序访问ARM汇编程序中的函数

C程序访问ARM汇编程序中的函数
C 程序调用ARM 汇编子程序,要做的主要工作有两个:一是在C 程序中用关键字EXTERN 声明ARM 汇编子程序的函数原型(C 程序是函数结构的程
序设计风格),声明该函数的实现代码在其他文件中;二是在ARM 汇编子程序
中用伪指令EXPORT 导出子程序名,并且用该子程序名最为ARM 汇编代码段
的标识,最后用MOV PC,LR 指令返回。

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

无论是C 语言中的函数名还是ARM 汇编语言中的标号,其作用一样,都只是起到表明该函数名或标号存储单元起始地
址的作用。

具体操作步骤如下:
(1)ARM 汇编程序中,用该子程序名作为ARM 汇编代码段的标识,定义
程序代码,最后用MOV PC,LR 指令返回;
(2)ARM 汇编程序中用伪指令EXPORT 导出子程序名;
(3)C 程序中用关键字EXTERN 声明该ARM 汇编子程序的函数原型,然
后就可在C 程序中访问该函数;
(4)函数调用时的参数传递规则:寄存器组中的【R0R3】作为参数传递而
返回值用寄存器R0 返回,如果参数数目超过4 个,则使用堆栈进行传递。

程序清单如下:
// main.c
#include
extern void my_strcpy(const char *src,char *dest);
int main(){ char *strsrc = “Welcome to XU”;char temp[32] = {0};。

关于在ARM中(MDK下)C与汇编混合编程的问题

关于在ARM中(MDK下)C与汇编混合编程的问题
{
loopLDRBr2,[r0],#1//R0保存第一个参数
STRBr2,[r1],#1//R1保存第二个参数
CMPr2,#0
BNEloop
BLXlr//返回指令须要手动加入
}
intmain(void)
{
constchar*a=“Helloworld!”;
charb[20];
my_strcpy(a,b);
关于在ARM中(MDK下)C与汇编混合编程的问题
于:bbs.21ic/icview-156494-1-1.html([微控制器/MCU]小窍门:Cortex-M3
在MDK C语言中嵌入汇编语言的方法)
==================================
==========================
如果须要访问C程式中的变量,可以使用_cpp关键字,编译器如LDRr0,=__cpp(&some_variable)
LDRr1,=__cpp(some_function)
BL__cpp(some_function)
MOVr0,#__cpp(some_constant_expr)
**********************************
***************************
在传统的ARM处理器中(ARM7/ARM9),如果要在C程式中嵌入汇编,可以有
两种方法:
一、内联汇编的方式方法如下:intPCBsheji(inti)
{
intr0;
__asm
{
ADDr0,i,1
EORi,r0,i
}
returni;
}
在汇编语句可以直接做用C语言中的变量.编译器会对这些代码进一步优化,

armc语言调用汇编函数

armc语言调用汇编函数

armc语言调用汇编函数
ARM系列处理器的程序开发,可以采用ARM汇编语言和C语言来实现,而两者可以互相调用。

本文主要介绍一种ARM处理器下,C语言调用汇编语言编写的函数的实现过程。

二、C语言调用汇编函数的实现
1. 首先,要在汇编代码中定义函数,函数的开始以及结束用特定的指令来表示,如下所示:
MyAdd PROC
;
MyAdd ENDP
2. 接着,定义C语言源程序中的函数,以下是MyAdd函数在C 语言源程序中的定义:
int MyAdd ( int a, int b ) //定义函数MyAdd,参数a,b
{
int c;
asm{
add a,b,c //汇编语言指令,将参数a ,b的和结果送给c
}
return c;
}
3. 若要将汇编语言定义的函数MyAdd引入C语言源程序,那么只需要在C语言源程序的前面加上如下的宏定义:
#define MyAdd ( int a, int b )
( {
int c ;
asm{
add a,b,c
}
c ;
} )
4. 最后,在C语言源程序的其他地方,就可以用MyAdd函数来调用汇编代码中定义的函数,实现C语言调用汇编函数的功能。

三、结论
ARM系列处理器的程序开发可以采用ARM汇编语言和C语言来实现,两者之间可以互相调用,C 语言也可以调用汇编语言编写的函数,只需要定义一个宏,就可以实现C语言调用汇编函数。

浅谈单片机中C语言与汇编语言的转换

浅谈单片机中C语言与汇编语言的转换

浅谈单⽚机中C语⾔与汇编语⾔的转换⼀、单⽚机课设题⽬要求与软件环境介绍做了⼀单⽚机设计,要⽤C语⾔与汇编语⾔同时实现,现将这次设计的感受和收获,还有遇到的问题写下,欢迎感兴趣的朋友交流想法,提出建议。

单⽚机设计:基于51单⽚机的99码表设计软件环境:Proteus8.0 + Keil4要求:1,开关按⼀下,数码管开始计时。

2,按两下,数码管显⽰静⽌。

3,按三下,数码管数值清零。

⼆、C语⾔程序1 #include<reg51.h>2#define uint unsigned int3#define uchar unsigned char4 uchar shi,ge,aa,keycount=0,temp;5 sbit anjian=P1^7;6 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};7void display(shi,ge);8void key ();9void init();10void delay(uint z);11/*-----主程序-----*/12void main()13 {14 init(); //初始化15while(1)16 {17 key ();18if(keycount==1)19 TR0=1; //开中断20if(keycount==2)21 TR0=0;22if(keycount==3)23 {24 temp=0;25 keycount=0;26 }27if(aa==10){aa=0;28if(temp<=99)29 {30 temp++;display(shi,ge);31 }32else33 temp=0;}34 }35 }363738/*------初始化程序-------*/39void init()40 {41 keycount=0;42 temp=0;43 TMOD=0x01;44 TH0=(65536-50000)/256;45 TL0=(65536-50000)%256;46 EA=1;47 ET0=1;48//TR0=0;49 }50/*-----定时器中断-----*/51void timer0() interrupt 152 {53 TH0=(65536-50000)/256;54 TL0=(65536-50000)%256;55 aa++;56 }57/*-----显⽰⼦程序-----*/58void display(shi,ge)59 {60 shi=temp/10;61 ge=temp%10;62 P0=table[shi];;delay(70);63 P2=table[ge]; ;delay(70);64 }65/*-----按键检测⼦程序-----*/66void key ()67 {68if(anjian==0)69 {70 delay(5); //消抖71if(anjian==0)72 keycount++;73 }74//while(anjian==0);75//display(shi,ge); //等待按键弹起76 }77/*-----延时⼦程序-----*/78void delay(uint z) //延时约1ms79 {80uint x,y;81for(x=z;x>0;x--)82for(y=100;y>0;y--);83 }电路仿真结果如下:三、C语⾔转汇编语⾔步骤好了,那么接下来我们就开始C语⾔——>汇编语⾔之旅(1)C语⾔1-10⾏改为1 ORG 0000H //汇编起始伪指令,功能是规定程序存储器中源程序或数据块存放的起始地址2 ajmp STAR //ajmp⽆条件跳转指令3 ORG 000bh4 ajmp timer05 anjian equ P1.7 //位定义6 keycount equ 40h7 shi equ 41h8 gewei equ 42h9 aa equ 43h10 temp equ 44h11tab: db 3fh,6h,5bh,4fh,66h //建表12 db 6dh,7dh,7h,7fh,6fh(2)C语⾔中的初始化函数 12-14⾏和39-49⾏改为1STAR:2 acall init //⼦程序近程调⽤指令,功能是主程序调⽤⼦程序,调⽤⼦程序的范围为2kb1init:2mov keycount,#0 //keycount=03mov temp,#0 //temp=14mov tmod,#01h //TMOD=0x015mov TH0,#606mov TL0,#1767setb EA //位置位指令,对操作数所指出的位进⾏置1操作8setb ET09setb TR010retacall为⼦程序近程调⽤指令,返回⽤ret。

基于ARM的C语言与汇编语言混合编程

基于ARM的C语言与汇编语言混合编程

基于ARM的C语言与汇编语言混合编程2009-07-30 19:12:34| 分类:ARM学习| 标签:|字号大中小订阅1、C语言与汇编语言混合编程应遵守的规则ARM编程中使用的C语言是标准C语言,ARM的开发环境实际上就是嵌入了一个C语言的集成开发环境,只不过这个开发环境与ARM的硬件紧密相关。

在使用C语言时,要用到和汇编语言的混合编程。

若汇编代码较为简洁,则可使用直接内嵌汇编的方法;否则要将汇编程序以文件的形式加入到项目中,按照ATPCS(ARM/Thumb过程调用标准,ARM/Thumb Procedure Call Standard)的规定与C程序相互调用与访问。

在C程序和ARM汇编程序之间相互调用时必须遵守ATPCS规则。

ATPCS规定了一些子程序间调用的基本规则,哪寄存器的使用规则,堆栈的使用规则和参数的传递规则等。

1)寄存器的使用规则子程序之间通过寄存器r0~r3来传递参数,当参数个数多于4个时,使用堆栈来传递参数。

此时r0~r3可记作A1~A4。

在子程序中,使用寄存器r4~r11保存局部变量。

因此当进行子程序调用时要注意对这些寄存器的保存和恢复。

此时r4~r11可记作V1~V8。

寄存器r12用于保存堆栈指针SP,当子程序返回时使用该寄存器出栈,记作IP。

寄存器r13用作堆栈指针,记作SP。

寄存器r14称为链接寄存器,记作LR。

该寄存器用于保存子程序的返回地址。

寄存器r15称为程序计数器,记作PC。

2)堆栈的使用规则ATPCS规定堆栈采用满递减类型(FD,Full Descending),即堆栈通过减小存储器地址而向下增长,堆栈指针指向内含有效数据项的最低地址。

3)参数的传递规则整数参数的前4个使用r0~r3传递,其他参数使用堆栈传递;浮点参数使用编号最小且能够满足需要的一组连续的FP寄存器传递参数。

子程序的返回结果为一个32位整数时,通过r0返回;返回结果为一个64位整数时,通过r0和r1返回;依此类推。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ARM中C语言调用汇编语言方法浅析在嵌入式系统开发中,目前使用的主要编程语言是C 和ARM指令汇编。

在一些对性能非常敏感的代码块,基于汇编与机器码一一对应的关系,这时不能依靠C编译器的生成代码,而要手工编写汇编,从而达到优化的目的。

一、在C语言中内嵌汇编
在C中内嵌的汇编指令包含大部分的ARM和Thumb指令,不过使用与单纯的汇编程序使用的指令略有不同,存在一些限制,主要有下面几个方面:
①不能直接向PC 寄存器赋值,程序跳转要使用B或者BL指令;
②在使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突;
③R12和R13可能被编译器用来存放中间编译结果,计算表达式值时可能把R0-R3、R12及R14用于子程序调用,因此避免直接使用这些物理寄存器;
d 一般不要直接指定物理寄存器;
④让编译器进行分配内嵌汇编使用的标记是__asm或asm关键字,用法如下:__asm{instruction [; instruction]}或asm("instruction [; instruction]")。

下面是一个例子来说明如何在C中内嵌汇编语言:
//C语言文件*.c
#include <stdio.h>
void my_strcpy(const char *src, char *dest){
char ch;
__asm{
loop:
ldrb ch, [src], #1
strb ch, [dest], #1
cmp ch, #0
bne loop
}
}
int main(){
char *a="forget it and move on!";
char b[64];
my_strcpy(a, b);
printf("original: %s", a);
printf("copyed: %s", b);
return 0;
}
在此例子中C语言和汇编之间的值传递是用C语言的指针来实现的,因为指针对应的是地址,所以汇编中也可以访问。

二、在汇编中使用C定义的全局变量
内嵌汇编不用单独编辑汇编语言文件,比较简洁,但是有很多的限制。

当汇编的代码较多时一般放在单独的汇编文件中,这时就需要在汇编文件和C文件之间进行一些数据的传递,最简便的办法就是使用全局变量。

下面是一个C语言和汇编语言共享全局变量的例子:
//C语言文件*.c
#include <stdio.h>
int gVar=12;
extern asmDouble(void);
int main(){
printf("original value of gVar is: %d", gVar_1);
asmDouble();
printf(" modified value of gVar is: %d", gVar_1);
return 0;
}
;汇编语言文件*.S
AREA asmfile, CODE, READONLY EXPORT asmDouble
IMPORT gVar
asmDouble
ldr r0, =gVar
ldr r1, [r0]
mov r2, #2
mul r3, r1, r2
str r3, [r0]
mov pc, lr
END
在此例中,汇编文件与C文件之间相互传递了全局变量gVar和函数asmDouble,留意声明的关键字extern和IMPORT
三、在C中调用汇编的函数
有一些对机器要求高的敏感函数,通过C语言编写再通过C编译器翻译有时会出现误差,因此这样的函数一般采用汇编语言来编写,然后供C语言调用。

在C文件中调用汇编文件中的函数,要注意的有两点:
一、是要在C文件中声明所调用的汇编函数原型,并加入extern关键字作为引入函数的声明;
二、是在汇编文件中对对应的汇编代码段标识用EXPORT关键字作为导出函数的声明,函数通过mov pc, lr指令返回。

这样,就可以在C文件中使用该函数了。

从C语言的角度的角度,并不知道调用的函数的实现是用C语言还是汇编汇编语言,原因C语言的函数名起到表明函数代码起始地址的作用,而这个作用和汇编语言的代码段标识符是一致的。

下面是一个C语言调用汇编函数例子:
//C语言文件*.c
#include <stdio.h>
extern void asm_strcpy(const char *src, char *dest);
int main(){
const char *s="seasons in the sun"; char d[32];
asm_strcpy(s, d);
printf("source: %s", s);
printf(" destination: %s",d);
return 0;
}
;汇编语言文件*.S
AREA asmfile, CODE, READONLY
EXPORT asm_strcpy
asm_strcpy
loop
ldrb r4, [r0], #1
cmp r4, #0
beq over
strb r4, [r1], #1
b loop
over
mov pc, lr
END
在此例中,C语言和汇编语言之间的参数传递是通过对应的用R0-R3来进行传递,即R0传递第一个参数,R1传递第二个参数,多于4个时借助栈完成,函数的返回值通过R0来传递。

相关文档
最新文档