单片机C语言与汇编混合编程讲解
汇编语言与C的混合编程PPT教学课件
![汇编语言与C的混合编程PPT教学课件](https://img.taocdn.com/s3/m/d1d91b3b941ea76e58fa04e6.png)
的子程序破坏,即这些寄存器是供所调用的子程 序作为工作寄存器的。
2020/12/10
9
2内嵌的汇编器和armasm的区别
• 与armasm相比,内嵌的汇编器在功能和使用方法上主要 有以下特点:
开成几条指令。例如指令: • ADD R0,R0,#1023 • 可能会被展开成下面的指令序列 • ADD R0,R0,#1024 • SUB R0,R0,#01 • 乘法指令MUL可能会被展开成一系列的加法操作和移位操作。 • 事实上,除了与协处理器相关的指令外,大部分的ARM指令和
Thumb指令中包含常量操作数都可能被展开成多条指令。
器的值,用户不需要去保护和恢复这些寄存器的值。
• 用户可以改变处理器模式,但是编译器并不了解处理器模式的改变。 这样,如果用户改变了处理器模式,将不能使用原来的C表达式;重 新恢复到原来的处理器模式后,才能再使用这些C表达式。
2020/12/10
11
3在C程序中使用内嵌的汇编指令
• 3.1在C程序中使用内嵌的汇编指令的语法格式 • 在ARM C语言程序中使用关键词_asm来标识一段汇编指令程序,其格式如下: • _asm •{ • Instruction[;instruction] • …… • [instruction] •} • 其中,如果一行中有很多个汇编指令,则指令之间使用分号“;”隔开。如
• 通常推荐在内嵌的汇编指令中不要指定物理寄存器,因为这可能会影 响编译器分配寄存器,进而可能影响代码的效率。
2020/12/10
4
1.3常量
单片机C语言与汇编语言混合编程_杨加国
![单片机C语言与汇编语言混合编程_杨加国](https://img.taocdn.com/s3/m/3d694944f01dc281e53af0c3.png)
表 2 函数参数传递举例
声 明 func1(int a) func2(int b, int c , int *d)
func3(long e , long f)
func4(float g , char h)
说 明 惟一 一个参数 a 在寄 存器 R6 中和 R7 中 传递 . 第一个参数 b 在寄存器 R6 中和 R7 中传 递 , 第二个参数 c 在寄存器 R4 中和 R5 中 , 传 递 第三 个参 数 d 在 寄存器 R1 中 、R2 中和 R3 中传递 . 第一个 参 数 e 在 寄存 器 R4 中 、R5 中 , R6 中和 R7 中传递 , 第二个参数 f 不 能用 寄 存器 , 因为 long 类 型可 用的 寄存器已被 第一个 参数 所用 , 这个参数用固定存储区传递 . 第一个 参 数 g 在 寄存 器 R4 中 、R5 中 、R6 中和 R7 中传递 , 第二个参数 h 不能用 寄存 器传 递 , 只 能用 固定 存储区传递 .
有复杂的跳转的时候 .在单片机 C 语言程序中嵌 入汇编程序是通过 C51 中的预处理指令 #pragma asm endasm 语句实现 , 格式如下 :
#pragma ASM ;汇编程序代码 #pragma ENDASM
通过 #pragma asm 和 #pragma endasm 告 诉 C51 编译器它们之间的语句行不用编译成汇编程 序代码 . 1 .2 在 C51 中调用汇编程序
第一步 , 在 C 文件中以如下方式嵌入 汇编程 序.
#pragma ASM ;汇编程序 #pragma ENDASM
第二步 , 在 keil C51 软件的 Project 窗口右键单 击嵌入汇编程序的 C 文件 , 选择“Options for …” , 点
第5章 单片机C语言与汇编语言混合编程
![第5章 单片机C语言与汇编语言混合编程](https://img.taocdn.com/s3/m/2089eea4f524ccbff1218491.png)
第5章 单片机C语ቤተ መጻሕፍቲ ባይዱ与汇编语言混合编程
第5章 单片机C语言与汇编语言混合编程
5.2.2 混合汇编的实现
1.C51中嵌入汇编程序的实现方法 . 中嵌入汇编程序的实现方法 第一步: 文件中以如下方式嵌入汇编程序。 第一步:在C文件中以如下方式嵌入汇编程序。 文件中以如下方式嵌入汇编程序 #include <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; } 第二步: 软件的Project 窗口右击嵌入汇编程序的 文件, 窗口右击嵌入汇编程序的C文件 文件, 第二步:在Keil C51软件的 软件的 在弹出的快捷菜单中选择Options for ...命令,选中右边的 命令, 在弹出的快捷菜单中选择 命令 选中右边的Generate Assembler SRC File和Assemble SRC File复选框,使检查框由灰 复选框, 和 复选框 色变成黑色(有效 状态。 有效)状态 色变成黑色 有效 状态。
第5章 单片机C语言与汇编语言混合编程
5.2 混合汇编的参数传递与实现 5.2.1 混合汇编的参数传递 1.汇编程序调用C51函数的参数传递 .汇编程序调用 函数的参数传递 函数有参数, 如C51函数有参数,则汇编程序在调用 函数有参数 则汇编程序在调用C51函数前要 函数前要 准备好参数。在汇编程序中C51函数最左边的一个参数由 准备好参数。在汇编程序中 函数最左边的一个参数由 寄存器A传递 其他的参数按顺序通过堆栈给出。 传递, 寄存器 传递,其他的参数按顺序通过堆栈给出。C51函 函 数的返回值是返回到A寄存器或者由 寄存器给出的地址。 寄存器或者由A寄存器给出的地址 数的返回值是返回到 寄存器或者由 寄存器给出的地址。 2.在C51中嵌入汇编程序的参数传递 . 中嵌入汇编程序的参数传递 通过变量或特殊功能寄存器来实现 3.在C51中调用汇编程序的参数传递 . 中调用汇编程序的参数传递 必须严格遵守C51函数的参数和返回值的相关约定。 函数的参数和返回值的相关约定。 必须严格遵守 函数的参数和返回值的相关约定 C51中调用汇编程序进行参数传递的方式有两种,一种 中调用汇编程序进行参数传递的方式有两种, 中调用汇编程序进行参数传递的方式有两种 是通过寄存器传递参数,第二种是通过固定存储区传递。 是通过寄存器传递参数,第二种是通过固定存储区传递。
汇编语言与C的混合编程
![汇编语言与C的混合编程](https://img.taocdn.com/s3/m/6eabbd6fcaaedd3383c4d33e.png)
1.3常量
• 在内嵌的汇编指令中,常量前的符号#可以省略。如果在一个表达式 前使用#,则该表达式必须是一个#。 • 1.4指令展开 • 内嵌的汇编指令中如果包含常量操作数,则该指令可能会被汇编器展 开成几条指令。例如指令: • ADD R0,R0,#1023 • 可能会被展开成下面的指令序列 • ADD R0,R0,#1024 • SUB R0,R0,#01 • 乘法指令MUL可能会被展开成一系列的加法操作和移位操作。 • 事实上,除了与协处理器相关的指令外,大部分的ARM指令和 Thumb指令中包含常量操作数都可能被展开成多条指令。
1.2物理寄存器
• 在内嵌的汇编指令中使用物理寄存器有一下限制: • 不能直接向PC寄存器中赋值,程序的跳转只能通过B指令和BL指令实 现。 • 在使用物理寄存器的内嵌汇编指令中,不要使用过于复杂的C表达式, 因为当表达式过于复杂时,将会需要较多的物理寄存器,这些寄存器 可能与指令中的物理寄存器的使用冲突。 • 编译器可能会使用R1寄存器或者R13寄存器存放编译的中间结果,在 计算表达式值时可能会将寄存器R0~R3、R2以及R14用于子程序的调 用。因此在内嵌的汇编指令中,不要将这些寄存器同时指定为指令中 的物理寄存器。 • 在内嵌的汇编指令中使用物理寄存器时,如果有C变量使用了该物理 寄存器,编译器将在合适的时候保存并恢复该变量的值。需要注意的 是,当寄存器sp、sl、fp以及sb用做特定的用途时,编译器不能恢复 这些寄存器的值。 • 通常推荐在内嵌的汇编指令中不要指定物理寄存器,因为这可能会影 响编译器分配寄存器,进而可能影响代码的效率。
• 下面是一个在汇编程序中访问C程序全局变量的例子。程序中变量 globv1是在C程序中声明的全局变量。在汇编程序中首先使用 IMPORT伪操作声明该变量;R0中;修改后再将寄存器R0的值赋予变量 globv1.本例中程序如下: • AREA globals,CODE,READONLY • EXPORT asmsub • IMPORT global ;用IMPORT伪指令声明该变量 • asmsum • LDR R1,# globv1 ;将其内存地址读入到寄存器R1中 • LDR R0,[R1] ;再将其值读入到寄存器R0中 • ADD R0,R0,#2 • STR R0,[R1] ;修改后再将寄存器R0的值赋予变量globv1 • MOV PC,LR • END
单片机C语言与汇编混合编程讲解
![单片机C语言与汇编混合编程讲解](https://img.taocdn.com/s3/m/63320141eff9aef8941e0649.png)
(1)、C51语言中调用汇编语言程序;C51语言调用汇编语言程序要注意以下几点:1:在文件栏选中File Group和C51程序原文件,在配置文件选项中激活“产生汇编(SRC)文件,“编译(SRC)文件”和“创建工程(目标)时包含”三个选项。
2:根据选择的编译模式,把相应的库文件(如SMALL模式,库文件为KEIL\C51\LIB\)加入工程中。
3:在C51语言中必须声明需要调用的函数为外部函数。
extern void DELAY(void);4:在汇编语言程序中必须声明被调用子程序为公共子程序,在被调用的文件中还需要声明此文件是可从新定位的。
PUBLIC DELAY,DELDELAYY SEGMENT CODERSEG DELAYY实例如下:C51语言文件:#include ""extern void DELAY(void);extern void DEL(void);void main(void){P1=0x00;DELAY();DEL();P1=0xff;}汇编语言文件:PUBLIC DELAY,DELDELAYY SEGMENT CODERSEG DELAYYDELAY: MOV R2,#3HDJNZ R2,$RETDEL: MOV R3,#03HDJNZ R3,$RETEND(2)、C51语言中调用外部的C51函数;C51语言调用外部的C51函数的注意事项如下:1:在主调函数中必须声明被调用的函数为外部类型的函数,其余都一样。
实例如下:主调函数A:#include ""extern void delay(void);sbit P1_1=P1^1;void main(void){P1_1=0;delay();P1_1=1;}被调用的函数B:delay(){unsigned char i;i=0;}(3)、C51语言中嵌入汇编程序;在C51语言中嵌套使用汇编语言编写程序要注意以下的几个问题:1:在文件栏选中File Group和C51程序原文件,在配置文件选项中激活“产生汇编(SRC)文件,“编译(SRC)文件”和“创建工程(目标)时包含”三个选项。
51单片机c语音 rrc汇编写法
![51单片机c语音 rrc汇编写法](https://img.taocdn.com/s3/m/996a849a250c844769eae009581b6bd97f19bc08.png)
近年来,随着物联网和嵌入式系统的快速发展,对嵌入式系统的需求也日益增长。
51单片机作为一种经典的嵌入式系统芯片,一直以来都备受工程师和科技爱好者的喜爱。
在嵌入式系统中,51单片机的C语言和汇编语言编程是必不可少的技能。
本文将介绍51单片机C语言和RRC汇编编程的技巧和方法。
1. 51单片机C语言编程51单片机的C语言编程是一种相对简单易学的编程方法。
通过C语言,可以实现对于51单片机的各种功能进行控制和操作。
在进行51单片机C语言编程时,首先需要熟悉51单片机的C语言编程环境和开发工具。
常用的51单片机C语言编程环境有Keil C51、SDCC等。
在选择合适的开发环境后,就可以开始进行51单片机C语言编程。
在编写C语言程序时,需要注意对51单片机的外设进行正确的配置和初始化,以及对硬件资源的合理利用。
另外,对于一些特殊的应用,可能需要对中断、定时器、串口等进行特殊的处理。
2. 51单片机RRC汇编编程在嵌入式系统中,汇编程序通常被用于对特定的硬件进行底层控制和优化。
对于51单片机来说,RRC汇编语言是一种常用的低级语言。
在进行51单片机RRC汇编编程时,需要对51单片机的指令集和寄存器进行深入的了解。
通过RRC汇编语言,可以直接对51单片机的硬件进行操作,实现对于特定硬件资源的高效控制。
在进行RRC汇编编程时,需要注意对内存和寄存器的管理,以及对51单片机的中断和外设的处理。
3. 51单片机C语言和RRC汇编编程的应用通过学习51单片机C语言和RRC汇编编程,可以实现对于各种应用的快速开发和优化。
在工业控制、通信系统、自动化设备等领域,都可以广泛应用51单片机C语言和RRC汇编编程技术。
通过合理的软件设计和编程,可以实现对51单片机硬件资源的高效利用,提高系统的稳定性和可靠性。
另外,通过C语言和RRC汇编的结合使用,可以实现对于嵌入式系统应用的灵活性和高性能要求。
4. 总结通过对51单片机C语言和RRC汇编编程的初步介绍,可以看出这两种编程方法对于嵌入式系统的开发和优化具有重要的意义。
10 C语言与汇编语言的混合编程
![10 C语言与汇编语言的混合编程](https://img.taocdn.com/s3/m/58d838de6137ee06eff918ea.png)
3.混合项目(续)
模块3(文件名pulse3.asm): PUBLIC _DELAY1MS;用PUBLIC声明_DELAY1MS为其它函数调用,以 “_”为前缀的函数名,表示该函数通过寄存器传递参数 DELAY SEGMENT CODE;定义DELAY段为再定位程序段 ,DELAY是用 户任意起的段名 RSEG DELAY ;选择DELAY为当前段 _DELAY1MS: DELA:MOV R6,#12 ;2T LOP1:MOV R5,#250 ;2T DJNZ R5,$ ;4T DJNZ R6,LOP1 ;4T DJNZ R7,DELA ;R7中数值为C ;程序传递过来的参数,参数为2则延时2ms EXIT: RET END
1.混合编程的实现(续)
第二步:在Keil C51环境下,在Project窗口中包含汇编代码 的C文件上单击右键,在弹出的快捷菜单中选择“Options for…”命令,再点击选中右边的“Generate Assembler SRC File”和“Assembler SRC File”复选框,使检查框由灰色(无 效)变成黑色(有效)状态。
12
3.混合编程
模块1(文件名pulse1.c): #include<STC12C5A.h> #define uchar unsigned char sbit P1_1=P1^1; extern void delay4ms(void); //外部函数delay4ms()声明 void main() { while(1) { P1_1=0; delay4ms (); //调用模块2延时4ms P1_1=1; delay4ms (); //调用模块2延时4ms } }
4
1.混合编程的实现(续)
5
MSP430 单片机C语言和汇编语言混合编程
![MSP430 单片机C语言和汇编语言混合编程](https://img.taocdn.com/s3/m/ef689e4be518964bcf847c94.png)
MSP430 单片机C语言和汇编语言混合编程Mixing C and Assembler With the MSP430刘玉宏Liu,Yuhong摘要:为了发挥C语言和汇编语言各自的优点,二者需要相互调用函数。
本文首先介绍了MSP430单片机的C语言函数的参数传递规则,然后对C语言和汇编语言的混合编程进行了详细描述,最后给出应用实例。
关键字:MSP430单片机IAR C语言汇编语言混合编程中图分类号:TP368.1 文献标识码:AAbstract:In order to play the vritues of c and assembler language,they need to call each other’s function. This paper describes the rules of C-Compiler for passing variables between functions, mixing c and assembler with MSP430 in details,then gives an application example.Keyword:MSP430 MCU;IAR C-Compiler;Assembler Language;Mixing ProgrammingMSP430是一款16位的单片机,它具有超低功耗、丰富的片内外围模块、多样的可选型号、软件对硬件的灵活控制能力等优点。
因此特别适合于以电池为电源的应用场合或手持设备,目前在国内主要应用于三表系统和消防设备方面。
MSP430单片机的开发软件较常用的是IAR公司的IAR Embedded Workbench集成开发环境,它可以编辑、汇编和编译汇编语言和C语言源文件,并且其C语言和汇编语言具有相同格式的头文件,给开发带来了灵活性。
C语言具有编程简单,可以移植等优点,但是产生代码较长,对硬件的直接控制能力相对较弱;汇编语言产生的代码较小,控制硬件灵活,但是可读性差,移植困难,因此为了发挥各自优点,产生高速度、高效率的代码混合编程是最好的选择。
汇编语言与 C 语言的混合程序设计技术
![汇编语言与 C 语言的混合程序设计技术](https://img.taocdn.com/s3/m/404f866a5acfa1c7aa00cc12.png)
汇编语言与 C 语言的混合程序设计技术一、混合编程中如何进行参数传递汇编语言程序和 C 语言程序在调用时会涉及到参数传递 ,一般采用堆栈进行传递。
在汇编语言中将 BP 作为基址寄存器 , 调用程序先将来自于 C 语言程序中的参数依次压入堆栈中 , 然后当需要使用这些参数时 , 再用 BP加上不同的偏移量依次对堆栈中的数据进行存取操作不同类型数据的传送有着一些不同1、整数型常量的传递整数型常量的传递是将所传递整数从上到下按顺序存储在参数区中, 以字为单位按十六进制方式存放2、字符型常量的传递c语言规定字符型常量要用单引号括起,因此传递时应特别注意传递的方式是将字符以ASCII码的形式以字节为单位放在参数区中如遇多个字符的传递可直接将多个字符顺序连写在一起用单引号括起来3、字符串常量的传递,在C语言里,字符串要求用双引号括起来传递的方式不同于以上两常量它是将字符串存放在某个数据区域内将字符串的首址指针放存参数区中因此在参数区中我们不可能找到所传送的字符串,能见到的只有一个地址指针4、整数型变量传递整数型变量的传递类似于整数型常量的传递只是将整数型变量中的内容加以传递5、字符型数组的传递字符型数组的传递类似于字符串常量的传被传递数组中的字符被存放到某个数据区而将字符数组所在的首址指针放到参数区6、整型数组的传递由于整型数组的数据量一般较大 , 因此我们认为整型数组的传递以传递指针为好。
正是由于C语言有指针运算功能 ,数组的传递先进行指针运算 ,得到数组的首指针,再将指针传送到参数区中。
二、简述混合编程的常见形式C调用汇编有两种方法,一是直接在C中插入汇编语句,二是分别编写汇编子程序和C语言程序,由C调用汇编程序。
方法一适用只需一两句汇编就能完成的程序;方法二较通用,如用汇编编写延时子程序可以实现精确延时。
使用方法二的注意事项有以下几点:1、函数声明C中在函数前加extern声明此函数为外部函数,在汇编中要声明函数名为全局变量如extern void delay(void); / 定义函数 /globl delay ; / 声明全局变量 /_delay:; / 函数开始 /2、参数传递一般用寄存器传递参数,如果返回结果需要多个字节表示,最好用 SRAM 保存即在汇编中将结果存入SRAM在C中读取相应的地址。
C语言和汇编语言混合编程
![C语言和汇编语言混合编程](https://img.taocdn.com/s3/m/5bc034ff04a1b0717fd5dd2b.png)
C/C++ 语言和汇编语言混合编程开发为了充分利用DSP芯片的硬件资源,更好发挥C/C++ 语言和汇编语言进行软件开发的各自优点,可以将两者有机的结合起来,兼顾两者优点,避免其弊端。
因此,在很多情况下,采用混合编程方法能更好地达到设计要求,完成设计任务。
C/C++语言和汇编语言混合编程的具体方法有以下几种:(1)独立编写C/C++程序和汇编程序,分开编译或汇编形成各自的目标模块,再用链接器将C/C++模块和汇编模块链接起来,这是一种灵活性较大的方法。
但用户必须自己维护各汇编模块的入口和出口代码,自己计算传递参数在堆栈中的偏移量,工作量稍大,但能做到对程序的绝对控制,也能满足软件设计结构化的要求。
这是主要讲述的方法。
(2)在C/C++程序中使用汇编程序中定义的变量和常量。
(3)在C/C++程序中直接内嵌汇编语句。
这种方法可以在C/C++程序中实现C/C++语言无法实现的硬件控制功能,如修改中断控制寄存器、中断标志寄存器等。
(4)在C/C++源程序中使用内部函数直接调用汇编语言语句。
后3种方法由于在C/C++语言中直接嵌入了汇编语言的成分,容易造成程序混乱,C/C++环境被破坏,甚至导致程序崩溃,而编程者又很难对不良结果进行预期和有效控制。
而如果采用第一种方法,只要遵循有关C/C++语言函数调用规则和寄存器规则,就能预见到程序运行的结果,保证程序正确。
下面分别讲述函数调用规则和寄存器规则。
1.函数调用规则C/C++编译器对函数调用强加了一组严格的原则。
除了特殊的运行时间支持库函数外,任何调用函数和被C/C++函数调用的函数都必须遵守这些原则。
不遵守这些原则可能破坏C/C++环境并导致程序失败。
图1说明了典型的函数调用。
在这个例子中,参数被传递到堆栈中调用者的参数块,函数再使用这些参数调用被调用函数。
注意,第一个参数是在A累加器中传递的。
这个例子还说明了汇编器对被调用函数的局部帧的分配。
局部帧包括局部变量块和局部参数块两部分,其中局部参数块是局部帧中用来传递参数到其他函数的部分。
第6章 C语言和汇编语言混合编程(C55x DSP)
![第6章 C语言和汇编语言混合编程(C55x DSP)](https://img.taocdn.com/s3/m/96a086bac77da26925c5b068.png)
第6章 C语言和汇编语言混合编程
2. 编译模式 使用C编译器,在进入汇编程序时,C55x的CPL(编译模 式位)自动被置1,相对寻址模式使用堆栈指针SP。如果在汇 编程序中需要使用相对直接寻址模式访问数据存储器,则必 须改成数据页DP直接寻址模式,这可以通过清CPL位实现。 在返回C调用程序前,CPL位必须重新置1。
序清单输入到这些文件当中,保存并将其添加到工程之中。
第6章 C语言和汇编语言混合编程
3. 编译链接工程和装载输出文件 编译链接工程,修改错误,直到无错误信息提示为止, 再装载输出文件。 4. 打开CPU寄存器视窗 在主菜单中选择View→Registers→CPU Registers命令, 打开CPU寄存器视窗,观察CPU寄存器的变化情况。
int s4; s4=sum(); s1=mac1(x,a,n); //*ar0=x[0],*ar1=a[0],t0=n,return is stored in t0
s2=mac2(x,a,n);
//*ar0=x[0],*ar1=a[0],t0=n,return is stored in ac0
第6章 C语言和汇编语言混合编程
“ _ ”。以下是C函数调用汇编子程序的例子。
第6章 C语言和汇编语言混合编程
//C源程序: extern int sum(int *); //参考一个汇编函数 int x[4]={0x1223,0x345,0x2345,0x3444}; //定义全局变量并初始化
int s;
void main() {
参数类型和寄存器安排顺序表。
第6章 C语言和汇编语言混合编程
表6-1 参数类型和寄存器安排顺序表
第6章 C语言和汇编语言混合编程
单片机C语言编程与汇编混合编程
![单片机C语言编程与汇编混合编程](https://img.taocdn.com/s3/m/fff87024ccbff121dd36835a.png)
单片机C语言编程与汇编混合编程时出现的问题悬赏分:30 - 解决时间:2008-12-29 11:07#include<reg51.h>#pragma srcvoid Delay(){#pragma asmMOV R2,#20D1:MOV R3,#100D2:MOV R4,#229DJNZ R4,$DJNZ R3,D2DJNZ R2,D1#pragma endasm}void main(){unsigned char c,i;while(1){c=0xfe;for(i=0;i>7;i++){P0=c;Delay();c<<=1;}}}TEST1.C(3): error C252: misplaced primary control, line ignoredTEST1.C(6): error C272: 'asm/endasm' requires src-control to be activeTEST1.C(15): error C272: 'asm/endasm' requires src-control to be active用KEIL 编译后出现上面几个错误.我将#pragma src 放在main() 前也不行,有各位高手指点提问者:lzh2113 - 二级最佳答案#include<reg51.h>main(){#pragma asmMOV R2,#20D1:MOV R3,#100D2:MOV R4,#229DJNZ R4,$DJNZ R3,D2DJNZ R2,D1#pragma endasm}void main(){unsigned char c,i;while(1){c=0xfe;for(i=0;i>7;i++){P0=c;Delay();c<<=1;}}TEST1.C(3): error C252: misplaced primary control, line ignoredTEST1.C(6): error C272: 'asm/endasm' requires src-control to be activeTEST1.C(15): error C272: 'asm/endasm' requires src-control to be active#1 楼主:keil C 语言与汇编语言混合编程贴子发表于:2009/2/19 16:41:04文章来看proteus 仿真网 /bbs keil C 语言与汇编语言混合编程1. C 语言中嵌入汇编1、在C 文件中要嵌入汇编代码片以如下方式加入汇编代码:#pragma ASM; Assembler Code Here#pragma ENDASM2、在Project 窗口中包含汇编代码的C 文件上右键,选择“Options for ...”,点击右边的“Generate Assemb ler SRC File”和“Assemble SRC File”,使检查框由灰色变成黑色(有效)状态;3、根据选择的编译模式,把相应的库文件(如Small 模式时,是Keil\C51\Lib\C51S.Lib)加入工程中, 该文件必须作为工程的最后文件;4、编译,即可生成目标代码。
汇编语言和C语言的简单混合编程
![汇编语言和C语言的简单混合编程](https://img.taocdn.com/s3/m/48cbef42f6ec4afe04a1b0717fd5360cba1a8d4f.png)
ASM JB COPY
/*转移到C的标号*/
ASM CMP A1,’Z’
ASM JA COPY /
/*不是’A’到’Z’之间的字符原样复制*
ASM ADD A1,20H
/*是小写字母转换成大写字母*/
copy:ASM STOSB
/* C语言定义的标号*/
ASM CMP AL,0
/* C语言中字符串用0结尾 */
12
注意:直接使用Turbo C的连接程序TLINK进行连接时,用户必须指定要连接 的与存储模式一致的初始化模块和函数库文件,并且初始化模块必须是第 一个文件。上例中,Lib\c0m和Lib\cm就是在Lib目录下中型存储模式的 初始化模块c0m.obj和函数库cm.lib。 如果形成的可执行文件exampl. exe正确,它的运行结果将是:
6
}
编辑完成后,假定该文件名为,在命令行输人如下 编译命令(选项-I和-L分别指定头文件和库函数的 所在目录):
TCC –B –Iinclude –Llib example.c 生成可执行文件example.exe,程序运行后输出的结
果将是:
OLD STRING IS I’AM a good STUDENT!
/*GOOD函数返回值缺省为INT型*/
EXTERN char tempvar
/*TEMPVAR变量为CHAR型*/
经说明后,这些外部变量、过程、函数可在C程序中直接使用,函数的参数在传 递过程中要求参数个数、类型、顺序要一一对应。
和纯汇编语言多模块编程要求一样,汇编语言程序的标识符(子程序名和变量名)
以用换行符结束;一行中可以有多个汇编语句,相互间用分号分隔, 但不能跨行书写。嵌入汇编语句的分号不是注释的开始;要对语句注 释,应使用C语言的注释,如/*……*/。例如:
51单片机C语言与汇编语言混合编程浅析_严峥晖(1)
![51单片机C语言与汇编语言混合编程浅析_严峥晖(1)](https://img.taocdn.com/s3/m/5e15a7542e3f5727a5e96239.png)
大多数情况下采用C51语言即可完成预期的任务,但是采用C51 语言编程还是存在着效率不如汇编高、对底层硬件控制不如汇编方 便、对代码执行速度有特殊要求(如精确延时)情况时无法实现等缺 点。因而,编写高速、高效率、可移植性好的单片机应用程序,必须 结合C51语言与汇编语言各自的优点,即C51语言与汇编语言混合编 程。混合编程通常的做法是,程序的框架、复杂的数学运算、多任务 管理等用C51语言编写,对于那些要求执行效率高、精确延时、直接 控制底层硬件等部分则由汇编语言来完成。
第三章 ARM中的C语言和汇编混合编程
![第三章 ARM中的C语言和汇编混合编程](https://img.taocdn.com/s3/m/b8407092cc22bcd126ff0cc2.png)
ATPCS规定数据栈为FD类型,并对数据栈的操作是8字节 对齐的。异常中断的处理程序可以使用被中断程序的数据 栈,这时用户要保证中断的程序数据栈足够大。下面是一 个数据栈的实例及相关的名称。 数据栈指针:指向最后一个写入栈的数据的内存地址。 数据栈的基地址:是指数据栈的最高地址。 已占用的数据栈:是指数据栈的基地址和数据栈栈指针之 间的区域。 未占用的数据栈:是指数据栈指针和数据栈界限之间的区 域。 数据栈中的数据帧:是指在数据栈中,为子程序分配的用 来保存寄存器和局部变量的区域。
在ARM C语言程序中使用关键词_asm来标识一段汇编指 令程序,基本格式为: _asm { instruction [;instruction] … [instruction] } 在以上的语法中需要指出的是:如果一行中有多个汇编指 令,指令间用分号“;”隔开;如果一条指令占多行,要 使用续行符号“\”;在汇编指令段中可以使用C语言的注释 语句。
3.2 内嵌汇编
使用内嵌汇编可以在C程序中实现C语言不能够完 成的一些操作,同时程序的代码效率也能够比较 高。在内嵌汇编指令包括大部分的ARM指令和 Thumb指令。但是不能够直接引用C语言的变量 定义,数据交换必须通过ATPCS进行。嵌入式汇 编在形式上往往表现为独立定义的函数体。
3.2.1 内嵌汇编的语法格式
对应不同的数据类型要采用不同的LDR/STR指令。 对于unsigned char类型,使用LDRB/STRB访问。 对于unsigned short类型,使用LDRH/STRH访问。 对于unsigned int 类型,使用LDR/STR访问。 对于char类型,使用LDRSB/STRSB访问。 对于short类型,使用LDRSH/STRSH访问。 对于小于8个字的结构型变量,可以通过一条 “LDM/STM”指令来读/写整个变量。 对于结构型变量的数据成员,可以使用相应的 “LDR/STR”指令来访问,这时必须知道该数据成员相对 于结构型变量开始地址的偏移。
单片机C与汇编混用
![单片机C与汇编混用](https://img.taocdn.com/s3/m/daff7984b9f3f90f77c61b55.png)
2.在C51中嵌入汇编程序通过C51中的预处理指令#pragma asm/endasm语句来实现的。
其格式如下:#pragma ASM;汇编程序代码#pragma ENDASM3. 在C51中调用汇编程序这种方法应用较多,C模块与汇编模块的接口较简单,分别用C51与A51对源程序进行编译,然后用L51将obj文件连接即可,关键问题在于C函数与汇编函数之间的参数传递和得到正确的返回值,以保证模块间的数据交换。
5.2 混合汇编的参数传递与实现5.2.1 混合汇编的参数传递1.汇编程序调用C51函数的参数传递如C51函数有参数,则汇编程序在调用C51函数前要准备好参数。
在汇编程序中,C51函数最左边的一个参数由寄存器A传递,其他的参数按顺序通过堆栈给出。
C51函数的返回值是返回到A寄存器或者由A寄存器给出的地址。
2.在C51中嵌入汇编程序的参数传递通过变量或特殊功能寄存器来实现难点))中调用汇编程序的参数传递((难点3.在C51中调用汇编程序的参数传递C51中调用汇编程序进行参数传递时都必须严格遵守C51函数的参数和返回值的相关约定。
C51中调用汇编程序进行参数传递的方式有两种,一种是通过寄存器传递参数,第二种是通过固定存储区传递。
5.2.2 混合汇编的实现1.C51中嵌入汇编程序的实现方法第一步:在C文件中以如下方式嵌入汇编程序。
#include <reg51.h>void main(void){P2=1;#pragma asmMOV R7,#10DEL:MOV R6,#20DJNZ R6,$DJNZ R7,DEL#pragma endasmP2=0;}第二步:在Keil C51软件的Project 窗口右击嵌入汇编程序的C文件,在弹出的快捷菜单中选择Options for ...命令,选中右边的Generate Assembler SRC File和Assemble SRC File复选框,使检查框由灰色变成黑色(有效)状态。
单片机C语言与汇编语言的混合编程
![单片机C语言与汇编语言的混合编程](https://img.taocdn.com/s3/m/d6f9a31414791711cc7917e8.png)
在单片机C语言与汇编语言的混合编程过程中,C语言调用汇编代码常有两种方法:一是直接在C语言程序中嵌入汇编语句;二是C语言调用汇编语言子程序。
把汇编语言程序加入到C语言程序中,必须使汇编程序和C程序一样具有明确的边界、参数、返回值和局部变量,必须为汇编语言编写的程序段指定段名并进行定义,如果要在它们之间传递参数,则必须保证汇编程序用来传递参数的存储区和C函数使用的存储区是一样的。
1.C语言内嵌汇编代码1.1内嵌汇编代码的格式在C语言程序中嵌入汇编代码,可以通过预编译指令“asm”来实现。
其格式如下:;C代码#pragmaasm;汇编代码#pragmaendasm;C代码1.2Keil软件中含内嵌汇编代码的C文件的编译与连接1.2.1工程相关选项的设置在Project窗口中包含汇编代码的C文件上点击右键,选择“Optionsfor...”,然后在弹出的窗口中选中“GenerateAssemblerSRCFile”和“AssembleSRCFile”两项。
选中这两项编译器才会将“asm”与“endasm”中的代码复制到输出的SRC文件中,然后才会将这些代码放入它所产生的目标文件中。
在编译过程中产生SRC文件为C文件对应的汇编文件,我们还可以对SRC文件进行仔细的分析来了解其函数封装规则。
1.2.2加入库文件根据所选择的编译模式,在工程中添加相应的库文件(如Small模式时,库文件为C51S.Lib)。
1.2.3编译与连接选择“Project/BuildTarget”仅对修改过的文件进行编译与连接处理,或选择“Project/BuildallTargetFiles”对所有源程序全部进行编译与连接,生成目标代码。
1.3内嵌汇编代码的C文件实例*************example1.c****************#include<reg51.h>voidmain(void){P2=1;#pragmaasmMOVR7,#10DEL0:MOVR6,#20DEL1:DJNZR6,DEL1DJNZR7,DEL0#pragmaendasmP2=0;}example1.c经过编译与连接后可得到下面的example1.SRC文件:;.\example1.SRCgeneratedfrom:example1.c……(寄存器描述省略)?PR?main?EXAMPLE1SEGMENTCODEEXTRNCODE(?C_STARTUP)PUBLICmain;#include<reg51.h>;voidmain(void)RSEG?PR?main?EXAMPLE1main:;SOURCELINE#2;{;SOURCELINE#3;P2=1;;SOURCELINE#4MOVP2,#01H;#pragmaasm;MOVR7,#10MOVR7,#10;DEL0:MOVR6,#20DEL0:MOVR6,#20;DEL1:DJNZR6,DEL1DEL1:DJNZR6,DEL1;DJNZR7,DEL0DJNZR7,DEL0;#pragmaendasm;P2=0;;SOURCELINE#11CLRAMOVP2,A;};SOURCELINE#12RET;ENDOFmainEND从上述SRC文件中可以看出,在“asm”与“endasm”中的代码被复制到输出的SRC文件中2.C语言调用汇编函数2.1C语言调用不传递参数的汇编函数2.1.1汇编文件的格式在汇编语言中,要求用汇编语言编写的函数和用C编译器编译出来的代码风格一样,这样可以让开发的程序具有很好的可读性和可维护性,另外也很容易和C编写的函数进行连接。
第六讲_C与汇编语言混合编程
![第六讲_C与汇编语言混合编程](https://img.taocdn.com/s3/m/c5bb5838453610661ed9f4b5.png)
数据栈的使用规则
•根据堆栈指针指向位置的不同 和增长方向的不同 可以分为以下4种数据栈 : FD (Full Descending) 满递减 ED (Empty Descending)空递减 FA (Full Ascending) 满递增 EA (Empty Ascending) 空递增 ATPCS规定数据栈为FD(满递减)类型,并且 对数据栈的操作是8字节对齐的。
内嵌汇编注意事项
必须小心使用物理寄存器,如R0~R3,LR和PC。 不要使用寄存器寻址变量。 使用内嵌汇编时,编译器自己会保存和恢复它可能用 到的寄存器,用户无须保存和恢复寄存器。 LDM和STM指令的寄存器列表只允许物理寄存器。 汇编语言用“,”作为操作数分隔符
三、C和ARM汇编程序间相互调用
内嵌汇编指令的语法格式
• __asm(“指令[;指令]”); • ARM C汇编器使用关键字“__asm"。如果有多 条汇编指令需要嵌入,可以用“{}”将它们 归为一条语句。如: • __asm •{ • 指令[;指令] • … • [指令] •} • 需要特别注意的是__asm是两个下划线。
内嵌的汇编指令的特点
在 C 和 ARM 汇编程序之间相互调用必须遵守 ATPCS (ARM-Thumb Procedure Call Standard)规则。 C和汇编之间的相互调用可以从以下这程序中调用C语言程序
汇编程序访问全局C变量
C函数原型: int 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 f AREA f,CODE,READONLY IMPORT g ;声明该变量函数g( ),i在R0中 STR LR,[SP,#- 4]! ;预先保存LR ADD R1,R0,R0 ;计算2 * i(第2个参数) ADD R2,R1,R0 ;计算3*i(第3个参数) ADD R3,R1,R2 ;计算5*i(第5个参数) STR R3,[SP,#- 4]! ;将第5个参数压人堆栈 ADD R3,R1,R1 ;计算4 * i(第4个参数) BL g ;调用C程序g( ) ADD SP,SP,#4 ;调整数据栈指针,准备返回 LDR PC,[SP],#4 ;从子程序返回 END
keil C语言与汇编语言的混合编程方法
![keil C语言与汇编语言的混合编程方法](https://img.taocdn.com/s3/m/f1c15165783e0912a2162aef.png)
} /********************************************** * 向 COM1 发送一个字符 **********************************************/ void SendChar(uint8 byteToSend) { SBUF=byteToSend ; while(!TI); TI=0 ; } /************************************************************ * 读取一个字节 ***********************************************************/ uint8 read_byte() { uint8 recvdata=8 ; delay(); return recvdata ; } /************************************************** * 主 程 序 ***************************************************/ int main() { UartInit();//串口初始化 while(1) { buf[i++]=read_byte(); } } /************************************************** * 串口中断处理 ***************************************************/ void chuankou()interrupt 4 { if(RI) for(i=0;i<sizeof(buf);i++) { SendChar(buf[i]); } //延时
第6章__C语言和汇编语言混合编程(C55x_DSP)
![第6章__C语言和汇编语言混合编程(C55x_DSP)](https://img.taocdn.com/s3/m/fb5342223968011ca3009177.png)
第6章 C语言和汇编语言混合编程
混合编程中参数传递和寄存器使用
第6章 C语言和汇编语言混合编程
6.1 混合编程中参数传递和寄存器使用
在很多DSP应用中都使用C语言和汇编语言进行混合编 程。C语言具有可读性高、便于维护和可移植性好等优点, 然而汇编语言具有实时运行效率高和代码效率高的优点。使 用汇编语言可以更充分地利用DSP的硬件资源,例如乘累加 单元、单指令重复、块重复和块移动等。
int MessageLength()
{ int Length = 0; char *pMessage; //定义字符指针变量
pMessage = Message;
{
//指针指向Message 内存块的首地址
while(*pMessage != '$') //$为字符串的结束符 Length++; pMessage++; } return(Length); //返回字符串的长度 }
MRS tmp, CPSR
//把状态寄存器加载给tmp
ORR tmp, tmp, #80 //将IRQ控制位置1 MSR CPSR_c, tmp //加载程序状态寄存器 } }
第6章 C语言和汇编语言混合编程
EXPORT Message extern char* Message; @声明全局标号 Message DCB "HELLO$" @定义5个有效字符,$为结束符
3. 应用实例 以下是几个参数传递和返回值使用寄存器的例子。
【例6-1】 返回值存放于T0,参数传递时,16位数据i
使用T0,16位数据指针*k使用AR0,32位数据p使用AC0。 函数定义及使用寄存器关系表示如下:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(1)、C51语言中调用汇编语言程序;
C51语言调用汇编语言程序要注意以下几点:
1:在文件栏选中File Group和C51程序原文件,在配置文件选项中激活“产生汇编(SRC)文件,“编译(SRC)文件”和“创建工程(目标)时包含”三个选项。
2:根据选择的编译模式,把相应的库文件(如SMALL模式,库文件为KEIL\C51\LIB\)加入工程中。
3:在C51语言中必须声明需要调用的函数为外部函数。
extern void DELAY(void);
4:在汇编语言程序中必须声明被调用子程序为公共子程序,在被调用的文件中还需要声明此文件是可从新定位的。
PUBLIC DELAY,DEL
DELAYY SEGMENT CODE
RSEG DELAYY
实例如下:
C51语言文件:
#include ""
extern void DELAY(void);
extern void DEL(void);
void main(void)
{
P1=0x00;
DELAY();
DEL();
P1=0xff;
}
汇编语言文件:
PUBLIC DELAY,DEL
DELAYY SEGMENT CODE
RSEG DELAYY
DELAY: MOV R2,#3H
DJNZ R2,$
RET
DEL: MOV R3,#03H
DJNZ R3,$
RET
END
(2)、C51语言中调用外部的C51函数;
C51语言调用外部的C51函数的注意事项如下:
1:在主调函数中必须声明被调用的函数为外部类型的函数,其余都一样。
实例如下:
主调函数A:
#include ""
extern void delay(void);
sbit P1_1=P1^1;
void main(void)
{
P1_1=0;
delay();
P1_1=1;
}
被调用的函数B:
delay()
{
unsigned char i;
i=0;
}
(3)、C51语言中嵌入汇编程序;
在C51语言中嵌套使用汇编语言编写程序要注意以下的几个问题:
1:在文件栏选中File Group和C51程序原文件,在配置文件选项中激活“产生汇编(SRC)文件,“编译(SRC)文件”和“创建工程(目标)时包含”三个选项。
2:根据选择的编译模式,把相应的库文件(如SMALL模式,库文件为KEIL\C51\LIB\)加入工程中。
3:用#pragma asm,和#pragma endasm语句包含嵌入的汇编语言程序。
实例如下:
#include ""
void delay(void);
void main(void)
{
void delay(void);
P1=0x00;
#pragma asm
MOV R3,#08H
DJNZ R3,$
#pragma endasm
P1=0xff;
}
void delay(void)
{
#pragma asm
MOV R4,#08H
DJNZ R4,$
#pragma endasm
}
(4)、汇编语言中外部子程序的调用
汇编语言中外部子程序的调用
在遍写程序的时候,可以在一个文件的汇编程序中调用另一个文件的子程序。
具体的方法如下。
1:在主程序文件中要声明所调用的子程序在外部。
比如在主程序中调用子程序名为DELAY 的子程序,其格式为:EXTRN CODE (DELAY)
2:在被调用的文件中要声明,被调用的子程序为公共类型的。
比如DELAY要声明的格式为:PUBLIC DELAY
3:在被调用的文件中还需要声明此文件是可从新定位的。
SS SEGMENT CODE
RSEG SS
整个事例如下,文件A:
EXTRN CODE (DELAY)
EXTRN CODE (DEL)
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN: NOP
TT: MOV P0,#00H
LCALL DELAY
LCALL DEL
MOV P0,#0FFH
LJMP TT
END
文件B:
PUBLIC DELAY
PUBLIC DEL
SS SEGMENT CODE
RSEG SS
DELAY: MOV R2,#3H
DJNZ R2,$
RET
DEL: MOV R3,#03H
DJNZ R3,$
RET
END。