首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

keil C语言与汇编语言混合编程

keil C语言与汇编语言混合编程

keil C语言与汇编语言混合编程


1. C语言中嵌入汇编


1、在 C 文件中要嵌入汇编代码片以如下方式加入汇编代码:


#pragma ASM


     ......         ; Assembler Code Here


#pragma ENDASM



2、在 Project 窗口中包含汇编代码的 C 文件上右键,选择“Options for ...”,点击右边的“Generate Assembler SRC File”和“Assemble SRC File”,使检查框由灰色变成黑色(有效)状态;


3、根据选择的编译模式,把相应的库文件(如 Small 模式时,是 Keil\C51\Lib\C51S.Lib)加入工程中, 该文件必须作为工程的最后文件;


4、编译,即可生成目标代码。


来个实例吧:


#i nclude <reg51.h>


void main(void)


{


      P2=1;


     #pragma asm


     MOV R7,#10


     DEL:MOV R6,#20


     DJNZ R6,$


     DJNZ R7,DEL


     #pragma endasm


     P2=0;


}



2 . 无参数传递的函数调用


C51调用汇编函数


1.无参数传递的函数调用


先来个例子:其中 example.c 和 example.a51 为项目中的两个文件


***********************example.c***********************************************


extern void delay100();


main()


{


     delay100;


}


***********************example.a51***********************************************


?PR?DELAY100 SEGMENT CODE;    // 在程序存储区中定义段


PUBLIC  DELAY100;  //声明函数


RSEG ?PR? DELAY100; //函数可被连接器放置在任何地方,RSEG是段名的属性


DELAY100;


     MOV R7,#10


DEL:


     MOV R6,#20


     DJNZ R6,$


     DJNZ R7,DEL


     RET


END



在example.c文件中,先声明外部函数,然后直接在main中调用即可。


在example.a51中,


?PR?DELAY100 SEGMENT CODE;    作用是在程序存储区中定义段,DELAY100为段名,?PR?表示段位于程序存储区内


PUBLIC DELAY100; 作用是声明函数为公共函数


RSEG ?PR?DELAY100; 表示函数可被连接器放置在任何地方,RSEG是段名的属性


段名的开头为PR,是为了和C51内部命名转换兼容,命名转换规律如下:


CODE -?PR?


XDATA-?XD


DATA-?DT


BIT-?BI


PDATA-?PD


3. 有参数传递的函数调用


记住哦,c文件和A51文件不能使用同一个文件名,不过我还不知道为什么会这样,有高手知道得话请告知。


今天说说带参数传递的函数调用,在C51和汇编之间传递参数的方式有两种,一种是通过寄存器传递参数,C51中不同类型的实参会存入相应的寄存器,在汇编中只需对相应寄存器进行操作,即达到传递参数的目的。


不同类型的数据及其传递参数的寄存器如下表所示:


 在C和汇编混合编程的时候存在C语言和汇编语言的变量以及函数的接口问题。


在C程序中定义的变量,编译为.asm文件后,都被放进了.bss区,而且变量名的前面都带了一个下划线。在C程序中定义的函数,编译后在函数名前也带了一个下划线。例如:


extern int num就会变成 .bss _num, 1


extern float nums[5]就会变成.bss _nums, 5


extern void func ( )就会变成 _func,



一  汇编和C的相互调用可以分以下几种情况:


(1) 汇编程序中访问c程序中的变量和函数。


在汇编程序中,用_XX就可以访问C中的变量XX了。访问数组时,可以用_XX+偏移量来访问,如_XX+3访问了数组中的XX[3]。


在汇编程序调用C函数时,如果没有参数传递,直接用_funcname 就可以了。如果有参数传递, 则函数中最左边的一个参数由寄存器A给出,其他的参数按顺序由堆栈给出。返回值是返回到A寄存器或者由A寄存器给出的地址。同时注意,为了能够让汇编语言 能访问到C语言中定义的变量和函数,他们必须声明为外部变量,即加extern 前缀。


(2) c程序中访问汇编程序中的变量www.icmall.com.cn


如果需要在c程序中访问汇编程序中的变量,则汇编程序中的变量名必须以下划线为首字符,并用global使之成为全局变量。


如果需要在c程序中调用汇编程序中的过程,则过程名必须以下划线为首字符,并且,要根据c程序编译时使用的模式是stack-based model还是register argument model来正确地编写该过程,使之能正确地取得调用参数。


(3) 在线汇编


在C程序中直接插入 asm(“ *** ”),内嵌汇编语句需要注意的是这种用法要慎用,在线汇编提供了能直接读写硬件的能力,如读写中断控制允许寄存器等,但编译器并不检查和分析在线汇编语言,插入在线汇编语言改变汇编环境或可能改变C变量的值可能导致严重的错误。


二 汇编和C接口中寻址方式的改变:


需要注意的是,在C语言中,对于局部变量的建立和访问,是通过堆栈实现的,它的寻址是通过堆栈寄存器SP实现的。而在汇编语言中,为了使程序代码变得更为精 简,TI在直接寻址方式中,地址的低7位直接包含在指令中,这低7位所能寻址的具体位置可由DP寄存器或SP寄存器决定。具体实现可通过设置ST1寄存器 的CPL位实现,CPL=0,DP寻址,CPL=1,SP寻址。在DP寻址的时候,由DP提供高9位地址,与低7位组成16位地址;在SP寻址的时候, 16位地址是由SP(16位)与低7位直接相加得来。


由于在C语言的环境下,局部变量的寻址必须通过SP寄存器实现,在混合编程的时候,为了使汇编语言不影响堆栈寄存器SP,通常的方式是在汇编环境中使用DP方式寻址,这样可以使二者互不干扰。编程中只要注意对CPL位正确设置即可


1 .word 的意思就相当与C语言里的int,char等定义一个变两的宽度


2. 编译错误原因有2:www.connmall.com.cn


a.如果在汇编里面定义.global(全局符号),那么在C语言里面应该用extern声明,以引用该符号。


b.在汇编里面声明的时候,符号前应加下划线,如 FIQ_Addr: .word EXTint_FIQ 应为: FIQ_Addr: .word _EXTint_FIQ 在C语言里面应用extern声明。 另外,一中方法是,用.ref 代替.global 来声明符号,这样就不用在C源程序里面用extern声明了。 两种方法结果相同。 我讲的是用C和汇编混编程用法,至于C++变量如何翻译成汇编符号可以用仿真器,自己去看,原则类似.


ICMALL全场正品,免费注册,欢迎在线订购!网址:www.icmall.com.cn  
专业仙童部分现货库存底价出售
FSCQ1265RTYD     FSC  
FSUSB30MUX        FSC  
FMS6502MTC24X  FSC  
FSDL0165RN        FSC
KA5M02659RN   FSC  
HCPL2631          FSC  
FDN306P          FSC  
FDV303N          FSC  
FDC3601N         FSC  
FSQ100              FSC
FSDM311           FSC  
FSDH321            FSC  
FSDM0265RNB   FSC
FSDM0365RNB   FSC  
FSDM0565R       FSC
FSFR2100           FSC
FSFR1700           FSC
FSBB15CH60C     FSC
FSBB20CH60C     FSC
FSBB30CH60C     FSC
.......

联系方式
Tel:0755-82533068
Fax:0755-82817019
Mobile:13714008147
QQ: 1030248222
朱.R
返回列表