关于在+KEIL+C51+中嵌入汇编以及C51与A51间的相互调用
深入剖析keilc51---从汇编到c51

深入剖析keilc51---从汇编到c51C插入汇编语句#pragma asmljmp 0#pragma endasm如果就这样直接编译的话,会出现以下错误:error C272: 'asm/endasm' requires src-control to be active解决方法:在 Files T oolbar 中选中当前C51文件,点右键查看文件选项,将 Generate Assembler SRC File 与 Assemble SRC File 的勾选由灰色变为黑色,即使这两项有效!第一节 main()函数和启动代码汇编是从org 0000h开始启动,那么keil c51是如何启动main()函数的?keil c51有一个启动程序startup.a51,它总是和c程序一起编译和链接。
下面看看它和main()函数是如何编译的;//主函数如下;void main(void){while (1) 这是个无条件空循环。
{}}把上面的main()函数编译后的汇编程序和反汇编代码整理后对照如下;C_C51STARTUP SEGMENT CODEPR?main?TESTMAIN SEGMENT CODESTACK SEGMENT IDATARSEG ?STACKDS 1CSEG AT 0C_STARTUP: LJMP STARTUP1C:0x0000 020003 LJMP STARTUP1(C:0003)RSEG ?C_C51STARTUPSTARTUP1: ;该段程序把内存清零; MOV R0,#IDATALEN - 1C:0x0003 787F MOV R0,#0x7F; CLR AC:0x0005 E4 CLR A; MOV @R0,AIDATALOOP:C:0x0006 F6 MOV @R0,A; DJNZ R0,IDATALOOPC:0x0007 D8FD DJNZ R0,IDATALOOP(C:0006); MOV SP,#?STACK-1 ;设制CPU的堆栈起始地址C:0x0009 758107 MOV SP(0x81),#0x07; LJMP ?C_STARTC:0x000C 02000F LJMP main(C:000F)RSEG ?PR?main?TESTMAINmain:; void main(void)C:0x000F 80FE SJMP main(C:000F) ;main()函数现在分析上面的汇编程序就会明白c51程序是如何启动的。
单片机C51与汇编语言的混合调用_沈洋

转换后函数名
说明
FUNC
无参或参数不经寄 存器传递时
Void func1(char)
_FUNC1 参数经寄存器传递时
Void func2(void)reentrant _?FUNC1 3.2 C51函数名及段的命名
可重入函数采用堆 栈传递参数
C51函数经编译器编译后,每个函数都将采用“?PR?函数
名?模块名”的命名格式分配到独立的代码(CODE)段中。对于
(Unsigned) long float
一般指针
C累加器 R7
R6, R7 R4-R7 R4-R7 R1-R3
5 混合编程实例
5.1 C51调用汇编语言 在采用C51调用汇编语言子程序时,被调用的汇编语言子
程序的名字,段名、参数读取方式,返回值的设置都要按相 应的规则进行。否则将无法完成调用或是无法正常传递参数 及返回值。以下代码为C51函数调用汇编语言子程序的例子。
6 结语
文中对单片机 KEIL C51开发平台的函数命名、段命名、 参数传递规则、返回值传递规则进行了细致的分析,并研究 了C51函数中内嵌汇编程序、C51函数中调用汇编子程序、汇 编程序中调用 C51函数的实现方法,给出了具体的源代码实 现。文中所实现的方法基于 KEIL C51的单片机在线仿真系统 的开发中得到使用,取得了良好的效果。本文介绍的方法对 于单片机系统的程序设计开发具有实际的参考价值。
作者简介 沈 洋,男(1984-),本科。
段类型 CODE DATA
PDATA
XDATA
BIT
段名
?PR?函数名?模块名 ?DT?函数名?模块名 (SMALL)模块 ?PD?函数名?模块名 (COMPACT)模块 ?XD?函数名?模块名 (LARGE)模块 ?BI?函数名?模块名
Keil C语言与汇编混合用

keil C语言与汇编语言混合编程1. C语言中嵌入汇编1、在C 文件中要嵌入汇编代码片以如下方式加入汇编代码:#pragma ASM; Assembler Code Here#pragma ENDASM2、在Project 窗口中包含汇编代码的C 文件上右键,选择“Options for ...”,点击右边的“Generate Assembler SRC File”和“Assemble SRC File”,使检查框由灰色变成黑色(有效)状态;3、根据选择的编译模式,把相应的库文件(如Small 模式时,是Keil\C51\Lib\C51S.Lib)加入工程中, 该文件必须作为工程的最后文件;4、编译,即可生成目标代码。
来个实例吧:#i nclude <reg51.h>{P2=1;#pragma asmMOV R7,#10DEL:MOV R6,#20DJNZ R6,$DJNZ R7,DEL#pragma endasmP2=0;}2 . 无参数传递的函数调用1.无参数传递的函数调用先来个例子:其中example.c和example.a51为项目中的两个文件***********************example.c*********************************************** extern void delay100();main(){delay100;}***********************example.a51*********************************************** ?PR?DELAY100 SEGMENT CODE; // 在程序存储区中定义段PUBLIC DELAY100; //声明函数RSEG ?PR?DELAY100; //函数可被连接器放置在任何地方DELAY100/P>MOV R7,#10DEL:MOV R6,#20DJNZ R6,$DJNZ R7,DELRETEND在example.c文件中,先声明外部函数,然后直接在main中调用即可。
C51和A51函数互调

;Assembler Code Here
#pragma ENDASM
C51和A51函数互调.files
2根据选择的编译模式把相应的库文件象加xxc一样加入工程中并放在xxc下面如smail模式下选择keilc51libc51slib加入工程中如果要进行浮点运算把keilc51libc51fpllib也加入工程中
1、把"xx.c"加入工程中,右击"xx.c"选择“options for file"xx.c"选择“Generate Assembler SRC File”和“Assemble SRC File”打上黑勾有效;
2、根据选择的编译模式,把相应的库文件象加"xx.c"一样加入工程中并放在"xx.c"下面,如smail模式下选择"keil\c51\lib\c51s.lib"加入工程中,如果要进行浮点运算把#34;也加入工程中。
3、在"xx.c"头文件中加入优化:比如#pragma OT(4,speed)
keil混合编程

Keil中c语言和汇编语言混合编程1 模块内接口在C51程序内部调用汇编语句的方法是用#pragma语句,具体结构如下:#pragma asm汇编语句行#pragma endasm这种方法实质是通过asm与endasm告诉c51编译器中间行不用编译,是汇编语句行而不是c 语言语句,因而在编译控制指令中有SRC指令以空盒子将这些不用编译的行存入其中。
下面介绍在c51程序内直接嵌入汇编代码的方法:(1)在c文件中将要嵌入的汇编代码按照图1添加到源文件中。
(2)在Project窗口中用鼠标右击包含汇编代码的c文件,在弹出的快捷菜单中选择“Options for test.c”命令,如图2所示。
(3)在弹出的如图3所示的“Options for File test.c”对话框中的properties选项卡中,单击右边的“Generate Assembler SRC File”和“Assemble SRC File”,使检查框由灰色变为黑色(有效)状态,即使“Generate Assembler SRCFile”和“Assembler SRC File”已经被选中。
(4)根据选择的编译模式,把相应的库文件(如Small模式时,是C51\Lib\C51S.Lib)加入工程中,该文件必须作为工程的最后文件;其他模式应选择相应的库文件,Compact模式对应C51\Lib\C51C.Lib,Large模式对应C51\Lib\C51L.Lib文件。
(5)编译后即可生成目标代码。
在View菜单中执行Periodic Windows Update命令,确保Periodic Windows Update前被选择;在Peripherals菜单中执行I/O port子菜单中的Port1和Port2命令,确保Port1和Port2前被选择,如下图6所示。
(6)使用单步执行,观察运行结果,如图6所示。
可以看出,在并行端口1和端口2,其值是不断变化的。
KEILC51中C语言加入汇编语言的使用方法

KEILC51中C语言加入汇编语言的使用方法一、为什么使用汇编语言?汇编语言是一种底层的编程语言,其主要目的是实现对硬件的直接控制,具有高度灵活性和效率。
在开发单片机程序时,通常使用高级语言来编写大部分的代码,但是在一些特定的情况下,使用汇编语言能够更好地满足需求,例如对一些硬件寄存器的操作、实现高速计算等。
二、C语言与汇编语言相结合的方法在KEILC51中,可以通过使用内联汇编或者使用汇编模块的方式将C 语言与汇编语言相结合。
1.内联汇编内联汇编是将汇编代码直接嵌入到C语言代码中。
使用内联汇编可以获得更高的性能和灵活性,但也增加了代码的可读性和可维护性。
在C语言中使用内联汇编需要使用__asm关键字,并在括号中编写要嵌入的汇编代码。
以下是一个示例:```void delay(unsigned int count)__asmMOVR1,loop:INCR1CJNE R1, count, loop}```在上述示例中,使用了__asm关键字将一段简单的汇编代码嵌入到了C函数delay中,以实现一个延时功能。
2.汇编模块另一种将C语言与汇编语言相结合的方法是使用汇编模块。
汇编模块是一个独立的文件,其中包含了汇编语言代码。
可以通过使用extern关键字将C语言代码与汇编模块连接起来。
首先,需要创建一个汇编模块的文件,例如delay.asm,其中包含了要实现的汇编代码:```; delay.asmPUBLIC delaydelay PROCMOVR1,loop:INCR1CJNE R1, R2, loopRETdelay ENDP```在上述示例中,创建了一个名为delay的汇编函数,该函数实现了一个简单的延时功能。
接下来,在C语言代码中使用extern关键字声明要调用的汇编函数:```// main.cextern void delay(unsigned int count);void maindelay(1000);```在上述示例中,使用extern关键字声明了一个名为delay的汇编函数。
关于在 KEIL C51 中直接嵌入汇编

我找到了一些资料希望对你有用下周就要做实验了,由于听老师说机房位子可能比较少,对我这种蹭课的学生来说也就不敢奢望同选这门课的同学一样能够正常的在机房调试程序了,因此,我决定提前先在自己的工作室里把实验内容给过一遍。
第一个实验是关于嵌入式编程的,这个实验目的一方面是为了让我们熟悉ARM下编程的编译环境ADS和调试器ATX,另一方面是让我们掌握如何将c语言和汇编语言在实际编程中相互调用。
经过这两天靠自己不断的摸索,终于掌握了如何在编译环境中进行ARM编程,另外,还学会了在c中调用汇编程序的方法,以及如何通过linux自带的gcc编译嵌有汇编的c程序,总之,收获还是蛮多的哦,下面就总结一下吧。
1、c嵌汇编首先说一下关于GCC编译嵌有汇编语言的c语言吧,GCC编译的汇编语言不是我们上课时学的Intel x86汇编,而是AT&T汇编,两者的区别可以查看《Gcc使用的内嵌汇编语法格式小教程》。
下面是内嵌汇编的几种格式:语法__asm__(“instruction. ……instruction”); //Linux gcc中支持(注意asm的下划线均为两个否则GCC将会无法编译)__asm{instruction…instruction}; //ADS中支持(注意asm的下划线均为两个否则GCC将会无法编译)asm(“instruction [; instruction]”); //ARM C++中使用例1是我在linux环境下,编的嵌有汇编程序的c语言,并通过了GCC的编译:例1:#includeint plus(int a,int b){__asm__(“add %1,%0\n\t”:”+r”(a):”r”(b));return (c);}int main(){int a,b,c;a=2;b=1;c=plus(a,b);printf(“c=%d\n”,c);}这个程序应该是很简单的,但关键是子函数中嵌入的那段汇编程序,具体的写法可以参看其他文章。
C51与汇编混合编程.

在 C51 中可以通过直接插入“#prapma asm/endasm”预处理指令,实现汇编语言程序的内嵌。具体步 骤如下:
① 在 C 文件中要嵌入汇编代码片以如下方式加入汇编代码: #pragma asm 汇编语句 #pragma endasm
② 在 Project 窗口中包含汇编代码的 C 文件上右击,选择“Options for ...”命令,单击右边的“Generate
;_AD0809 为函数名,“_”表明有参数在寄存器内部传递
PUBLIC _AD0809
;用“PUBL IC”声明该函数
;可以被其他模块调用 RSEG ? PR ? _AD0809 ? ADC0809 ;AD0809 子程序代码段起始位置
_AD0809:
MOV A,R1 MOV R0,A
;R1 传递数组 adc_data[8]首址
将汇编语言程序编写成与 C51 函数类似的独立文件,独立于 C51 程序文件之外,然后将其加入到 Keil C51 项目文件中。在 Keil C51 编译器中,提供了 C51 与汇编语言程序的接口规则,要求在 C51 中必须先声明(定 义)要调用的独立汇编语言程序名,并且要求独立汇编语言程序与 C51 函数一样,具有明确的边界、参数、 返回值和局部变量,这些规则保证了汇编语言能够正确地被 C51 调用。具体如下:
R6,#250
DJNZ R6,$
DJNZ R6,$DEL
#pragma endasm
P10=0;
// 设 P1.0 口为低电平,点亮 LED
for (n=0;n<20000; n++)
// 延时
P10=1;
// 设 P1.0 口为高电平,熄灭 LED
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
关于在 KEIL C51 中嵌入汇编以及C51与A51间的相互调用如何在 KEIL C51(v6.21)中调用汇编函数的一个示例 [ycong_kuang]有关c51调用汇编的方法已经有很多帖子讲到,但是一般只讲要点,很少有对整个过程作详细描述,对于初学者是不够的,这里笔者通过一个简单例子对这个过程进行描述,希望能对初学者有所帮助。
几年来,在这个论坛里笔者得到很多热心人指导,因此也希望藉此尽一点绵薄之力。
在这个例子里,阐述了编写c51程序调用汇编函数的一种方法,这个外部函数的入口参数是一个字符型变量和一个位变量,返回值是一个整型变量。
例中,先用c51写出这个函数的主体,然后用SRC控制指令编译产生asm文件,进一步修改这个asm文件就得到我们所要的汇编函数。
该方法让编译器自动完成各种段的安排,提高了汇编程序的编写效率。
step1. 按写普通c51程序方法,建立工程,在里面导入main.c文件和CFUNC.c文件。
相关文件如下://main.c文件#include < reg51.h >#define uchar unsigned char#define uint unsigned intextern uint AFUNC(uchar v_achr,bit v_bflag);void main(){bit BFLAG;uchar mav_chr;uint mvintrslt;mav_chr=0xd4; BFLAG=1;mvintrslt=AFUNC(mav_chr,BFLAG);}//CFUNC.c文件#define uchar unsigned char#define uint unsigned intuint AFUNC(uchar v_achr,bit v_bflag){uchar tmp_vchr;uint tp_vint;tmp_vchr=v_achr;tp_vint=(uint)v_bflag;return tmp_vchr+(tp_vint<<8);}step2. 在 Project 窗口中包含汇编代码的 C 文件上右键,选择“Options for ...”,点击右边的“Generate Assembler SRCFile”和“Assemble SRC File”,使检查框由灰色变成黑色(有效)状态;step3. 根据选择的编译模式,把相应的库文件(如 Small 模式时,是 Keil\C51\Lib\C51S.Lib)加入工程中,该文件必须作为工程的最后文件;step4. build这个工程后将会产生一个CFUNC.SRC的文件,将这个文件改名为CFUNC.A51(也可以通过编译选项直接产生CFUNC.A51文件),然后在工程里去掉库文件(如C51S.Lib)和CFUNC.c,而将CFUNC.A51添加到工程里。
//CFUNC.SRC文件如下.\CFUNC.SRC generated from: CFUNC.cNAME CFUNC?PR?_AFUNC?CFUNC SEGMENT CODE?BI?_AFUNC?CFUNC SEGMENT BIT OVERLAYABLEPUBLIC ?_AFUNC?BITPUBLIC _AFUNCRSEG ?BI?_AFUNC?CFUNC?_AFUNC?BIT:v_bflag?041: DBIT 1; #define uchar unsigned char; #define uint unsigned int;; uint AFUNC(uchar v_achr,bit v_bflag)RSEG ?PR?_AFUNC?CFUNC_AFUNC:USING 0; SOURCE LINE # 5;---- Variable 'v_achr?040' assigned to Register 'R7' ----; {; SOURCE LINE # 6; uchar tmp_vchr;; uint tp_vint;;; tmp_vchr=v_achr;; SOURCE LINE # 10;---- Variable 'tmp_vchr?042' assigned to Register 'R5' ----MOV R5,AR7; tp_vint=(uint)v_bflag;; SOURCE LINE # 11MOV C,v_bflag?041CLR ARLC A;---- Variable 'tp_vint?043' assigned to Register 'R6/R7' ----; return tmp_vchr+(tp_vint<<8);; SOURCE LINE # 12MOV R6,AMOV R4,#00HCLR AADD A,R5MOV R7,AMOV A,R4ADDC A,R6MOV R6,A; }; SOURCE LINE # 13?C0001:RET; END OF _AFUNCENDstep5. 检查main.c的“Generate Assembler SRC File”和“Assemble SRC File”是否有效,若是有效则点击使检查框变成无效状态;再次build这个工程,到此你已经得到汇编函数的主体,修改函数里面的汇编代码就得到你所需的汇编函数了。
参考文献:1.徐爱钧,彭秀华。
单片机高级语言C51windows环境编程与应用,电子工业出版社, C51编程:关于在 KEIL C51 中直接嵌入汇编。
帖子编号: 83838 发表用户:Youth................................................................................. ................................keil中汇编函数调用c51函数 [ycong_kuang]在keil的写法可参考89852帖子,具体如下:与89852帖子相比,第一步在工程里多了一个被汇编调用的c51的函数文件(c51func.c),至于汇编函数还是先用c51编写出主体(a51func.c),这样汇编程序接口和段都交给编译器处理,你只管在编译成汇编代码后按你的要求改写汇编代码就行了。
例程如下://main.c#include < reg51.h >#define uchar unsigned char#define uint unsigned intextern uint AFUNC(uchar v_achr,bit v_bflag);void main(){bit BFLAG;uchar mav_chr;uint mvintrslt;mav_chr=0xd4; BFLAG=1;mvintrslt=AFUNC(mav_chr,BFLAG);}//a51FUNC.c#define uchar unsigned char#define uint unsigned intextern uint CFUNC(uint);uint AFUNC(uchar v_achr,bit v_bflag) //c51写的汇编函数,最终要变成汇编代码{uchar tmp_vchr;uint tp_vint;tmp_vchr=v_achr;tp_vint=(uint)v_bflag;return CFUNC(tp_vint); //这里调用一个c51函数}//c51FUNC.c#define uchar unsigned char#define uint unsigned intuint CFUNC(uint v_int) //被汇编函数调用c51函数{return v_int<<2;}第二步是按89852帖子的step2,3,4把用c51写的(汇编)函数变成a51文件(今天我试了一下step3可以不要)例程编译结果如下:; .\a51func.SRC generated from: a51func.cNAME A51FUNC?PR?_AFUNC?A51FUNC SEGMENT CODE?DT?_AFUNC?A51FUNC SEGMENT DATA OVERLAYABLE?BI?_AFUNC?A51FUNC SEGMENT BIT OVERLAYABLEEXTRN CODE (_CFUNC)PUBLIC ?_AFUNC?BITPUBLIC _AFUNCRSEG ?DT?_AFUNC?A51FUNC?_AFUNC?BYTE:tmp_vchr?042: DS 1RSEG ?BI?_AFUNC?A51FUNC?_AFUNC?BIT:v_bflag?041: DBIT 1; //a51FUNC.c;; #define uchar unsigned char; #define uint unsigned int;; extern uint CFUNC(uint);;; uint AFUNC(uchar v_achr,bit v_bflag)RSEG ?PR?_AFUNC?A51FUNC_AFUNC: ;c51所写的函数产生的汇编代码从这里开始USING 0; SOURCE LINE # 8;---- Variable 'v_achr?040' assigned to Register 'R7' ----; {; SOURCE LINE # 9; uchar tmp_vchr;; uint tp_vint;;; tmp_vchr=v_achr;; SOURCE LINE # 13MOV tmp_vchr?042,R7; tp_vint=(uint)v_bflag;; SOURCE LINE # 14MOV C,v_bflag?041CLR AMOV R6,ARLC AMOV R7,A;---- Variable 'tp_vint?043' assigned to Register 'R6/R7' ----; 这里说明R6,R7内容就是tp_vint; return CFUNC(tp_vint);; SOURCE LINE # 16LCALL _CFUNC ;这里调用了用c51写的函数; }; SOURCE LINE # 17?C0001:RET; END OF _AFUNCEND这个文件就是你的汇编函数所在文件,把函数里面的汇编代码修改成你所需的汇编函数就ok了。
建议参考徐爱钧,彭秀华所写的《单片机高级语言C51windows环境编程与应用》或马忠梅所写的《单片机的c语言应用程序设计》有关混合语言编程有关章节................................................................................. ................................关于在 KEIL C51 中直接嵌入汇编。