第3章单片机指令系统与汇编语言程序设计本章主要介绍单片机指令系统和汇编语言程序设计。通过本章的学习,应掌握MCS?51单片机指令系统的功能、格式、寻址方式和特点,无须每一条指令都死记硬背。指令是程序的*小单元,只有经常进行编程的实践才能使用好指令,才能掌握编程的技巧和程序设计的方法。掌握了子程序调用、查表程序、循环程序等基本的汇编程序设计,将为后面学习C51和单片机的应用程序设计打下基础。
3.1指令系统概述单片机的指令系统就是指单片机能够执行的全部操作所对应的指令的集合,它是表征单片机特性的重要标志。每种不同的单片机均有其自己的指令系统,但同系列单片机的指令系统功能相同。单片机指令越丰富、寻址方式越多,则其功能就越强。本节将详细叙述MCS?51单片机指令系统的功能、含义、特点及其应用。
3.1.1指令格式
MCS?51单片机完成某种操作的命令就是指令,它是构成程序的基本单位。单片机能直接识别和执行的指令是用二进制编码的指令,称为机器指令,不便记忆、阅读和理解。用户为了编写程序方便,往往采用具有一定含义的符号(助记符)来表示指令,称为符号指令,它与机器指令一一对应。无论是机器指令还是符号指令,均由操作码和操作数(或操作数地址)两部分组成。如:在指令“ADDA,#84H”中,ADD为操作码,累加器A和立即数#84H为操作数,它对应的机器指令编码为:00100100(操作码)和10000100(操作数)。通常,单片机的汇编语言指令的表示格式依次为标号、操作码、操作数和注释4个部分。[标号:]操作码
[操作数] [;注释]其中,操作码是指令中**不可缺少的部分,而方括号中的内容是否必要则取决于具体指令和实际应用的需要。
1.标号标号是程序员根据编程需要给指令设定的符号地址,相当于指令操作码在存储器中的物理地址,在实际操作中可有可无。标号由1~8个字符组成,**个字符必须是英文字母,而不能是数字或其他符号,并且不允许与保留的符号(如指令中的助记符)重名。标号后必须用冒号。在程序中,标号不可以重复使用。完整程序的**条指令一般要设置标号,便于程序调用。当一条指令作为其他转移指令的目的指令时,也应为其设置标号。另外,作为检索用的表格首地址也需要为其设置标号。
2.操作码操作码规定了指令的具体操作功能,是指令*重要的组成部分。为便于编程,操作码用指令功能的英文缩写表示,称为助记符。例如,MOV表示数据传送指令,MOV也就是助记符。
3.操作数实际的指令格式中有无操作数、有几个操作数视具体的情况而异,通常有如下4种情况。(1)无操作数指令:NOP(空操作)、RET(子程序返回)和RETI(中断返回)3条指令没有操作数。(2)单操作数指令:指令只有一个操作数,如指令INC
A(累加器数据增1)和CLRA(对累加器清零)。(3)双操作数指令:多数双操作数指令有源操作数和目的操作数两个操作数,书写时目的操作数写在前面,源操作数紧跟在其后,如指令MOV
A,R0(将寄存器R0中的数据传送到累加器A)。(4)三操作数指令:如CJNE
A,#20H,LOOP(比较转移指令)中有三个操作数。注意:有多个操作数时,操作数和操作数之间必须用逗号分隔开。
4.注释注释其实是指令功能的解释说明。编程时程序代码应为主要指令加上注释,以便于程序的阅读、理解和维护。注释必须以“;”(分号)和指令分开。编程时要严格按照指令格式的顺序书写,各部分之间还要加上规定的分隔符。例如,标号以冒号结束,表示指令操作码的助记符与操作数之间用空格分开,操作数与操作数之间用逗号分隔,注释前用分号作引导。
3.1.2指令符号规定为便于后面对指令功能进行介绍,指令系统中定义了一些用于表示寄存器、存储单元、数据和地址等信息的符号。在符号指令及其注释中常用的符号和含义约定如表3?1所示。表3?1常用符号及其含义常
用 符 号含义 A累加器ACC B寄存器B,主要用于乘除指令,也可作为通用寄存器使用
C进位标志位CY,在位操作中作为位运算的累加器,也称为布尔累加器 Rn(n=0~7)当前选中的工作寄存器组中的寄存器(R0~R7)之一
Ri(i=0~1)当前选中的工作寄存器组中的寄存器R0或R1 @间接寻址方式中,作为间接寻址寄存器的前缀 $当前指令地址
#data8位立即数 #data1616位立即数 Direct8位直接地址,表示片内低128
B的RAM单元地址(00H~7FH)及SFR地址(80H~FFH) addr1111位的目的地址 addr1616位的目的地址 续表常
用 符 号含义 Rel补码形式表示的8位相对偏移地址,其值在-128~+127之间
Bit片内RAM或特殊功能寄存器SFR中某一可寻址位的位地址
/位操作数的取反操作的前缀符号(x)表示x地址所对应的单元或寄存器中的内容((x))表示以x单元或寄存器内容为地址的间接寻址单元的内容
←将箭头右边的内容送入箭头左边的单元中
3.1.3指令的字节数在指令的二进制形式中,不同指令的操作码和操作数也不相同,MCS?51单片机的机器语言指令根据其指令编码长短的不同,可分为单字节指令、双字节指令和三字节指令3种格式。
1.单字节指令单字节指令码只有一个字节,由8位二进制数组成,这类指令共有49条,其操作码中包含了操作数的信息。单字节指令码可以分为两种形式:一种是无操作数单字节指令,另一种是含有操作数寄存器编号的单字节指令。
1)无操作数单字节指令这类指令的指令码的8位全表示操作码,没有专门指示操作数的字段,操作数是隐含在操作码中的。例如,空操作指令NOP,其机器码为0000
0000。
2)含有操作数寄存器编号的单字节指令这类指令的指令码的8位编码中既包含操作码字段,也包含专门用来指示操作数所在寄存器编号的字段。例如,8位数传送指令:
MOV A,Rn;A←Rn
这条指令的功能是把寄存器Rn(n=0,1,2,3,4,5,6,7)中的内容传送到累加器A中去。其机器码为:11101(操作码)Rn(寄存器编号)。假设n=0,则寄存器编码为Rn=000,则指令“MOVA,R0”的机器码是E8H。其中,操作11101表示执行将寄存器中的数据传送到A中的操作。
2.双字节指令双字节指令的指令码含有2B的机器符,可以分别存放在两个存储单元中,操作码字节在前,操作数字节在后,这类指令共有45条,其中,操作数字节可以是立即数(指令码中的数),也可以是操作数所在的片内RAM地址。例如:
MOVA,#DATA;A←data
这条指令的功能是将立即数DATA送到累加器A中去。假设立即数DATA=85H,则其机器码表示如下。**字节为操作码:0111
0100。第二字节为操作数(立即数85H):0111 0100。
3.三字节指令(17条)三字节指令的指令码的**个字节为操作码,第二和第三个字节为操作数或操作数地址,这类指令共有17条。例如:
MOVdirect,#data
这条指令是将立即数data传送到地址为direct的单元中。假设(direct)=78H,data=80H,则“MOV78H,#80H”指令的机器码表示如下。**字节为操作码:0111
0100。第二字节为**操作数(目的地址):0111 1000。第三字节为第二操作数(立即数80H):1000
0000。用二进制编码表示的机器语言指令由于不便于阅读、理解和记忆,因此在单片机控制系统中采用汇编语言(用助记符和专门的语言规则表示指令的功能和特征)指令来编写程序。一条汇编语言指令*多包含四个区段,具体形式如下所示。[标号:]操作码助记符
[目的操作数][,源操作数] [;注释]例如,把立即数F0H传送至累加器的指令如下。 START:MOV
A,#0F0H;立即数F0H→A
标号区段由用户定义的符号组成,必须用英文大写字母开始,并且标号区段可以省略。若一条指令中有标号区段,标号代表该指令的**字节所存放的存储器单元的地址,故标号又称为符号地址。在进行汇编时,把该地址赋值给标号。操作码区段表示指令要操作的数据信息。根据指令的不同功能,实现不同的操作。如数据传送、算术运算、逻辑运算、程序转移、调用子程序等。操作数表示参加操作的操作数本身或操作数所在的地址。不同类型的指令,操作数也不相同。操作数通常有单操作数、双操作数、三操作数和无操作数四种情况。如果有两个以上的操作数,则操作数之间,要以逗号隔开。在操作数的表示中,有以下几种情况需要注意。(1)十六进制数、二进制数和十进制数形式的操作数表示。在大多数情况下,操作数或操作数地址采用十六进制数的形式表示,只有在某些特殊场合才采用二进制数或十进制数的表示形式。
●若操作数采用十六进制数形式,则需加后缀“H”; ●若操作数采用二进制数形式,则需加后缀“B”;
●若操作数采用十进制数形式,则需加后缀“D”,也可省略。若十六进制数的操作数以字符A~F中的某个开头,则需在其前面加一个0,以便在汇编时把它和字符A~F区别开来。(2)工作寄存器和特殊功能寄存器的表示。当操作数在某个工作寄存器或特殊功能寄存器中时,操作数字段允许采用工作寄存器和特殊功能寄存器的代号来表示,也可用其地址来表示。注释区段也可省略,对程序功能无影响。注释区段只是用于对指令或程序段作简要的说明,以便以后查阅,调试程序时也会带来诸多方便。通常,指令字节数越少,其执行速度就越快,所占用的存储单元也越少。因此,在程序设计中应尽可能优先选用指令字节数少的指令。