欢迎来到优发表网,发表咨询:400-888-9411 订阅咨询:400-888-1571股权代码(211862)

购物车(0)

期刊大全 杂志订阅 SCI期刊 期刊投稿 出版社 公文范文 精品范文

汇编语言(合集7篇)

时间:2022-10-24 03:41:53
汇编语言

汇编语言第1篇

一、变量与函数的相互调用

c语言可以调用汇编子程序和汇编语言中定义的变量。但要注意由于。编译后的目标文件自动地在函数名和变量名前加一个下划线,所以在汇编语言中调用C语言的函数和变量时,应在函数名和变量名前加一下划线。在汇编语言程序开始部分,应对调用的函数和变量用EXTERN加以说明。

二、调用者与被调用者的参数传递

这种数据传递通过堆栈完成,在执行调用时从调用程序参数表中的最后一个参数开始,即从右到左自动依次压人堆栈;将所有参数压人堆栈后,再自动将被调用程序执行结束后的返回地址(断点)压人堆栈,以使被调程序结束后能返回主调程序的正确位置而继续执行。进人汇编子程序后,为了能正确获取主调程序并存人堆栈中的数据,被调的汇编子程序先后要做如下一些工作:

l、保存sp的副本进人汇编子程序后,子程序中免不了要有压栈和出栈的操作,故sP时刻在变化。为了能用SP访问堆栈中的参数,安全办法是一进人子程序后,先为SP制副本,以后对传递参数的访问都用副本进行。一般可用BP保存SP,如:pushbPmovbP,sp

2、保留数据空间如果汇编子程序中需要一些局部数据,可以简单地减小SP的值,以便在栈空间中保留出一段存贮区,用于存放局部数据,该区域须在子程序结束后恢复。如下语句可以保留一个局部数据区:pushbPmovbP,spsubsp,spaee;设spaee=4如上语句段中,SPACE是局部数据的总字节数。在以后的应用中,由于SP是变化的,而BP是固定的,用负偏移量可以存取局部变量。上例利用BP及偏移量,将两个字的局部数据初始化为0。

3、保留寄存器值如果在被调子程序中用到sI、DI等其它寄存器,则应先把它们压人堆栈,以保留寄存器原值。例如,下例就是将SI和DI寄存器的值压栈:pushbpmoybp,SpsubSp,sPaeePush51Pushdi

4、获取传递参数BP保留了SP在参数传递完并将BP压栈后的一个副本,利用BP可以很方便地访问各参数。现假设调用了名为funcl汇编程序模块的主函数:maln(){……fund(pl,pZ,p3);……}。各参数都是2字节的整数值,返回地址retumaddress,在小模式编译方式共占用2个字节。如果要将传递的参数p卜pZ、p3取出,并分别赋给bx、Cx、dx寄存器,可由下列语句完成这一功能:movbx,[bp+4jmovcx,[bp+6]movdx,[bp+8〕

汇编语言第2篇

汇编语言属于一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,也称为符号语言。在汇编语言中,用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址。在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。普遍地说,特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。同时,汇编语言不像其他大多数的程序设计语言一样被广泛用于程序设计,在今天的实际应用中,它通常被应用在底层、硬件操作和高要求的程序优化的场合。

(来源:文章屋网 http://www.wzu.com)

汇编语言第3篇

关键词: C 语言;汇编语言;混合编程

中图分类号:TP313 文献标识码:A 文章编号:1006-4311(2014)24-0231-02

0 引言

汇编语言是一种面向机器的语言,其优点是运行速度快,占用存储空间小,可直接对硬件进行控制。缺点是编写、调试困难、移植性差。C语言简洁、灵活、库函数丰富、调试方便、移植性好,目前已被广泛地应用于系统软件和应用软件的开发中,为了发挥各自优势,取长补短,采用混合编程。大部分程序,如界面、人机接口(外壳程序)、数据处理等用C语言编写,以提高程序的开发效率。而某些程序,如需要缩短程序的运行时间,或需要对硬件进行直接操作,或需要利用操作系统的某些功能模块,或频繁使用的程序、或需要占用内存空间少的程序(内核程序),则用汇编编写,以提高程序的运行效率。

1 嵌入式汇编

嵌入式汇编也称行内汇编,源程序中直接插入汇编语句。汇编语句可直接访问C程序中定义的常量、变量、函数。不必考虑二者之间的接口,方便编程。

1.1 嵌入式汇编语句的格式

格式:asm操作码 操作数[;或换行]

其中:操作数可以是汇编语句中的立即数、寄存器、表达式等还可以是C中的常量、变量、标号等。分号;是汇编语句结束符,并非注解,要用注解,用C的注解。如下例

所示。

1.2 汇编语句访问C的数据

嵌入的汇编语句可以访问C语言程序中的任何标识符,包括变量、常量、标号、函数名、寄存器变量、函数参数等。如下例所示。

1.3 汇编语言与C语言接口规则

1.4 编译过程

命令行键入命令:TCC-B-Iinclude-Llib 文件名.c即可. TCC会自动调用TASM.EXE和TLINK.EXE,并且TLINK.EXE能正确的找到需要的.obj和.lib文件,要保证TC目录下存在TASM.EXE文件。如果单步编译,可能会碰到很多的问题,主要是TLINK.EXE不会自己去找.obj和.lib文件。该命令的功能是:.C编译TCC.ASM汇编TASM.OBJ连接TLINK.EXE。

2 Turbo C模块连接方式

C、汇编程序各自编程,各自编译,然后连接在一起。

2.1 汇编语言与C语言接口规则

①命名约定:汇编的名字前加一个下划线,C的名字前不加下划线(编译后内部自动加),以确保两个模块内部名字一致。

3 结语

混合编程,主要涉及接口,汇编调C的函数、全局变量。C调汇编的函数、变量。本文对此做了浅述。

参考文献:

[1]谭浩强.C语言程序设计[M].清华大学出版社,2004.

汇编语言第4篇

关键词:汇编语言 高级编程语言 历史 趋势

中图分类号:TP313 文献标识码:A 文章编号:1003-9082(2017)06-0002-02

一、编程语言的发展历程

自从1946年世界上第一台电子计算机问世,人类和机器的交流方式和语言就成为了软件工程师和计算机从业者的主要研究方向,更有效更简便的编程语言成为了软件工程师的新宠儿,伴随着计算机的飞速发展,计算机的硬件升级速度也越来越快,对编程语言的要求也日益严格。在过去的几十年,编程语言有了长足的发展,至今已经有四代语言问世。大量的编程语言为了满足不同领域的编程要求和软件功能,经历了被修改,被取代,被发展等过程,最终发展成了现在编程语言的多样化。尽管人们多次试图寻找一个能够适应所有编程环境的通用语言,但是却没有一次成功。程序设计语言正在与现代科技日益飞跃,人类的智慧在日益彰显。

1.机器语言

计算机的硬件作为一种电路元件,它的输出和输入只能是有电或者没电,也就是所说的高电平和低电平,所以计算机传递的数据是由“0”和“1”组成的二进制数,所以说二进制的语言是计算机语言的本质。计算机发明之初,人们为了去控制计算机完成自己的任务或者项目,只能去编写“0”、“1”这样的二进制数字串去控制电脑,其实就是控制计算机硬件的高低电平或通路开路,这种语言就是机器语言。直观上看,机器语言十分晦涩难懂,其中的含义往往要通过查表或者手册才能理解,使用的时候非常痛苦,尤其当你需要修改已经完成的程序时,这种看起来无序的机器语言会让你无从下手,也很难找到程序的错误。而且,不同计算机的运行环境不同,指令方式操作方式也不尽相同,所以当你在这种机器语言就有了特定性,只能在特定的计算机上执行,而一旦换了机器就需要重新编程,这极大的降低了程序的使用和推广效率。但由于机器语言具有特定性,完美适配特定型号的计算机,故而运行效率远远高过其他语言。机器语言,也就是第一代编程语言。

2.汇编语言

通过我对机器语言的介绍,不难看出机器语言作为一种编程语言,灵活性较差可阅读性也很差,为了减轻机器语言带给软件工程师的不适应,人们对机器语言进行了升级和改进:用一些容易理解和记忆的字母,单词来代替一个特定的指令,比如:用“ADD”代表数字逻辑上的加减,“MOV”代表数据传递等等,通过这种方法,人们很容易去阅读已经完成的程序或者理解程序正在执行的功能,对现有程序的bug修复以及运营维护都变得更加简单方便,这种语言就是我们所说的汇编语言,即第二代计算机语言。但是这时候,计算机的硬件还是那些硬件,所以计算机还是不认识那些字母符号,这时候就需要一个专门的程序把这些字符变成计算机能够识别的二进制数。因为汇编语言只是将机器语言做了简单编译,所以并没有根本上解决机器语言的特定性,所以汇编语言和机器自身的编程环境息息相关,推广和移植很难,但是还是保持了机器语言优秀的执行效率,因为他的可阅读性和简便性,汇编语言到现在依然是常用的编程语言之一。

3.高级语言

在编程语言经历了机器语言,汇编语言等更新之后,人们发现了限制程序推广的关键因素――程序的可移植性。需要设计一个能够不依赖于计算机硬件,能够在不同机器上运行的程序。这样可以免去很多编程的重复过程,提高效率,同时这种语言又要接近于数学语言或人的自然语言。在计算机还很稀缺的50年代,Q生了第一个高级编程语言。当时计算机的造价不菲,但是每天的计算量有有限,如何有效的利用计算机有限的计算能力成为了当时人们面对的问题。同时,因为资源的稀缺,计算机的运行效率也成为了那个年代工程师追寻的目标。为了更高效的使用计算机,人们设计出了高级编程语言,来满足人们对于高效简的编程语言的追求。用高级编程语言编写的程序需要经过翻译,翻译成机器所能识别的二进制数才能由计算机去执行。虽然,高级编程语言编写的程序需要一些时间去翻译代码,从而降低了计算机的执行效率,但是实践证明,高级编程语言为工程师带来的便利远远大于降低的执行效率。经过各软件工程师和专家的不懈努力,1954年,第一个完全意义的高级编程语言―FORTRAN问世了,他完全脱离了特定机器的局限性,是第一个通用性的编程语言。从第一个编程语言问世到现今,共有几百种高级编程语言出现,很多语言成为了编程语言发展道路上的里程碑,影响很大。比如:FORTRAN、BASIC、JAVA、C、C++、python等。高级编程语言也从早期的控制信号变成了现在的有结构有格式的程序编写工具,C++等语言的出现更是开启了面向对象编程语言的新章。同时伴随着软件编写效率的提高,软件开发也逐渐变成了有规模、有产业的商业项目。

二、高级编程语言、汇编语言和机器语言的区别

根据上面的简单介绍,我们可以说作为编程语言的一种划分,高级编程语言和低级语言构成了一般意义上的计算机语言。而高级编程语言又是和汇编语言对比而言。高级编程语言作为一种通用的编程语言,它的语言结构和计算机本身的硬件以及指令系统无关,它的可阅读性更强,能够方便的表达程序的功能,更好的描述使用的算法。同时,它更容易被初学者所掌握,很容易学习。而且容易学习掌握。但是高级编程语言因为是一种编译语言,所以他的运行速度比汇编程序要低,同时因为高级语言比较冗长,所以代码的执行速度也要慢一些。所以说汇编语言更适合编写一些需要高效率运行的程序或者对程序代码的长度又要求的程序,同时在直接控制硬件方面也能够起到很好的作用。

高级编程语言,作为用户层面的程工具,用户并不需要去了解硬件的结构,而是去用逻辑的语言去实现想要的目标,但是因为高级编程语言的架构高于汇编,所以不能编写直接访问硬件资源的系统程序,因次,高级编程语言必须要调用汇编语言编写的程序来访问硬件地址。

机器语言(machine language)就是一种指令集了,它是一串数据代码,也可以叫做机器码。他能够由硬件直接读取,同时硬件返回的数据也是这种二进制代码。机器语言是作为直接控制硬件的桥梁,连接这软件和硬件两个不同领域的技术。它是计算机的设计者通过计算机的硬件结构赋予计算机的操作功能。机器语言执行速度是上述语言中最快的,而且无需编译直接执行。用机器语言编写程序,编程人员不仅要对所有二进制数字所指代的指令烂熟于心,而且还要手动为程序分配存储空间以及输入和输入。所以这是一个十分复杂的过程,即使编写简单程序也好耗费大量的人力。而且不论是代码还是输出,全是“0”和“1”的数字串,在后期的阅读和维护也会非常困难,所以机器语言已经慢慢的推出了主流编程语言的领域。

三、汇编语言和高级编程语言的优缺点

1.汇编语言的优缺点

汇编语言作为机器语言之上的第二代编程语言,它也有很多优点:

1)可以轻松的读取存储器状态以及硬件I/O接口情况

2)编写的代码因为少了很多编译的环节,可以能够准备的被执行

3)作为一种低级语言,可扩展性很高

缺点:

1)因为代码非常单调,特殊指令字符很少,所以造成了代码的冗长已经编写的困难

2)因为汇编仍然需要自己去调用存储器存储数据,很容易出现BUG而且调试起来也不容易

3)就算完成了一个程序,后期维护时候也需要耗费大量的时间。

4)因为机器的特殊性造成了代码兼容性差的缺陷。

2.高级编程语言的优点

因为高级编程语言很多,我们就拿C语言展开论述。C语言是一个面向过程的语言,用户根据自己的需求来调用函数或创建目标。因为明确的目标性以及理解容易,一个新手很容易去学习C语言。同时C语言因为发展的历史,拥有很多函数库,用户可以根据自身的需求在代码中加入头文件来调用这些函数来实现自己的功能,当然使用者也可以根据自己的喜好编写函数来在后续的代码中调用,关键字像if,else,return,main,end等这些简单易懂的单词也使得C语言记忆和理解起来更加容易。作为一个通用性很高的编程语言,C语言的可移植性是它出色的优点之一,你可以在任意一台电脑、一个设备上运行程序而不需要重新编译。

四、对未来编程语言的展望

通过上面的介绍,我们不难发现面向对象思想在编程设计中占有很重要的地位,同时现在编程语言的多元化也告诉我们,未来的语言发展不会是一枝独秀,也不会是单纯的语言发展,而是以完全面向对象的姿态你展现我们的现实世界。它将更容易被工程师学习和使用,人们完全可以通过简单的操作来完成复杂的编程。这就得出了未来语言发展的第一个趋势--面向对象,由计算机来提供现有的函数功能、封装结构。而工程师只需要去拿现成的函数来调用,大大提高了代码的利用率。同时简单性也成为未来追求的目标,如果一个有简单计算机知识的人只需学习一些基本的操作就能编写适合于各种情况的应用程序,这样创造和编写的成本将会大大降低。在互联网高速发展的今天,安全也将成为了代码编写中必不可少的因素,一个更安全更具有保密性的语言也是未来的需求。综上在这样一个“百花齐放百家争鸣”的编程语言环境,只有能真正给使用者带来便利的语言才会走的更远走的更好。

参考文献

[1]张t蕊,C++教学方法及学习方法的调研与分析,计算机教育第23期

[2]王文东,李竹林,尚建人,汇编语言与C语言的混合程序设计技术,计算机发展第十六卷第八期

[3]路士兵,浅谈计算机汇编语言的特点和学习方法,科技创新导报2014NO.20

汇编语言第5篇

一、变量与函数的相互调用

c语言可以调用汇编子程序和汇编语言中定义的变量。但要注意由于。编译后的目标文件自动地在函数名和变量名前加一个下划线,所以在汇编语言中调用C语言的函数和变量时,应在函数名和变量名前加一下划线。在汇编语言程序开始部分,应对调用的函数和变量用EXTERN加以说明。

二、调用者与被调用者的参数传递

这种数据传递通过堆栈完成,在执行调用时从调用程序参数表中的最后一个参数开始,即从右到左自动依次压人堆栈;将所有参数压人堆栈后,再自动将被调用程序执行结束后的返回地址(断点)压人堆栈,以使被调程序结束后能返回主调程序的正确位置而继续执行。进人汇编子程序后,为了能正确获取主调程序并存人堆栈中的数据,被调的汇编子程序先后要做如下一些工作:

l、保存sp的副本进人汇编子程序后,子程序中免不了要有压栈和出栈的操作,故sP时刻在变化。为了能用SP访问堆栈中的参数,安全办法是一进人子程序后,先为SP制副本,以后对传递参数的访问都用副本进行。一般可用BP保存SP,如:pushbPmovbP,sp

2、保留数据空间如果汇编子程序中需要一些局部数据,可以简单地减小SP的值,以便在栈空间中保留出一段存贮区,用于存放局部数据,该区域须在子程序结束后恢复。如下语句可以保留一个局部数据区:pushbPmovbP,spsubsp,spaee;设spaee=4如上语句段中,SPACE是局部数据的总字节数。在以后的应用中,由于SP是变化的,而BP是固定的,用负偏移量可以存取局部变量。上例利用BP及偏移量,将两个字的局部数据初始化为0。

3、保留寄存器值如果在被调子程序中用到sI、DI等其它寄存器,则应先把它们压人堆栈,以保留寄存器原值。例如,下例就是将SI和DI寄存器的值压栈:pushbpmoybp,SpsubSp,sPaeePush51Pushdi

4、获取传递参数BP保留了SP在参数传递完并将BP压栈后的一个副本,利用BP可以很方便地访问各参数。现假设调用了名为funcl汇编程序模块的主函数:maln(){……fund(pl,pZ,p3);……}。各参数都是2字节的整数值,返回地址retumaddress,在小模式编译方式共占用2个字节。如果要将传递的参数p卜pZ、p3取出,并分别赋给bx、Cx、dx寄存器,可由下列语句完成这一功能:movbx,[bp+4jmovcx,[bp+6]movdx,[bp+8〕

汇编语言第6篇

关键词:加密算法DES汇编语言

目前在金融界及非金融界的保密通信中,越来越多地用到了DES算法。DES(DataEncryptionStandard)即数据加密算法,是IBM公司于1977年研究成功并公开发表的。随着我国三金工程尤其是金卡工程的启动,DES算法在POS、ATM、磁卡及智能卡(IC卡)中被广泛应用,以此来实现关键数据的保密。如信用卡持卡人的PIN的加密传输、IC卡与POS间的双向认证、金融交易中的密码键盘等,均用到DES算法。由于密码键盘不可能使用高级语言,所以用汇编语言实现DES就非常实用。

1DES算法的简单原理

DES是一种分组密码。假定明文m是由0和1组成的长度为64位的符号串,密钥k也是64位的0、1符号串。

设:M=m1m2m3…m64

K=k1k2k3…k64

加密过程可表达如下:

DES(m)=IP-1·T16·T15…T2·T1·IP(m)

其中:IP(m)是初始置换,IP-1是逆置换,T16~T1是16次迭代。

(1)初始置换IP

功能是把输入的明文m按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则如下:

58,50,42,34,26,18,10,2,

60,52,44,36,28,20,12,4,

62,54,46,38,30,22,14,6,

64,56,48,40,32,24,16,8,

57,49,41,33,25,17,9,1,

59,51,43,35,27,19,11,3,

61,53,45,37,29,21,13,5,

63,55,47,39,31,23,15,7

(2)逆置换IP-1

经过16次迭代运算后,得到L16、R16,将此作为输入,进行逆置换。逆置换满足:

IP·IP-1=IP-1·IP=I

逆置换正好是初始置换的逆运算。

(3)T16~T1的迭代计算

DES的迭代算法采用模2加法。

在通信网络的两端,双方约定了一致的密钥。在通信的源点用密钥对核心数据进行加密并形成密文,然后,以密文的形式在公共通信网中传输到通信网络的终点。数据到达终点后,用同样的密钥对密文数据进行解密,便再现了明文形式的核心数据。这样,便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。

2汇编语言的实现

用汇编语言实现DES算法有它的优势也有它的难点。优势是51汇编的位操作可以方便地实现置换功能。但用汇编语言实现算法的迭代运算及循环功能比较烦琐。在用51汇编实现DES的过程中,我编写了几个子程序,组合起来可实现DES算法加密。在这里写出一些思路,有需要的同行可与我联系(E-mail:zhoubin@)。

8031有16个可以位寻址的寄存器,可放置128位的数据,利用它可实现DES的转置功能。将明文m放入寄存器27H~20H中,即位地址00H对应m64,3FH对应m1。利用标志寄存器C可实现置换与逆置换程序。在DES的16次迭代过程中,要实现公式:

Li=Ri-1;Ri=Li-1f(Ri-1,ki)

的运算过程,其关键在于f(Ri-1,ki)的功能。f是将32位的输入转化为32位的输出。其中含3项技术:

①将32位膨胀为48位的E功能。该项功能可用类似于置换功能的子程序编写。

②48位子密钥的生成。为了便于51汇编生成子密钥,可以使用主机用串口下传的方式,由主机将16个子密钥传给89C52为核心的单片机,然后存入80H~FFH中。如果密钥是固定的,则可直接将子密钥固化在89C52的Flash中。

③S盒的功能是将48位的输入再次缩为32位。具体实现是将S盒表存入89C52的Flash中,每次通过查表求得S输出的结果。

下面列举其中的几个子程序。

(1)IP置换子程序

;入口寄存器:(MSB)2726252423222120(LSB),出口寄存器:(MSB)2F2E2D2C2B2A2928(LSB)

;功能:将入口寄存器的数据按置换表换位。

IP:MOVC,06H;将m58送到进位标志中

MOV7FH,C;将进位标志送m1中

MOVC,0EH;将m50送到进位标志中

MOV7EH,C;将进位标志送m2中

;重复,按表编写MOVC,31H;将m15送到进位标志中

MOV41H,C;将进位标志送m63中

MOVC,39H;将m7送到进位标志中

MOV40H,C;将进位标志送m64中

RET

(2)逆置换子程序

;入口寄存器:(MSB)2726252423222120(LSB),出口寄存器:(MSB)2F2E2D2C2B2A2928(LSB)

;功能:将入口寄存器的数据按逆置换表换位。

IPRVS:MOVC,18H;将m40送到进位标志中

MOV7FH,C;将进位标志送m1中

MOVC,38H

.

.

.

RET

(3)异或子程序

;入口寄存器:272625243F3E3D3C,出口寄存器:2B2A2928

;功能:将寄存器27262524的内容和寄存器3F3E3D3C的内容异或。结果保存在2B2A2928寄存器中。

XORLF:MOVA,3FH;将高8位异或

XRLA,27H

MOV2BH,A;放入出口处

MOVA,3EH

XRLA,26H

MOV2AH,A

MOVA,3DH

XRLA,25H

MOV29H,A

MOVA,3CH

XRLA,24H

MOV28H,A

RET

(4)S盒子程序

;入口寄存器:(MSB)2F2E2D2C2B2A2928,出口寄存器:(MSB)27262524

;功能:48位32位

S6TO4:MOV20h,2FH;取出高位数据

LCALLS162345;调用实现Si(b1b6,b2b3b4b5)

;的功能子程序

MOVDPTR,#S1TAB;S盒表的首址

MOVA,21H;取出第几个S盒

LCALLDPTRADD

CLRA

MOVCA,@A+DPTR;求出S盒的表地址及S结果

SWAPA

MOV27H,A;保存高位结果

MOV20H,2EH

LCALLS162345

;重复

汇编语言第7篇

关键词:PIC单片机;PICC编译器;C语言;汇编语言

中图分类号:TP312文献标识码:A文章编号:1009-3044(2010)11-2640-05

Analysis Based on C Language and Assembler Language Mix Programming in PICC Compiler

LIU Jin-ping, YE Sai-feng

(Fujian Electric Vocational and Technical College, Quanzhou 362000, China)

Abstract: Articles detailed C language and assembly language mixed programming methodology and anslysis and settlement according to these problems of PIC singlechip in PICC compiler environment through 9 program and lastly presented their own views on the advantages and disadvantages of C language and assembly language mixed programming .

Key words: PICC singlechip; PICC compiler; C language; assembler language

目前,最常用PIC单片机C语言编程环境是MATLAB调试环境和HI-TECH编译器PICC。虽然还有众多支持PIC单片机的C语言编译器,但PICC因为稳定、可靠、编译生成的代码效率高,而受到青睐。用C语言来开发PIC单片机系统软件最大的好处是编写代码效率高,软件高度直观、维护升级方便、代码的重复利用率高、便于跨平台的代码移植等。因此用C语言编程,在进行系统设计和开发的工程师群体中得到广泛认可。既然C语言是一种强有力的程序设计语言,那么是不是就可以抛弃汇编语言?写单片机C程序最关键的一点是单片机内设资源非常有限,同时,要求控制的实时性高,这就要求对单片机体系结构和硬件资源有详尽的了解,而这些恰恰是汇编语言的优势,所以对于PIC爱好者,尤其初学者而言,C语言与汇编语言混编是不可避免的。实际上,C语言和汇编语言混合编程可以使单片机应用程序的开发效率和程序本身的运行效率达到最佳的配合。

1 PICC对RAM的特殊要求

下面,我们通过一个引例的不同编程来看PICC对RAM的特殊要求。

例:将RAM中的BANK0的0X20~0X2F共16个单元置为55H。

1.1 采用汇编语言编程

程序1:

INCLUDE "P16F877.INC"

MOVLW 0X20

MOVWF FSR

MOVLW 55H

ABC MOVWFINDF

INCF FSR ,F

BTFSSFSR ,4

GOTOABC

GOTO$

END

程序1经过调试,运行后能实现引例功能。

1.2 采用C语言编程

程序2:

#include"pic.h"

unsigned char i;

unsigned char *tmp;

void main()

{

tmp=0x20;

for(i=1;i

{

(*tmp)=0x55;

tmp++;

}

}

程序2中运用指针知识,经过调试没有发现错误,但运行后根本无法满足引例的要求。

修改程序2第2行为:“bank2 unsigned char i;”,即变量i改到RAM的BANK2。运行的结果是将0X56~0X64共15个单元置为55H。再次将程序2第6行修改为:“tmp=0x21;”,运行后,RAM的0X21~0X30共16个单元置为55H,离要求还有一点距离。

1.3 采用C语言绝对定位技术

程序3:

#include"pic.h"

bank2 unsigned char i;

static volatile unsigned char *tmp @ 0x30;

void main()

{

tmp=0x20;

for(i=1;i

{

(*tmp)=0x55;

tmp++;

}

}

程序3将定义的指针定位在BANK0的0X30单元开始的区域,与0X20~0X2F区域没有冲突。经过调试运行能实现引例功能。

1.4 采用C语言与汇编语言混编

程序4:

#include"pic.h"

bank2 unsigned char i;

void main()

{ #asm

MOVLW0X20

MOVWF_FSR

MOVLW0X55

MOVWF_INDF

#endasm

for(i=1;i

{ #asm

INCF _FSR,F

MOVLW0X55

MOVWF _INDF

#endasm

}

}

程序4中唯一变量i 定义在RAM的BANK2区域,程序经过调试运行能实现引例功能。要说明的是,C语言与汇编语言混编时,汇编语言部分的特殊功能寄存器名必须采用下划线引导和大写字母。

从以上不同方法的编程出现的结果,可以看出在C语言环境下,PICC对File Registers(RAM数据存储器)中的20H~7FH单元具有绝对使用权,这些单元位于BANK0的最后,即通用寄存器的96个字节。所以,在编程时若要应用这部分单元,那么,则在C语言中定义的所有变量必须放在除BANK0外的RAM中,否则运行结果不可预料。

2 PICC混编时对传递参数的要求

2.1 采用局部变量进行主函数与自定义函数之间的数据传递

PICC规定,应用局部变量传递数据,在汇编语言部分引用参数时,第2 个形参要写成?_函数名,第3个形参要写成?_函数名+1,以此类推。而第1个形参以及函数内部自定义变量必须分别命名为?a_函数名,?a_函数名+1,……,至于?a_函数名先分配给第1个形参或是第1个自定义变量则不确定。

程序5:

#include

void Test(unsigned char inVar1, unsigned char inVar2,unsigned char inVar3,unsigned char inVar4)

{

unsigned char tmp1=0;

inVar1++;

asm("incf ?a_Test+1,f");

asm("decf ?_Test,f");//inVar2--;

#asm //inVar3+=5;

movf ?_Test+1,w

addlw 0x5

movwf ?_Test+1

#endasm

#asm //inVar4-=0x5左移一位,低位补1;

bsf _STATUS,0

rlf ?_Test+2,f

#endasm

#asm //tmp1=inVar1;

movf ?a_Test+1,w

movwf ?a_Test

#endasm

}

void main()

{

unsigned char t1,t2;

t1=t2=10;

Test(t1,t2,t1,t2);

}

程序5中的自定义函数名为Test,共有inVar1~inVar4等4个形参,函数内部还有1个自定义变量tmp1。在汇编语言中inVar1写成?a_Test+1、inVar2~inVar4分别写成?_Test~?_Test+2、而tmp1写成?a_Test。需要说明的是:

1) 程序中C语言部分若不对第1个形参inVar1进行操作,则在汇编语言部分中对inVar1处理是无效的!也就是不分配内在单元给inVar1。

2) 程序中C语言部分若不对函数内部的自定义tmp1进行赋值或运算,则在汇编部分对tmp1处理是无效的,也就是不分配RAM空间。

以上两点,在进行C语言与汇编语言混编时应特别关注。

2.2 采用全局变量进行主函数与自定义函数之间的数据传递

程序6:

#include

volatile unsigned char tmp;

volatile bank1 unsigned char tmp1;

volatile bank2 unsigned char tmp2;

void Test(void)

{

#asm

clrf _STATUS

movlw 0x55

movwf _tmp

#endasm

}

void Test1(void)

{

#asm

clrf _STATUS

movlw 0x10

movwf _tmp

bcf _STATUS,6

BSF _STATUS,5

movlw 0x20

movwf _tmp1^0x80;非BANK0变量,在汇编语言中使用要如此

#endasm

}

void main()

{

while(1)

{

Test1();

if(tmp==0x10)

{

tmp=0xab;

}

if(tmp1==0x20)

{

tmp1=0xcd;

}

Test();

tmp2=tmp+tmp1;

}

}

程序6采用全局变量传递数据,共定义tmp、tmp1、tmp2三个全局变量,分别定义在RAM的BANK0、BANK1、BANK2,其中tmp、tmp1用于函数之间传递函数,在汇编语言部分要使用这两个全局变量时,只要在变量名前加下划线作为引导就可以了。但要注意的是,若这些全局变量定义在非BANK0,如程序中的tmp,则在汇编语言部分使用时,必须写成_tmp1^0x80。若是定义在BANK1,就得写成_tmp1^0x100,若是定义在BANK2,就得写成_tmp1^0x180。

程序7:

#include

volatile unsigned char inVar1,inVar2,inVar3,inVar4;

void Test()

{

unsigned char tmp1=0;

//inVar1-=1;

asm("incf _inVar1,f");

//inVar2--;

asm("decf _inVar2,f");

//inVar3+=5;

#asm

movf _inVar3,w

addlw 0x5

movwf _inVar3

#endasm

//inVar4-=0x5左移一位,低位补1;

#asm

bsf _STATUS,0

rlf _inVar4,f

#endasm

//tmp1=inVar1;

#asm

movf _inVar1,w

movwf ?a_Test

#endasm

}

void main()

{

unsigned char tmp1=2;

inVar1=inVar2=inVar3=inVar4=10;

Test();

inVar1=inVar4;inVar3=tmp1;

}

程序7除定义了全局变量,还在自定义函数中定义了一个自定义变量tmp1,同样在汇编部分要换名为?a_Test,需要说明的是,若对tmp1不赋初值,那么在汇编时会出现“找不到?a_Test”错误信息,而无法通过汇编。

使用全局变量最大的好处是寻址直观,只需在 C 语言定义的变量名前增加一个下划线,即可在汇编语句中寻址,使用全局变量进行参数传递效率比形参传递高。

3 C语言主函数内含汇编语言的情况

程序8:

#include

void main()

{

unsigned char tmp,i;

while(1)

{

tmp=1;

#asm

movf ?a_main+1,w

movwf ?a_main

#endasm

i++;

} }

程序8在主函数内定义两个变量,这两个变量在汇编语言部分使用时,必须换名为 ?a_main和 ?a_main+1,需要说明的是,第1 个自定义变量tmp,在汇编语言部分使用?a_main前,在C语言部分必须先进行赋初值或计算,否则会出现错误。

程序9:

#include

volatileunsigned char tmp,i;

void main()

{

while(1)

{

//tmp=1;

#asm

movf _i,w

movwf _tmp

#endasm

i++;

} }

程序9在主函数外定义了两个全局变量,它们在汇编语言部分使用比较简单,只要在变量前加下划线引导就可以。

4 结束语

可以看出,C语言和汇编语言混合编程在具体实施时,一定要注意许多细节问题,否则运算结果不可预料。

一般来说,在项目开发过程中,程序量较大且PICC 进行后道编译优化,采用C语言编写的代码不会比全部用汇编编写的代码差多少。所以,既然用了C语言编程,就尽量避免使用嵌入汇编指令或整个地编写汇编指令模块文件。对于非得采用C语言和汇编语言混合编程,一定要注意:1)尽量使用嵌入汇编;2)尽量使用全局变量进行参数传递。

参考文献:

[1] 李荣正.PIC单片机原理及应用[M].北京:北京航空航天大学出版社,2006.