单片机原理及应用技术
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第3章MCS-51单片机指令系统及程序设计

3.1 指令系统简介

指令是使计算机内部执行的一种操作,提供给用户编程时使用的一种命令,由构成计算机的电子器件特性所决定,计算机只能识别二进制代码。以二进制代码来描述指令功能的语言,称之为机器语言。由于机器语言不便被人们识别、记忆、理解和使用,因此给每条机器语言指令赋予助记符号来表示,这就形成了汇编语言。也就是说,汇编语言是便于人们识别、记忆、理解和使用的一种指令形式,它和机器语言指令一一对应,也是由计算机的硬件特性所决定的。计算机能够执行的全部操作所对应的指令集合,称为这种计算机的指令系统。

MCS-51系列单片机的指令系统具有两种形式:机器语言形式和汇编语言形式。单片机指令系统及实际中主要采用汇编语言形式,采用汇编语言编写的程序称为源程序。汇编语言程序不能被单片机直接识别并执行,必须经过一个中间环节把它翻译成机器语言程序,这个中间过程叫做汇编。

MCS-51单片机共有111条指令,从功能上可划分成数据传送、算术操作、逻辑操作、程序转移、位操作5大类,其中单字节指令49条,双字节指令45条,只有17条三字节指令。在一个机器周期内(12个系统时钟振荡周期)执行完的指令有64条,两个机器周期内执行完的指令有45条,只有乘法和除法两条指令占用4个机器周期。以系统时钟12MHz为例,机器周期为1μs,那么,大多数常用指令执行时间是1μs,平均不到2μs。MCS-51单片机指令系统具有占用存储空间少,且执行速度快的双重优点,有很强的实时处理能力,特别适合于现场控制的场合。

3.1.1 指令格式

指令系统中的指令描述了不同的操作,不同操作对应不同的指令。但结构上,每条指令通常由操作码和操作数两部分组成。操作码表示计算机执行该指令将进行何种操作,操作数表示参加操作的数本身或操作数所在的地址。MCS-51单片机的指令有无操作数、单操作数、双操作数三种情况。汇编语言指令有如下的格式。

            [标号:]操作码助记符[操作数][;注释]

其中,[]中的内容都不是必需的。

标号是语句地址的标志符号,必须以字母开始,后接1~8个字母、数字或下横线符号“_”,并以冒号“:”结尾,用户定义的标号不能和汇编保留符号(包括指令操作码助记符以及寄存器名等)重复。标号的值是它后面的操作码的存储地址,具有唯一性,因此标号不能多处重复定义。程序中定义过的标号名可在指令中作为操作数使用。标号的使用方便了子程序的调用、转移指令的转入及调试的查找和修改。下面给出一些常见的错误标号和正确标号,以加深理解。

操作码是由2~5个英文字母所组成的功能助记符,用来反映指令的功能,它是每条汇编指令中必需的部分。

操作数表示参与操作的数据所在的地址,取决于指令的寻址方式。它可以是具体的数、标号、寄存器和直接地址等。指令的操作数可以有3个、2个、1个或没有,操作码与操作数之间必须以空格分隔,操作数与操作数之间必须以逗号分开。

注释表示用户对该条指令功能的解释或说明,它是为了方便阅读程序而做的一种标注。注释以“;”开始,注释部分不影响指令的执行。

3.1.2 指令的分类

汇编语言指令是以助记符表示的指令,每一条指令就是汇编语言的一条语句。按照指令的功能,可以把MCS-51的111条指令分为5类。

● 数据传送类指令,共29条。

● 算术运算类指令,共24条。

● 逻辑运算及移位类指令,共24条。

● 控制转移类指令,共17条。

● 布尔变量操作类指令,共17条。

为了便于后面的学习,在这里先对描述指令的一些符号的约定意义做以下说明。

① Ri和Rn:表示当前工作寄存器区中的工作寄存器,i取0或1,表示R0或R1;n取0~7,表示R0~R7。

② #data:表示包含在指令中的8位立即数。

③ #data16:表示包含在指令中的16位立即数。

④ rel:以补码形式表示的8位相对偏移量,范围为-128~+127,主要用在相对寻址的指令中。

⑤ addr16和addr11:分别表示16位直接地址和11位直接地址。

⑥ direct:表示可直接寻址的地址。

⑦ bit:表示可位寻址的直接位地址。

⑧“/”和“→”:“/”表示对该位操作数取反,但不影响该位的原值;“→”表示操作流程,将箭尾一方的内容送入箭头所指的另一方单元中去。

⑨ @:间接寄存器寻址或基址寄存器的前缀。

⑩ DPTR:数据指针。

A:累加器A。

B:累加器B,用于乘法和除法指令中。

C:进位标志位。

3.1.3 伪指令

伪指令仅仅在机器汇编时供汇编程序识别和执行,用来对汇编过程进行控制和操作。汇编时,伪指令并不产生供机器直接执行的机器码,也不会直接影响存储器中代码和数据的分布。

不同的MCS-51汇编程序对伪指令的规定有所不同,但基本的用法是相似的,下面介绍一些常用的伪指令及其基本用法。

1.定位伪指令

格式:ORG M

M一般为十进制数或十六进制数表示的16位地址。M指出在该伪指令后的指令的汇编地址,即生成的机器指令起始存储器的地址。在一个汇编语言源程序中允许使用多条定位伪指令,但其值应和前面生成的机器指令存放地址不重叠。

【例3-1】

                    ORG    0000H
            START: SJMP   MAIN
                      ︙
                    ORG    0030H
            MAIN: MOV    SP,#30H

以START开始的程序汇编位机器码后从0000H存储单元开始连续存放,不能超过0030H存储单元,以MAIN开始的程序机器码则从0030H存储单元开始连续存放。

2.汇编结束伪指令

格式:END

结束汇编伪指令END必须放在汇编语言源程序的末尾。机器汇编时遇到END就认为源程序已经结束,对END后面的指令都不再汇编。因此,一个源程序只能有一个END指令。

3.定义字节伪指令

格式:DB x 1,x 2,…,xn

定义字节伪指令DB(Define Byte)将其右边的数据依次存放到以左边标号为始址的存储单元中,xi为8位二进制数,可以采用二进制、十进制、十六进制和ASCII码等多种表示形式。DB通常用于定义一个常数表。

【例3-2】

                      ORG  7F00H
            TAB:    DB   01110010B,16H,45,′8′,′A′

汇编后存储单元内容为

           (7F00H)=72H     (7F01H)=16H     (7F02H)=2DH
           (7F03H)=38H     (7F04H)=40H

4.定义字伪指令

格式:DW y 1,y 2,…,yn

定义字伪指令DW(Define Word)功能与DB相似,但DW定义的是一个字(2个字节),主要用于定义16位地址表(高8位在前,低8位在后)。

【例3-3】

                    ORG  6000H
            TAB:  DW   1254H,32H,161

汇编后存储单元内容为

           (6000H)=12H     (6001H)=54H     (6002H)=00H
           (6003H)=32H     (6004H)=00H     (6005H)=0A1H

5.定义空间位指令

格式:DS表达式

定义空间伪指令DS从指定的地址开始,保留若干字节内存空间作为备用。汇编后,将根据表达式的值来决定从指定地址开始留出多少个字节空间,表达式也可以是一个指定的数值。

【例3-4】

            ORG  0F00H
            DS    10H
            DB   20H,40H

汇编后,从0F00H开始,保留16个字节的内存单元,然后从0F10H开始,按照下一条DB伪指令给内存单元赋值,得(0F10H)=20H,(0F11H)=40H。保留的空间将由程序的其他部分决定其用处。

DB、DW、DS伪指令都只对程序存储器起作用,不能用来对数据存储器的内容进行赋值或进行其他初始化的工作。

6.等值伪指令

格式:字符名称EQU数据或汇编符

等值伪指令EQU(equate)将其右边的数据或汇编符赋给左边的字符名称。字符名称必须先赋值后使用,通常将等值语句放在源程序的开头。“字符名称”被赋值后,在程序中就可以作为一个8位或16位的数据或地址来使用。编写源程序时,经常把一些常用的数据或地址赋值给有意义的“字符名称”,然后,在程序中可以将这些数据或地址用该“字符名称”来代替,便于程序的修改和维护,使程序的可读性大为提高。

7.数据地址赋值伪指令

格式:字符名称DATA表达式

数据地址赋值伪指令DATA将其右边“表达式”的值赋给左边的“字符名称”。表达式可以是一个8位或16位的数据或地址,也可以是包含定义“字符名称”在内的表达式,但不可以是一个汇编符号(如R0~R7)。

DATA伪指令定义的“字符名称”没有先定义后使用的限制,可以用在源程序的开头或末尾。

8.位地址赋值伪指令

格式:字符名称BIT位地址

位地址赋值伪指令BIT将其右边的位地址赋给左边的字符名称。

【例3-5】

            A1         BIT  ACC.1
            USER      BIT  PSW.5

这样就把位地址ACC.1赋给了变量A1,把位地址PSW.5赋给了变量USER,在编程中A1和USER就可以作为地址使用了。