[VIP专享]关于在 KEIL C51 中直接嵌入汇编

合集下载

[VIP专享]关于在 KEIL C51 中直接嵌入汇编

[VIP专享]关于在 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);}这个程序应该是很简单的,但关键是子函数中嵌入的那段汇编程序,具体的写法可以参看其他文章。

深入剖析keilc51---从汇编到c51

深入剖析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程序是如何启动的。

KEIL C51 中 C语言加入汇编语言的使用方法

KEIL C51 中 C语言加入汇编语言的使用方法

KEIL C51 中C语言加入汇编语言的使用方法
51单片机2008-06-03 18:20:42 阅读22 评论0字号:大中小
1.通过使用预处理指令#asm 和#endasm来使用汇编语言。

用户编写的汇编语言可以紧跟在#asm之后,而在#endasm之前结束。

如下所示:
#asm
/*汇编源程序*/
#endasm
在#asm和#endasm之间的语句将作为汇编语言的语句输出到由编译器产生的汇编语言文件中。

2.通过使用预处理指令# pragma asm和函数_asm()来使用汇编语言。

在程序的开头加上预处理指令#pragma asm,在该预处理指令之前只能有注释和其它预处理指令。

_asm()函数可按以下方式使用。

_asm(汇编语言字符串)
在汇编语言字符串中,可以通过回车和换行符把各个语句分开。

在C语言中使用汇编语言,可以操作C语言中的全局变量或完成用C语言难于完成的功能,但要注意以下几点:
①#asm不允许嵌套使用。

②当使用asm语句时,编译系统并不输出目标模块,而只输出汇编源文件。

③ _asm只能用小写字母,如果写成大写,就作为普通变量。

④#asm#endasm和_asm只能用在函数内。

Keil C51中嵌入汇编

Keil C51中嵌入汇编

转载请注明出处谢谢
Keil C51中嵌入汇编
我们知道,用C语言实现精确延时是一件比较困难的事情,而用汇编写精确延时程序就简单多了,但是整个程序都用汇编,那就是件头疼的事情。

要是能在C里面嵌入汇编,那就爽了,本文介绍的就是如何在Keil C51里嵌入汇编。

1、在C 文件中以如下方式加入汇编代码:
#pragma ASM
; Assembler Code Here
#pragma ENDASM
例如:
//延时1ms程序晶振:11.0592MHZ
void delay_1ms(void)
{
#pragma asm
DELAY1MS: MOV R7,#50
DD: MOV R6,#10
D2: DJNZ R6,$
DJNZ R7,DD
#pragma endasm
}
2、在Project 窗口中包含汇编代码的C 文件上右键,选择“Options for ...”,点击右
边的“Generate Assembler SRC File”和“Assemble SRC File”,使检查框由灰色变成黑色
(有
效)状态。

如图所示。

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

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

怎样使用keil C51汇编软件编写程序

怎样使用keil C51汇编软件编写程序

怎样使用keil C51汇编软件编写程序在keil C51汇编软件安装章节我们已经将软件安装好了。

下面我们就用这个软件来编写一个小小的程序吧:第一步:双击Uvw51图标,出现如图一所示的主界面图一第二步:新建文件单击菜单栏内的“文件----新建”或者单击图标按钮则在上图所示的灰色区域内出现一个白色的编辑区,这时我们就中以在这里编辑程序了。

如图二所示。

图二第三步:编程程序建立了一个新的编程文件后,我们就可以在这里编写我们所需要的程序了,下面我们就来编写一个简单的程序吧。

!如图三所示:注意,程序的语法及格式绝对不能错误!图三第四步:保存文件程序编写好了,我们当然要记得保存了,要不我们编写程序就白费劲了。

好了,下面我们将上面编写的程序保存起来:单击“文件----保存”或者单击图标,出现如图四所示的对话框:图四这时参照图五所示将对话框的内容设置好:c51eval保存文件时默认的文件扩展是名*.C,请按图五所示改变为为*.a51:图五我们这里就先将文件保存在d:\led 文件夹中,文件名你可以随便取,这里先叫他为ddw.a51;需强调的是保存文件的文件夹和文件名不能使用中文!即保存文件时不能以如下格式保存:正确的保存路径:D/led/ddw.a51当然,保存的文件夹名led、编写的程序的文件名ddw,你都可以随意的取一个,可以是D/ABC/000.a51。

这就取决于你的兴趣了。

错误的保存路径:D/源程序/led/ddw.a51,或者是D/led/流水灯程序.a51。

总之在源程序的保存路径下不能有中文的出现,同时文件名不能取的太长。

第五步:建立项目将汇编的源程序保存后,还没有得到我们所需要的文件,这时我们还需要再建立项目,以便得到我们所需的hex文件。

新建项目的步骤如下:首先先打开新建项目的对话框文件,如图六所示:图六点击新建项目后出现如图七所示的对话框,我们将对话框的参数设定好。

将文件名设置成与刚才源程序的文件名相同,即设为ddw.prj,同时保存的路径跟前面的源程序保存的路径一样,在d/led 上。

KEILC51中C语言加入汇编语言的使用方法

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 c语言中调用汇编指令

keil c语言中调用汇编指令

keil c语言中调用汇编指令Keil C语言是一种嵌入式开发环境,支持多种单片机平台,如STC89C52、STM32等。

在Keil C语言中,可以通过调用汇编指令来实现一些特定的功能。

本文将介绍一些常用的汇编指令及其在Keil C语言中的调用方法。

一、MOV指令MOV指令用于将数据从一个寄存器或内存位置复制到另一个寄存器或内存位置。

在Keil C语言中,可以使用__asm关键字来调用MOV指令。

例如,下面的代码将将一个变量的值从寄存器R0复制到寄存器R1:```c__asm{MOV R1, R0}```二、ADD指令ADD指令用于将两个操作数相加,并将结果存储到目标操作数中。

在Keil C语言中,可以使用__asm关键字来调用ADD指令。

例如,下面的代码将将两个变量的值相加,并将结果存储到另一个变量中:```c__asm{ADD A, B, C}```三、SUB指令SUB指令用于将两个操作数相减,并将结果存储到目标操作数中。

在Keil C语言中,可以使用__asm关键字来调用SUB指令。

例如,下面的代码将将一个变量的值减去另一个变量的值,并将结果存储到另一个变量中:```c__asm{SUB C, A, B}```四、MUL指令MUL指令用于将两个操作数相乘,并将结果存储到目标操作数中。

在Keil C语言中,可以使用__asm关键字来调用MUL指令。

例如,下面的代码将将两个变量的值相乘,并将结果存储到另一个变量中:```c__asm{MUL C, A, B}```五、DIV指令DIV指令用于将两个操作数相除,并将结果存储到目标操作数中。

在Keil C语言中,可以使用__asm关键字来调用DIV指令。

例如,下面的代码将将一个变量的值除以另一个变量的值,并将结果存储到另一个变量中:```c__asm{DIV C, A, B}```六、CMP指令CMP指令用于比较两个操作数的大小,并根据比较结果设置标志位。

KEILC51编译软件使用方法

KEILC51编译软件使用方法

KEILC51编译软件使用方法
2.创建一个新项目
打开KEIL C51软件,点击“Project” -> “New µVision Project”创建一个新的项目。

选择项目所在的文件夹和项目名称,然后点击“Save”。

3.添加源文件
在新创建的项目中,右键点击"Source Group 1",选择"Add New
Item to Group"。

选择您要添加的源文件类型,比如.C文件,然后点击"Add"。

4.编写代码
5.配置单片机参数
在"Project" -> "Options"中选择"Target"选项卡。

选择您正在使用
的目标芯片型号,并配置相关参数,如时钟频率等。

6.编译代码
在工具栏中点击"Build"按钮,或者按下"F7"键来编译代码。

KEIL
C51将会编译源文件,并生成可执行文件。

8.调试程序
9.仿真运行
在工具栏中选择"Start/Stop Simulation"按钮,或按下"F9"键,
KEIL C51将会启动一个仿真器运行您的程序。

您可以在仿真器中监视程
序的运行状态。

10.生成可烧录文件
在成功编译程序后,您可以在工具栏中选择"Output"按钮,或按下CTRL+F7键,KEIL C51将生成可烧录到单片机的HEX文件。

将生成的HEX 文件用于烧录器烧录到目标芯片即可。

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

我找到了一些资料希望对你有用下周就要做实验了,由于听老师说机房位子可能比较少,对我这种蹭课的学生来说也就不敢奢望同选这门课的同学一样能够正常的在机房调试程序了,因此,我决定提前先在自己的工作室里把实验内容给过一遍。

第一个实验是关于嵌入式编程的,这个实验目的一方面是为了让我们熟悉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);}这个程序应该是很简单的,但关键是子函数中嵌入的那段汇编程序,具体的写法可以参看其他文章。

例2同样是c语言中嵌入了汇编,与例1不同的是,这个程序的编译环境为ADS。

例2#includevoid my_strcpy(char* src, const char* dst){ int ch;__asm{loop:LDRB ch, [src], #1STRB ch, [dst], #1CMP ch, #0BNE loop};}int main(void){const char* a = "Hello World!";char b[20];__asm{MOV R0, aMOV R1, bBL my_strcpy, {R0, R1}};printf("Original String: %s\n",a);printf("Copied String: %s\n",b);return 0;}一定要注意例1与例2中汇编语言的语法格式。

2、C语言调用汇编再说一下如何将一个c语言文件与一个汇编文件通过ADS环境编译,并通过ATX进行DEBUG调试的。

先看一下下面的例3例3Cfile.c#includeextern void strcopy(char *d, const char *s);int main(){ const char *srcstr = "abcde";char dststr[32];/* dststr is an array since we're going to change it */printf("Before copying:\n");printf(" '%s'\n '%s'\n",srcstr,dststr);strcopy(dststr,srcstr);printf("After copying:\n");printf(" '%s'\n '%s'\n",srcstr,dststr);return 0;}Asmfile.sAREA SCopy, CODE, READONLYEXPORT strcopystrcopy; r0 points to destination string; r1 points to source stringLDRB r2, [r1],#1 ; load byte and update addressSTRB r2, [r0],#1 ; store byte and update address;CMP r2, #0 ; check for zero terminatorBNE strcopy ; keep going if notMOV pc,lr ; ReturnEND ;注意!!汇编代码编写时一定要缩进,否则编译将会出错这是一个c语言调用汇编的例子,功能是为了实现字符串的拷贝,其中汇编文件为字符串拷贝的功能子函数。

在这里需要说明的是c语言调用汇编语言的一些基本规则,首先是参数传递的规则,c语言的函数前4个参数通过R0-R3来传递,其它参数通过堆栈(FD)传递,且这种传递是单项的,即汇编语言中的R0-R3的值不会再回传给c语言。

拿例3举例来说,当在语言中调用strcopy(dststr,srcstr);时,字符串dststr的首地址将会传给r0,srcstr的首地址将会传给r1,当汇编语言拿到这两个寄存器时,就会通过地址依次加1的形式进行地址内容的复制也就是字符串的复制,当复制到最后一个字母e时,通过比较r2寄存器中的值是否为0来判断是否调出汇编程序(因为在c语言中声明字符串时末尾被自动的添加了一个\0),这里需要注意的是,此时寄存器r0的值为指向源字符串末尾的’\0’的地址值,而寄存器r1的值为指向已经拷贝过的目的字符串中的”e”的地址值,当调出汇编程序时,r0,r1这两个值将不会回传给strcopy(dststr,srcstr);中的两个参数dststr和srcstr,这两个参数的值仍然是c语言在初始化这两个字符串时指向字符串的首地址,这一点可以通过ATX调试时观察寄存器的变化情况来证明。

但是为什么地址值没有变化,但却实现了字符串的拷贝了呢?这主要时因为通过汇编程序,虽然没有改变两个指针的位置,但却改变了两个字符串所在内存地址中的内容,这种方式就是c语言中常说的引用方式,即dststr和r0起初指向的是同一内存空间,但是字符串复制时只是利用r0来复制的,而dststr的位置却没有发生变化。

因此在c语言中输出字符串时并不需要将dststr减去字符串的个数来实现指向字符串的首地址。

这个程序中第二个需要注意的地方是,汇编程序段中的起到临时存放字符串的r2寄存器,很奇怪的是这个地方的寄存器不能换成r4,如果换成r4的话,输出的结果就会有问题,这一点我现在还没有找到答案,希望将来某一天能遇见高人给我指点一下。

最后需要注意的地方是在汇编程序末尾一定要加上MOV pc, lr用ADS编译后,两个文件会被自动的链接,并在工程文件夹下生成一个.o文件,这个文件就是将来要下到开发板上的二进制文件,其中还有一个.axf的镜像文件,这个文件是用来进行ATX调试的,默认的单步调试是在反汇编中进行的,这就会给调试程序带来极大的不便,通过自己的摸索,发现可以通过设置strong source实现在c语言中进行单步调试,两外在单步调试中通过watch来观察c语言中的形参的值和地址的变化情况,便于程序的调试,需要强调的一点时,汇编程序与c程序的文件名不能相同,否则将无法用ATX进行调试。

另外,在汇编程序中访问c程序全局变量的例子。

程序中变量globvl是在c程序中声明的全局变量。

在汇编程序中首先用IMPORT伪操作声明该变量;再将其内存地址读入到寄存器R1中;再将其值读入到寄存器R0中;修改后再将寄存器R0的值赋于变量globvl。

请参看例4例4#includeint globvl;int main(){globvl = 0;asmsub();printf(“globvl = %d”, globvl);return 0;}AREA globals, CODE, READONLYEXPORT asmsubIMPORT globvlasmsubLDR r1, =globvlLDR r0, [r1]ADD r0, r0, #2STR r0, [r1]MOV pc, lrEND ;注意!!汇编代码编写时一定要缩进,否则编译将会出错3、汇编调用c最后我再谈一下如何在汇编中调用c,看一下例5例5int g(int a, int b, int c, int d, int e){return a + b + c + d + e;};汇编程序调用c程序g()计算5个整数i, 2*i, 3*i, 4*i, 5*i的和EXPORT fAREA f, CODE, READONLYIMPORT g ;使用伪操作数IMPORT声明c程序g()STR lr, [sp,#-4]! ;保存返回地址ADD r1, r0, r0 ;假设进入程序f时,r0中的值为i,r1值设为2*iADD r2, r1, r0 ;r2的值设为3*iADD r3, r1, r2 ;r3的值设为5*iSTR r3, [sp, # -4]! ;第五个参数5*i通过数据栈传递ADD r3, r1, r1 ;r4值设为4*iBL g ;调用c程序g()ADD sp, sp, #4 ;调整数据栈指针,准备返回LDR pc, [sp], #4 ;返回END ;注意!!汇编代码编写时一定要缩进,否则编译将会出错注意,c语言最终返回的五个数之和放到了r0寄存器中关于在 KEIL C51 中直接嵌入汇编上网搜索加上看帮助文档,明白了应该进行一些设置。

现在的问题是右键单击文件,没有“options for...”选项。

再问问有经验的人吧。

这里先做个回复。

下面这段话来自于google搜索:1、在C 文件中要嵌入汇编代码片以如下方式加入汇编代码:#pragma ASM; Assembler Code Here#pragma ENDASM2、在Project 窗口中包含汇编代码的 C 文件上右键,选择“Options for ...”,点击右边的“Generate Assembler SRC File”和“Assemble SRC File”,使检查框由灰色变成黑色(有效)状态;3、根据选择的编译模式,把相应的库文件(如Small 模式时,是KeilC51LibC51S.Lib)加入工程中, 该文件必须作为工程的最后文件;4、编译,即可生成目标代码。

相关文档
最新文档