汇编语言和C语言

上传人:206****923 文档编号:56677981 上传时间:2018-10-15 格式:PPT 页数:20 大小:92KB
返回 下载 相关 举报
汇编语言和C语言_第1页
第1页 / 共20页
汇编语言和C语言_第2页
第2页 / 共20页
汇编语言和C语言_第3页
第3页 / 共20页
汇编语言和C语言_第4页
第4页 / 共20页
汇编语言和C语言_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《汇编语言和C语言》由会员分享,可在线阅读,更多相关《汇编语言和C语言(20页珍藏版)》请在金锄头文库上搜索。

1、*4。8 汇编语言和C语言的混合编程,本节介绍不同的模块,不同的语言相结合的编程方法。 通常情况下以高级语言编写主程序,用汇编语言编写与硬件有关的子程序。不同的编译程序 高级语言对汇编的调用方法不同,在Franklin C51中,是将不同的模块(包括不同语言的模 块)分别汇编或编译,再通过连接生成一个可执行文件。C语言程序调用汇编语言程序要注意以下几点:1. 被调函数要在主函数中说明,在汇编程序中,要使用伪指令使CODE选项有效并声明为可再 定位段类型,并且根据不同情况对函数名作转换,见表4.6。,2.对为其他模块使用的符号进行PUBLIC声明,对外来符号进行EXTRN声明。 3.参数的传递。

2、在混合语言编程中,关键是入口参数和出口参数的传递,Franklin C编译器可使用寄存器传递参数,也可以使用固定存贮器或使用堆栈,由于8XX51的堆栈深度有限,因此多用寄存器 或存贮器传递。用寄存器传递最多只能传递三个参数,选择固定的寄存器,见表4.7 。 表4.7,例如 func1(int a) “a”是第一个参数,在R6,R7传递,func2(int b,int c,int *d)“b”在R6,R7中传递,“c”在R4,R5中传递,“d”在R1,R2 ,R3中传递。 如果传递参数寄存器不够用,可以使用存贮器传送, 通过指针取得参数。汇编语言通过寄存器或存贮器传递参数给C语言程序,汇编语言通

3、过寄存器传递给C语言的返回值见表4.8。,下面通过两个实例说明混合编程的方法及参数传递过程.例4_10 用P1.0产生周期为4ms的方波,同时用P1.1产生周期为8ms的方波。 说明:设计三个模块 模块一 C语言编主程序,使 P1.1产生周期为8ms的方波; 模块二 用C语言编程,使P1.0产生周期为4ms的方波; 模块三 用汇编语言编写延时1ms 程序。模块一调用模块二获得8ms方波, 模块二调模块三 ,向汇编程序传递字符型参数(x=2),延时2ms。 各模块程序如下:,模块一: P1.1产生周期为8ms的方波 #include #define uchar unsigned charsbit

4、 P1-1=P11;void delay4ms(void); /* 定义延时4ms函数(模块二) */main( ) uchar i;for(;) P1-1=0;delay4ms();/* 调模块二延时4ms */P1-1=1;delay4ms();/* 调模块二延时4ms*/ ,模块二(delay4ms) :使P1.0产生周期为4ms的方波#include#define uchar unsigned charsbit P1-0=P10;delaylms(uchar x); /* 定义延时1ms函数(模块三) */void delay4ms(void)P1-0=0;delaylms(2);/*

5、 调汇编函数(模块三) */P1-0=1;delaylms(2);/* 调汇编函数(模块三)* ,模块三: PUBLIC -DELAY1MS ;DE LAY1MS为其他 模块调用DE SEGMENT CODE ;定义DE段为再定位程序段RSEG DE ;选择DE为当前段 - DELAY1MS: NOPDELA: MOV R1,#0F8H ;延时LOP1: NOP NOPDJNZ R1,LOP1DJNZ R7,DELA ;R7为C程序传递 过来的参数(x=2) EXIT: RETEND 上例可见汇编语言程序从R7中获取C程序传递参数(x=2) 。,例2.在汇编程序中比较两数大小,将大数放到指定的

6、存储区,由C程序的主调函数取出。 C语言程序,模块一: #define uchar unsigned char void max(uchar a, uchar b); /* 定义汇编函数 */main()uchar a=5,b=35,*c,d;c=0x30; /* c指针变量指向内部 RAM 30H单元 */max(a,b); /* 调汇编函数,a,b为传递的参数 */d=*c; /* d存放模块二传递过来的参数 */ ,模块二:汇编语言程序PUBLIC -MAX MAX为其 他模块调DE SEGMENT CODE ;定义DE段为再定位程序段 RSEG DE ;选择DE为当前段MAX: MOV

7、 A,R7 ;取模块一的参数aMOV 30H,R5 ;取模块一的参数bCJNE A,30H,TAG1 ;比较a,b的大小 TAG1: JC EXITMOV 30H,R7 ;大数存于30H单元 EXIT: RETEND可见,C语言程序通过R7和R5传递字符型参数a和b到汇编语言程序,汇编语言程序将返回值 放在固定存贮单元,主调函数通过指针取出返回值。,C语言程序调用汇编程序最多只能传递三个参数,如果多于三个参数,就需要通过存贮qu区传递,这就需要在汇编程序中建立数据段,在下例中C语言程序向汇编传递六个参数,汇编程序 *C_CALL.C* #pragma code small extern int

8、 afunc(char v_a,char v_b, char v_c, char v_d,char v_e,char v_f); /*外来函数说明 void C_call(void) char v_a=0x11; /*传递参数赋值*/char v_b=0x18;char v_c=0x33;char v_d=0x44;char v_e=0x55;char v_f=0x98;,int data *aa; /*指针变量指向int型data区*/int A_ret; /*存汇编返回结果的变量*/aa=0x30; /*置指针*/A_ret=afunc(v_a,v_b,v_c,v_d,v_e,v_f);

9、/*调汇编函数*/*aa=A_ret; /*取汇编返回结果*/ *aa=(int)0; /*为方便观察改值,强制0为int型*/*aa=A_ret; /*再次观察汇编返回结果*/ void main(void) /*主函数*/char a1,a2,a3; /*为方便观察设a1 a2 a3*/a1=0; a2=2; a3=3;C_call();a1=1;a2=3;while(1); ,*AFANC.ASM* PR_AFUNC SEGMENT CODE ;名为AFUNC段为代码段 (PR)在CODE区可再定位, DT_AFUNC SEGMENT DATA OVERLAYABLE;名为AFUNC段为

10、数据段(DT)在DATA区,可再定位,可以覆盖PUBLIC ?_afunc?BYTE ;公共符号定义PUBLIC _afuncRSEG DT_AFUNC ?_afunc?BYTE: ;数据段保留参数传递区v_a: DS 1v_b: DS 1v_c: DS 1v_d: DS 1,v_e: DS 1 v_f: DS 1RSEG PR_AFUNC _afunc: USING 0 ;程序段 MOV A,R7 ;取R7中的v_a ADD A,R5 ;取R5中的v_b ADD A,R3 ;取R3中的v_c ADD A,v_d ADD A,v_e ADD A,v_f MOV R7,A ;和存R7,进位存R6

11、MOV A,#0 ;以便返回RLC A,MOV R6,A RETEND 编译连接方法以上各模块可以先分别汇编(A51)和编译(C51)(选择DEBUG编译控制项),生成的.OBJ文件,然后运 行L51将各OBJ文件连接,生成一个新的文件。在集成环境下的连接调试可以连续进行,比上面方法更为方便,现使用wave(伟福)的仿真软 件ICExplorerW(ICE For Windows)的编译连接步骤如下: 1.编辑好各个模块,保存。 2.点击文件/新建项目,弹出项目窗口。,3.点击项目菜单,选加入模块,此时弹出有文件目录的对话框,选中要加入刚才编辑好的文 件(模块),并打开。此时在项目窗口中可以看

12、到加入的模块文件。 4.点击项目菜单中的全部编辑,并取名保存项目。于是系统对加入各模块进行编译,并进行 连 5.编译连接完成会弹出信息窗口,如编译连接有错,信息窗口将出现错误信息。 6.模块连接成功,生成二进制文件(.BIN)和十六进制文件(.HEX)。 7.点击跟踪或单步按钮,就可对程序进行跟踪调试,程序运行到不同模块时,wave就会弹 出相应的模块源程序窗口,显示程序运行情况。,4。9 小 结本章介绍了C51的基本数据类型、存贮类型及对C51对单片机内部部件的定义,并介绍了C语 言 基础知识,最后通过编程实例介绍了各种结构的程序设计,以上是利用C语言编单片机程序 的基础,都应该掌握并灵活应

13、用,只有多编程,多上机才能不断提高编程的能力。如何编写高效的C语言程序,通常应注意以下问题:,1. 定位变量 经常访问的数据对象放入在片内数据RAM中,这可在任一种模式(COMPACT/LARGE)下用输入存贮器类型的方法实现。访问片内RAM要比访问片外RAM快得多。在片内RAM由寄存器组、位 数据区、栈和其它由用户用“data”类型定义的变量共享。由于片内RAM容量的限制(128 256)字节,由使用的处理器决定),必须权衡利弊以解决访问效率和这些对象的数量之间的 矛盾。 2 .尽可能使用最小数据类型MCS-51系列单片机是8位机,因此对具有“char”类型的对象的操作比“int”或“lon

14、g”类型,的对象方便得多。建议编程者只要能满足要求,应尽量使用最小数据类型。C51编译器直接支持所有的字节操作,因而如果不是运算符要求,就不作“int”类型的转 换,这可用一个乘积运算来说明,两“char”类型对象的乘积与8XX51操作码“MUL AB”刚 好相符。如果用整型完成同样的运算,则需调用库函数。只要有可能,使用“unsigned”数据类型 8XX51单片机的CPU不直接支持有符号数的运算。因而C51编译必须产生与之相关的更多的 代码以解决这个问题。如果使用无符号类型,产生的代码要少得多。,只要有可能,使用局部函数变量 编译器总是尝试在寄存器里保持局部变量。 这样,将索引变量(如FOR和WHILE循环中计数变 量)声明为局部变量是最好的,这个优化步骤只为局部变量执行。使用“unsigned char/int ”的对象通常能获得最好的结果。,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号