单片机中级教程 第3章 指令系统.docx
《单片机中级教程 第3章 指令系统.docx》由会员分享,可在线阅读,更多相关《单片机中级教程 第3章 指令系统.docx(48页珍藏版)》请在冰豆网上搜索。
单片机中级教程第3章指令系统
第3章MCS-51系列单片机的指令系统
学习和使用单片机的一个最重要的环节就是理解和熟练掌握它的指令系统。
不同种类的机型指令系统是不同的,本章将详细介绍MCS-51系列单片机指令系统的寻址方式、各类指令的格式及功能。
3.1指令系统概述
指令是规定计算机进行某种操作的命令。
一台计算机所能执行的指令集合称为该计算机的指令系统。
计算机的主要功能是由指令系统来体现的。
指令系统与机器密切相关,指令系统是由计算机生产厂商定义的,不同系列的机器其指令系统是不同的。
3.1.1指令概述
计算机内部只识别二进制数。
因此,能被计算机直接识别、执行的指令是使用二进制编码表示的指令,这种指令被称为机器语言指令。
机器语言具有难学、难记、不易书写、难于阅读和调试、容易出错而且不易查找错误,程序可维护性差等缺点。
为方便人们的记忆和使用,制造厂家对指令系统的每一条指令都给出了助记符,助记符是用英文缩写来描述指令的功能,它不但便于记忆,也便于理解和分类。
以助记符表示的指令就是计算机的汇编语言指令,汇编语言指令与机器语言指令具有一一对应的关系。
与通常的计算机一样,MCS-51系列单片机也只能识别二进制编码表示的机器语言。
同样,为了人们记忆和使用方便,也采用汇编语言指令来描述它的指令系统。
MCS-51系列单片机指令系统共有111条指令,按功能划分,可分为五大类:
1)数据传送类指令(29条);
2)算术运算类指令(24条);
3)逻辑运算及移位类指令(24条);
4)控制转移类指令(17条);
5)位操作类指令(17)。
3.1.2指令格式
一条完整的MCS-51系列单片机汇编语言的指令格式如下:
[标号:
]〈操作码〉[操作数][;注释]
标号——标号是该指令的起始地址,是一种符号地址。
标号可以由1~8个字符组成,第一个字符必须是字母,其余字符可以是字母、数字或其他特定符号。
标号后跟分界符“:
”。
操作码——即指令的助记符。
它规定了指令所能完成的操作功能。
操作数——指出了指令的操作对象。
操作数可以是一个具体的数据,也可以是存放数据的单元地址,还可以是符号常量或符号地址等。
在一条指令中可能有多个操作数,操作数与操作数之间用逗号“,”分隔。
注释——为了方便阅读而添加的解释说明性的文字,用“;”开头。
操作码与操作数之间必须用空格分隔,带方括号项称为可选项。
由指令格式可见,操作码是指令的核心,不可缺少。
在MCS-51系列单片机指令系统中,指令的字长有单字节、双字节、三字节三种,在程序存储器中分别占用1~3个单元。
3.1.3指令中常用符号说明
在描述MCS-51系列单片机指令系统的功能时,经常使用的符号及意义如下:
Rn——当前选中的工作寄存器组中的寄存器R0~R7之一,所以n=0~7。
Ri——当前选中的工作寄存器组中可作地址指针的寄存器R0、R1,所以i=0、1。
#data——8位立即数。
#data16——16位立即数。
direct——内部RAM的8位地址。
即可以是内部RAM的低128个单元地址,也可以是特殊功能寄存器的单元地址或符号。
因此在指令中direct表示直接寻址方式。
addr11——11位目的地址,只限于在ACALL和AJMP指令中使用。
addr16——16位目的地址,只限于在LCALL和LJMP指令中使用。
rel——补码形式表示的8位地址偏移量,在相对转移指令中使用。
bit——片内RAM位寻址区或可位寻址的特殊功能寄存器的位地址;
@——间接寻址方式中间址寄存器的前缀标志;
C——进位标志位,它是布尔处理机的累加器,也称之为位累加器;
/——加在位地址的前面,表示对该位先求反再参与操作,但不影响该位的值;
(x)——由x指定的寄存器或地址单元中的内容;
((x))——由x寄存器的内容作为地址的存储单元的内容;
$——本条指令的起始地址;
←——指令操作流程,将箭头右边的内容送到箭头左边的单元中。
3.2寻址方式
在指令系统中,操作数是一个重要的组成部分,它指出了参加运算的数或数所在的单元地址。
而如何找到这个操作数就称为寻址方式。
寻址方式越多,则计算机的功能越强,灵活性亦越大,但指令系统也就越复杂。
寻址方式是汇编语言程序设计中最基本的内容之一,必须十分熟悉,牢固掌握。
在上一章中,我们已介绍过MCS-51系列单片机系统的存储器分布,在学习寻址方式时,要特别注意在各种不同的存储区中,分别可以采用什么寻址方式。
MCS-51系列单片机提供了七种寻址方式,下面分别介绍。
3.2.1立即寻址
所谓立即寻址就是操作数在指令中直接给出。
通常把出现在指令中的操作数称为立即数。
为了与直接寻址指令中的直接地址相区别,在立即数前面加“#”标志。
例如:
MOVA,#3AH
其中3AH就是立即数,该指令功能是将3AH这个数本身送入累加器A中。
3.2.2直接寻址
在指令中直接给出操作数地址,这就是直接寻址方式。
此时,指令的操作数部分就是操作数的地址。
例如:
MOVA,3AH
其中3AH就是表示直接地址,其操作示意图如图3-1所示,该指令功能是把内部RAM地址为3AH单元中的内容68H传送给累加器A。
直接寻址方式可访问以下存储空间:
①内部RAM低128个字节单元。
在指令中直接地址以单元地址的形式给出。
②特殊功能寄存器。
对于特殊功能寄存器,其直接地址还可以用特殊功能寄存器的符号名称来表示。
应注意,直接寻址是访问特殊功能寄存器的唯一方法。
图3-1直接寻址示意图图3-2寄存器间接寻址示意图
3.2.3寄存器寻址
寄存器寻址就是以寄存器的内容作为操作数。
因此在指令的操作数位置上指定了寄存器就能得到操作数。
采用寄存器寻址方式的指令都是一字节的指令,指令中以符号名称来表示寄存器。
例如:
MOVA,R0
MOVR2,A
以上两条指令都是属于寄存器寻址。
前一条指令是将R0寄存器的内容传送到累加器A。
后一条是把累加器A中的内容传送到R2寄存器中。
由于寄存器在CPU内部,所以采用寄存器寻址可以获得较高的运算速度。
能实现这种寻址方式的寄存器有:
R0~R7、A、AB寄存器对和数据指针DPTR
3.2.4寄存器间接寻址
所谓寄存器间接寻址就是以寄存器中的内容作为RAM地址,该地址中的内容才是操作数。
寄存器间接寻址也需在指令中指定某个寄存器,也是以符号名称来表示寄存器的,为了区别寄存器寻址和寄存器间接寻址,用寄存器名称前加“@”标志,来表示寄存器间接寻址。
例如:
MOVA,@R0
其操作示意图如图3-2所示。
这时R0寄存器的内容3AH是操作数地址,内部RAM的3AH单元的内容65H才是操作数,并把该操作数传送到累加器A,结果A=65H。
若是寄存器寻址指令:
MOVA,R0
则执行结果A=3AH。
对这两类指令的差别和用法,一定要区分清楚。
间接寻址理解起来较为复杂,但在编程时是极为有用的一种寻址方式。
MCS-51系列单片机规定只能用寄存器R0、R1、DPTR作为间接寻址的寄存器。
间接寻址可以访问的存储空间为内部RAM和外部RAM。
①内部RAM的低128个单元采用R0、R1作为间址寄存器
②外部RAM的寄存器间接寻址有两种形式:
一是采用R0、R1作为间址寄存器,可寻址256个单元。
二是采用16位的DPTR作为间址寄存器,可寻址外部RAM的整个64KB地址空间。
对于52子系列的单片机,其内部RAM是256个字节,其高128个字节与特殊功能寄存器的地址是重叠的,二者由不同的寻址方式加以区分。
对52子系列的高128字节RAM,必须采用寄存器间接寻址方式访问。
3.2.5变址寻址
变址寻址是以DPTR或PC作为基址寄存器,以累加器A作为变址寄存器(存放地址偏移量),并以二者内容相加形成的16位地址作为操作数地址。
例如:
MOVCA,@A+DPTR;A←((A)+(DPTR))
MOVCA,@A+PC;A←((A)+(PC))
第一条指令的功能是将A的内容与DPTR的内容相加形成操作数的地址(即程序存储器的16位地址),把该地址中的内容送入累加器A中,如图3-3所示。
第二条指令的功能是将A的内容与PC的内容相加形成操作数的地址(ROM16位地址),把该地址中的内容送入累加器A中。
这两条指令常用于访问程序存储器中的数据表格。
且都为一字节指令。
图3-3变址寻址示意图
3.2.6相对寻址
相对寻址只在相对转移指令中使用,指令中给出的操作数是相对地址偏移量rel。
相对寻址就是将程序计数器PC的当前值与指令中给出的偏移量rel相加,其结果作为转移地址送入PC中。
此种寻址方式的操作是修改PC的值,故可用来实现程序的分支转移。
PC当前值是指正在执行指令的下条指令的地址。
rel是一个带符号的8位二进制数,取值范围是-128~+127,故rel给出了相对于PC当前值的跳转范围。
例如:
SJMP54H
这是无条件相对转移指令,是双字节指令,指令代码为80H、54H,其中80H是该指令的操作码,54H是偏移量。
现假设此指令所在地址为2000H,执行此指令时,PC当前值为2000H+02H,则转移地址为:
2000H+02H+54H=2056H
故指令执行后,PC的值变为2056H,程序的执行发生了转移。
其寻址方式如图3-4所示。
3.2.7位寻址
MCS-51系列单片机有位处理功能,可对寻址的位单独进行操作,相应的在指令系统中有一类位操作指令,它们可以采用位寻址方式。
在指令的操作数位置上直接给出位地址,这种寻址方式被称为位寻址。
例如:
MOVC,30H
该指令的功能是把位地址30H中的值(0或1)传送到位累加器CY中。
图3-4相对寻址示意图
8051单片机内部RAM有两个区域可以位寻址:
一个是位寻址区20H~2FH单元的128位,另一个是字节地址能被8整除的特殊功能寄存器的相应位。
在MCS-51系列单片机中,位地址的表示可以采用以下几种方式:
(1)直接使用位地址。
对于20H~2FH共16个单元的128位,其位地址是00H~7FH,例如,20H单元的0~7位的位地址为00H~7H。
而特殊功能寄存器的可寻址的位地址见第2章表2-3
(2)用单元地址加位序号表示。
如25H.5表示25H单元的D5位(位地址是2DH),而PSW中的D3可表示为D0H.3。
这种表示方法可以避免查表或计算,比较方便。
(3)用位名称表示。
特殊功能寄存器中的可寻址位均有位名称,可以用位名称来表示该位。
如可用RS0表示PSW中的D3——D0H.3
(4)对特殊功能寄存器可直接用寄存器符号加位序号表示。
如PSW中的D3,又可表示为PSW.3。
习惯上,对于特殊功能寄存器的寻址位常使用位名称表示其位地址。
3.3数据传送类指令
数据传送类指令是最常用、最基本的一类指令。
数据传送类指令的一般功能是把源操作数传送到目的操作数,指令执行后,源操作数不变,目的操作数被源操作数所代替。
主要用于数据的传送、保存以及交换数据等场合。
在MCS-51系列单片机的指令系统中,各类数据传送指令共有29条,分述如下。
3.3.1内部RAM数据传送指令
内部RAM的数据传送类指令共16条,包括累加器、寄存器、特殊功能寄存器、RAM单元之间的相互数据传送。
1.以累加器A为目的操作数的数据传送指令
MOVA,#data;A←data
MOVA,direct;A←(direct)
MOVA,Rn;A←(Rn)
MOVA,@Ri;A←((Ri))
这组指令的功能是将源操作数所指定的内容送入累加器A中。
源操作数可以采用立即寻址、直接寻址、寄存器寻址、寄存器间接寻址4种寻址方式。
上述指令在上节均有例题和图示。
不再重复。
2.以寄存器Rn为目的操作数的数据传送指令
MOVRn,A;Rn←(A)
MOVRn,#data;Rn←data
MOVRn,direct;Rn←(direct)
这组指令的功能是将源操作数所指定的内容送到当前工作寄存器组R0~R7中的某个寄存器中。
源操作数可以采用寄存器寻址、立即寻址和直接寻址。
注意,没有“MOVRn,Rn”指令,也没有“MOVRn,@Ri”指令。
例3-1(A)=50H,(R1)=10H,(R2)=20H,(R3)=30H,(30H)=4FH,执行指令:
MOVR1,A;R1←(A)
MOVR2,30H;R2←(30H)
MOVR3,#85H;R3←85H
执行后,(R1)=50H,(R2)=4FH,(R3)=85H。
3.以直接地址为目的操作数的数据传送指令
MOVdirect,A;direct←(A)
MOVdirect,#data;direct←data
MOVdirect1,direct2;direct1←(direct2)
MOVdirect,Rn;direct←(Rn)
MOVdirect,@Ri;direct←((Ri))
这组指令的功能是将源操作数所指定的内容送入由直接地址direct所指定的片内存储单元。
源操作数可以采用寄存器寻址、立即寻址、直接寻址和寄存器间接寻址。
例3-2已知:
(R0)=60H,(60H)=72H,现执行如下指令:
MOV40H,@R0;(40H)←(60H)
该指令执行过程如图3-5所示。
执行结果为:
(40H)=72H
注意,“MOVdirect1,direct2”指令在译成机器码时,源地址在前,目的地址在后。
图3-5MOV40H,@R0执行示意图
4.以间接地址@Ri为目的操作数的数据传送指令
MOV@Ri,A;(Ri)←(A)
MOV@Ri,#data;(Ri)←data
MOV@Ri,direct;(Ri)←(direct)
这组指令的功能是把源操作数所指定的内容送入以R0或R1为地址指针的片内RAM单元中。
源操作数可以采用寄存器寻址、立即寻址和直接寻址3种方式。
注意,没有“MOV@Ri,Rn”指令。
例3-3已知:
(R1)=30H,(A)=20H,执行指令
MOV@R1,A;(30H)←(A)
执行指令结果为:
(30H)=20H。
5.以DPTR为目的操作数的数据传送指令
MOVDPTR,#data16;DPTR←data16
这是MCS-51系列单片机指令系统唯一的一条16位立即数传送指令,其功能是将外部存储器(RAM或ROM)某单元地址作为立即数送到DPTR中,立即数的高8位送DPH,低8位送DPL。
注意,该指令在译成机器码时,16位立即数其高8位在前,低8位在后。
在使用上述指令时,需注意以下几点:
(1)要区分各种寻址方式的含义,正确传送数据。
例3-4:
若(R0)=30H,(30H)=50H时,注意以下指令的执行结果;
MOVA,R0;(A)=30H
MOVA,@R0;(A)=(30H)=50H
MOVA,30H;(A)=(30H)=50H
MOVA,#30H;(A)=30H
(2)所有传送指令都不影响标志位。
这里所说的标志位是指CY、AC、和OV。
涉及到累加器A的将影响奇偶标志位P。
(3)估算指令的字节数:
凡是指令中既不包含直接地址、又不包含8位立即数的指令均为一字节指令;若指令中包含一个直接地址或8位立即数,指令字节数要增加1,若包含两个这样的操作数,则指令字节数要增加2。
如:
MOVA,@R0;一字节
MOVA,direct;二字节
MOVdirect,#data;三字节
MOVDPTR,#data16;三字节
3.3.2访问外部RAM的数据传送指令
CPU与外部RAM或I/O口进行数据传送,必须采用寄存器间接寻址的方法,并通过累加器A来传送。
这类指令共有四条:
MOVXA,@DPTR;A←((DPTR))
MOVX@DPTR,A;(DPTR)←A
MOVXA,@Ri;A←((Ri))
MOVX@Ri,A;(Ri)←A
前两条指令是以DPTR作为间址寄存器,其功能是将DPTR所指定的外部RAM单元与累加器A之间传送数据。
由于DPTR是16位地址指针,因此这两条指令的寻址范围可达片外RAM64KB全部空间。
后两条指令是以R0或R1作为间址寄存器,其功能是将R0或R1所指定的外部RAM单元与累加器A之间传送数据。
由于R0或R1是8位地址指针,因此这两条指令的寻址范围仅限于外部RAM256个字节单元。
例3-5试编程,将片外RAM的2000H单元内容送入片外RAM的0200H单元中;
解:
片外RAM与片外RAM之间不能直接传送,需通过累加器A,另外,当片外RAM地址值大于FFH时,需用DPTR作为间址寄存器。
编程如下:
MOVDPTR,#2000H;源数据地址送DPTR
MOVXA,@DPTR;从外部RAM中取数送A
MOVDPTR,#0200H;目的地址送DPTR
MOVX@DPTR,A;A中内容送外部RAM
3.3.3程序存储器向累加器A传送数据指令
MOVCA,@A+DPTR;A←((A)+(DPTR))
MOVCA,@A+PC;A←((A)+(PC))
这两条指令的功能是从程序存储器中读取源操作数送入累加器A中。
源操作数均为变址寻址方式。
这两条指令都是一字节指令。
这两条指令特别适合于查阅在ROM中建立的数据表格。
故称作查表指令。
虽然这两条指令的功能完全相同,但在具体使用中却有一点差异。
前一条指令是采用DPTR作为基址寄存器,在使用前,可以很方便的把一个16位地址(表格首地址)送入DPTR,实现在整个64KBROM空间向累加器A的数据传送。
即数据表格可以存放在64KB程序存储器的任意位置,因此,第一条指令称为远程查表指令。
远程查表指令使用起来比较方便。
后一条指令是以PC作为基址寄存器。
在程序中,执行该查表指令时PC值是确定的,为下一条指令的地址,而不是表格首地址,这样基址和实际要读取的数据表格首地址就不一致,使得A+PC与实际要访问的单元地址不一致,为此,在使用该查表指令之前,必须用一条加法指令进行地址调整,地址调整只能通过对累加器A的内容进行调整,使得A+PC和所读ROM单元地址保持一致。
例3-6若在外部ROM中2000H单元存放(0~9)的平方值0,1,,4,9……,81,要求根据累加器A中的值(0~9),来查找所对应的平方值,并存入60H单元中。
解:
①用DPTR作基址寄存器:
MOVDPTR,#2000H;表格首地址送DPTR
MOVCA,@A+DPTR;根据表格首地址及A确定地址,取数送A。
MOV60H,A;存结果
这时,(A)+(DPTR)之和就是所查平方值所存的地址。
②用PC作为基址寄存器:
在MOVC指令之前应先用一条加法指令进行地址调整,编程如下:
(2字节)ADDA,#data;(A)+data作地址调整
(1字节)MOVCA,@A+PC;(A)+data+(PC)确定查表地址,取数送A。
(2字节)MOV60H,A;存结果
(1字节)RET
2000H:
DB0,1,4,9,16,25,36,…,81
执行该查表指令时,PC已指向下一条指令地址,很显然,PC的内容不是要查找的表格首地址2000H,二者之间存在地址差,因此需进行地址调整,使其能指向表格首地址,由于PC的内容不能随意改变,所以只能借助于A来进行调整。
故在MOVC指令之前,先执行对A的加法操作,其中#data的值要根据MOVC指令后的地址和数据表格首地址之间的地址差确定,也就是由MOVC下边的指令与数据表格首地址之间,其他指令所占的字节数之和来确定。
本例中,data=03H。
还应注意,累加器A中的内容为8位无符号数,该查表指令只能查找指令所在地址以后256字节范围内的数据,即表格只能放在该指令所在地址之后的256个字节范围内,故称之为近程查表指令。
3.3.4数据交换指令
数据交换指令共有五条,可完成累加器和内部RAM单元之间的字节或半字节交换。
1.整字节交换指令
整字节交换指令有三条,完成累加器A与内部RAM单元内容的整字节交换。
XCHA,Rn;(A)←→(Rn)
XCHA,direct;(A)←→(direct)
XCHA,@Ri;(A)←→((Ri))
2.半字节交换指令
XCHDA,@Ri;(A)3~0←→((Ri))3~0
该指令功能是将A的低4位和Ri间接寻址单元的低4位交换,而各自的高4位内容都保持不变。
3.累加器高低半字节交换指令
SWAPA;(A)7~4←→(A)3~0
由于十六进制数或BCD码都是以四位二进制数表示,因此SWAP指令主要用于实现十六进制数或BCD码的数位交换。
例3-7试编程,将外部RAM1000H单元中的数据与内部RAM6AH单元中的数据相互交换。
解:
数据交换指令只能完成累加器A和内部RAM单元之间的数据交换,要完成外部RAM与内部RAM之间的数据交换,需先把外部RAM中的数据取到A中,交换后再送回到外部RAM中。
编程如下。
MOVDPTR,#1000H;外部RAM地址送DPTR
MOVXA,@DPTR;从外部RAM中取数送A
XCHA,6AH;A与6AH地址中的内容进行交换
MOVX@DPTR,A;交换结果送外部RAM
3.3.5堆栈操作指令
堆栈操作指令可以实现对数据或断点地址的保护,它只有两条指令:
PUSHdirect;SP←(SP)+1,(SP)←(direct)
POPdirect;direct←((SP)),SP←(SP)-1
前一条指令是进栈指令,其功能是先将栈指针SP的内容加1,使它指向栈顶空单元,然后将直接地址direct单元的内容送入栈顶空单元。
后一条指令是出栈指令,其功能是将SP所指的单元的内容送入直接地址所指出的单元,然后将栈指针SP的内容减1,使之指向新的栈顶单元。
注意,进栈、出栈指令只能以直接寻址方式来取得操作数,不能用累加器或工作寄存器Rn作为操作数。
例如把累加器A的内容送入堆栈,应使用指令:
PUSHACC
这里ACC表示累加器A的直接地址EOH。
利用堆栈操作指令也可以完成数据的传送。
3.4算术运算类指令
MCS-51系列单片机的算术运算类指令共有24条,可以完成加、减、乘、除等各种操作,全部指令都是8位数运算指令。
如果需要作16位数的运算则需编写相应的程序来实现。
算术运算类指令大多数要影响到程序状态字寄存器PSW中的溢出标志OV、进位(借位)标志CY、辅助进位标志AC和奇偶标志位P。
利用进位(借位)标志CY,可进行多字节无符号整数的加、减运算,利用溢出标志可对带符号数进行补码运算,辅助进位标志则用于BCD码运算的调整。
3.4.1加法指令
ADDA,#data;A←(A)+data
ADDA,direct;A←(A)+(direct)
ADDA,Rn;A←(A)+(Rn)
ADDA,@Ri;A←(A)+((Ri))
这组指令的功能