MCS-51系列单片机的数据传送类指令分为片内RAM数据传送指令、片外RAM数据传送指令、ROM数据传送指令、堆栈操作指令和数据交换指令5类。
数据传送类指令主要完成的功能是:把源地址中的内容传送到目的地址中,但不改变源地址中的内容(交换指令除外)。数据传送类指令是使用最频繁的指令,有MOV、MOVX、MOVC、XCH、XCHD、SWAP、PUSH、POP这8种。
数据传送属“复制”性质,而不是“搬家”,即该类指令执行后,源操作数不变,目的操作数被源操作数取代。数据传送类指令不影响进位标志位Cy、辅助进位标志位AC和溢出标志位OV,但不包括检验累加器奇偶性的标志位P。以累加器A为目的操作数寄存器的指令都会对PSW中的奇偶标志位P有影响。所以在数据传送指令中,除了该类指令外,其余指令执行时,均不会影响任何标志位。
1 片内RAM数据传送指令(16条)
片内RAM数据传送指令使用MOV助记符。这类指令主要用来实现在累加器A、工作寄存器Rn、直接寻址单元、间接寻址单元、立即数之间进行数据传送。MCS-51系列单片机片内数据传送途径如图3-10所示。
图3-10 片内RAM数据传送指令的传送方式
如图3-10中箭头表示数据传送方向:双箭头表示可以双向相互传送,单箭头(实线)表示只能单向传送;单箭头(虚线)表示不同的直接寻址单元可以相互传送。
特点:除第一操作数为A的指令影响P位外,其他并不影响标志位,有三种传送指令。
一般格式如下:
MOV <目的字节>,<源字节>
MOV:片内RAM和SFR之间的传送。
MOVX:片外RAM与ACC之间的传送。
MOVC:程序存储器的数据送ACC。
表3-2列出了内部RAM数据传送指令、功能操作、机器代码和执行机器周期数。此类指令的特征是操作码为MOV。
表3-2 内部RAM数据传送指令、功能操作、机器代码和执行机器周期数
例3-7:写出下列指令的机器代码和对源操作数的寻址方式,并注释其操作功能。
MOV R6,#88H;机器代码7E 88,立即寻址,将立即数88H传送到寄存器R6中
MOV @R1,48H;机器代码A748,直接寻址,将片内RAM中48H地址单元中内容传送到以寄
;存器R1中的内容为地址的存储单元中
MOV 30H,R0;机器代码8830,寄存器寻址,将寄存器R0中的内容传送到片内RAM30H地址
;单元中
MOV 50H,@R0;机器代码8650,寄存器间址寻址,以R0中的内容为地址,再将该地址中的
;内容传送到片内RAM的50H地址单元中
(1)以累加器A为目的操作数的指令
这组指令的功能是把源操作数送入累加器A中,源操作数(或源地址)有#data、direct、@Ri、Rn4种类型。为了缩短指令的字节长度,加快指令执行速度,采用寄存器寻址的指令往往将寄存器的编号隐含在机器码中。
MAIN:MOV A,#03H;A←03H
MOV A,28H;A←(28H)
MOV A,@R0;A←((R0))
MOV A,R2;A←(R2)
对于所有MOV类指令,累加器A是一个特别重要的8位寄存器,单片机CPU对它具有其他寄存器所没有的操作指令。
(2)以Rn为目的操作数的指令
这组指令的功能是把源操作数送入当前工作寄存器区的Rn中。该指令的源操作数(或源地址)只能具有3种类型。
注意:这组指令中没有MOV Rn,@Ri和MOV Rn,Rn这两种形式。
MOV R3,#00H;R3←00H
MOV R2,A;R2←(A)
(3)以直接地址为目的操作数
这组指令的功能是把源操作数送入直接地址指出的存储单元direct中。源操作数(或源地址)5种类型全部具备。
MOV SP,#5AH;SP←5AH
MOV 28H,A;28H←(A)
MOV 3BH,@Rl;3BH←((R1))
MOV 2EH,DPL;2EH←(DPL)
MOV 3AH,A;3AH←(A)
(4)以寄存器间接寻址为目的操作数
这组指令的功能是把源操作数送入以Ri的内容为地址的单元中。注意:这组指令没有MOV@Ri,Rn和MOV@Ri,@Ri这两种形式。源操作数(或源地址)只能有3种类型。
MOV @R0,A;(R0)←(A)
MOV @R0,#00H;(R0)←00H
(5)16位数据送数据指针DPTR
把高8位立即数送入DPH,低8位立即数送入DPL,地址指针DPTR由DPH和DPL组成。这是MCS-51指令系统中唯一的一条16位数据传送指令,用来设置地址指针。这条指令主要是用于配合下面将要介绍的片外RAM数据传送和ROM数据传送使用。
例3-8:
MOV 30H,#7AH;将立即数7AH送片内RAM的30H单元中
MOV R0,#30H;将立即数30H送R0寄存器
MOV A,@R0;将R0指定的30H中的数7AH送A中
MOV DPTR,#1000H;将1000H送DPTR寄存器
2 用于片外RAM传送的指令(4条)
片外数据传送指令采用的助记符为MOVX。该指令分为读片外RAM指令和写片外RAM指令两种。MOV后面加X,表示访问的是片外RAM或I/O接口,该类指令必须通过累加器A与外部RAM或I/O间相互传送数据。在单片机外接扩展的I/O接口时,往往是将相应的I/O接口映射为一个片外RAM地址。于是可以利用指令,通过对映射的片外RAM地址的读/写,实现从该I/O地址输入/输出数据。
表3-3列出了外部RAM数据传送指令、功能操作、机器代码和执行机器周期数,它们都是与片外RAM有关的数据传送指令。该类指令均涉及对片外RAM的64KB地址单元操作,而指令MOVX@Ri,A和MOVX A,@Ri中Ri只提供片外RAM地址的低8位地址,所以高8位应由P2提供。
表3-3 外部RAM数据传送指令、功能操作、机器代码和执行机器周期数
读片外RAM单元或I/O的数据的指令用@R0或@R1间接寻址,地址位长为8位,可以读片外RAM单元的地址为××00H~××FFH,低8位地址由指令给定,从P0口输出,并由地址锁存信号ALE锁存在外接地址锁存器中;高8位地址××H,由P2口的状态决定。指令用@DPTR间接寻址,地址位长为16位,可以读片外RAM单元整个64KB的空间,地址范围为0000H~FFFFH。高8位地址DPH由P2口输出,低8位地址DPL由P0口输出,但P0口和P2口输出的访问地址都由指令指定。
这两种指令是让单片机读取和写入外部RAM或I/O的数据,此时对应引脚P3.7(RD)、P3.6(WR)有效。值得注意的是,无论是读还是写片外RAM,都要通过累加器A来完成。因此,在两个片外RAM单元中传送数据时,必须通过A进行中转。
例3-9:(1)外部RAM低256B单元与A之间的传送;(2)64KB外部RAM单元与A之间的传送。
MOV R0,#80H
MOVX A,@R0;将外部RAM的80H单元内容→A,
;将片外RAM的2000H单元中的内容传送到3000H单元
MOV DPTR,#2000H;设指针
MOVX A,@DPTR;取(2000H)的数
MOV DPTR,#3000H;修改指针
MOVX @DPTR,A;存到(3000H)单元
例3-10:将立即数18H传送到外部RAM中的0100H单元中去。接着从片外RAM中的0100H单元取出数再送到外部RAM中的0280H单元中。
ORG 0000H;伪指令,指出下一指令首地址为0000H
MOV A,#18H;将立即数18H传送到累加器A中
MOV DPTR,#0100H;将立即数片外RAM的地址0100H送到DPTR中
MOVX @DPTR,A;将A中内容18H送到片外RAM地址0100H中
MOVX A,@DPTR;将片外RAM的0100H单元中内容18H送到累加器A中
MOV R0,#80H;将立即数80H送到寄存器R0中,作为片外RAM地址低8位
MOV P2,#02;将片外RAM地址高8位置2,由P2给出地址的高8位
MOVX @R0,A;将A中内容18H送到片外RAM的0280H单元地址中
SJMP $(www.xing528.com)
END;伪指令,表示程序结束
3 用于ROM传送的指令(2条)
由于MCS-51系列单片机规定ROM专门用于存放程序和常数,由编程器(俗称烧写器)写入,单片机正常工作时,只能从ROM中读出数据,而不能向ROM写入数据,传送为单向,因此,MCS-51系列单片机仅有两条从程序存储器ROM中读出数据到累加器A的指令。表3-4为ROM数据传送指令、功能操作、机器代码和执行机器周期数。ROM数据传送指令(程序存储器访问指令)的助记符为MOVC。两条指令均属变址寻址指令,涉及ROM的寻地址空间均为64KB。程序存储器中的常数被称为表格常数,它们在程序中多用于查数据表,故该两条指令也被称为查表指令。一般地,A中内容称为变址,DPTR、PC中内容称为基地址。
表3-4 ROM数据传送指令、功能操作、机器代码和执行机器周期数
(1)以DPTR的内容为基地址
MOVC A,@A+DPTR指令是以DPTR的内容为基地址的读ROM指令,该指令首先将DPTR中的数据(16位无符号数)与A中的数据(无符号数)进行相加,获得基址与变址之和,将和作为地址(16位的程序存储器ROM地址),再将该地址指定的程序存储器单元中的内容传送到累加器A中。低8位相加产生进位时,直接加到高位,并不影响标志。指令执行后,DPTR的内容不变,累加器A内容变为从ROM读出的内容。因此常数表格的大小和位置可以在64KB程序存储器中任意安排,一个表格可以为各个程序块公用。
(2)以PC的内容为基地址
MOVC A,@A+PC指令以PC作为基址寄存器,以PC的内容为基地址的读ROM指令的机器码是83H,它是单字节指令。取出该指令后,指令首先将PC值修正到指向该指令的下一条指令地址,即PC中的内容自动加1,加1后的这个PC值(称为PC当前值)与A中的地址偏移量相加,得到一个新的16位的程序存储器ROM地址,然后,将该地址单元的内容传送到累加器A。指令执行后,PC中的内容不变,累加器A的内容变为从ROM读出的内容。
因为PC的值是一个字值,指向下一条指令的首地址,而A的值最大为256字节,则常数表格只能存放在该条查表指令后面的256个字节单元之内,表格的大小受到限制,而且表格只能被一段程序所利用。
例3-11:将程序存储器2010H单元中的数据传送到累加器A中。设程序的起始地址为2000H。
方法1:在访问前,必须保证A+DPTR等于访问地址,如该例中2010H,一般方法是访问地址低8位值(10H)赋给A,剩下的16位地址(2010H-10H)=2000H赋给DPTR。该编程与指令所在的地址无关。
ORG 2000H
MOV DPTR,#2000H
MOV A,#10H
MOVC A,@A+DPTR
方法2:因为程序的起始地址为2000H,第一条指令为双字节指令,第二条指令为单字节指令,则第二条指令的地址为2002H,第二条指令的下一条指令的首地址就应为2003H,即PC=2003H,因为A+PC=2010H,故A=0DH。该编程与指令所在地址有关。由此例可见,此方法不利于修改程序,不建议使用。
ORG 2000H
MOV A,#0DH
MOVC A,@A+PC
用DPTR查表时,表格可以放在ROM的64KB范围,用PC指令时则必须把表格放在该条指令下面开始的255个字节的空间中。
MOV A,@R0;取显示缓冲区中的数
MOV DPTR,#SEGTAB;指向字形码表首
MOVC A,@A+DPTR;查表、找字形码
SEGTAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH
DB 07H,7FH,6FH
其中,#SEGTAB是字形码表的起始地址,该程序的功能是利用读ROM指令进行查表。
例3-12:在ROM的1000H开始存有5个字节数,编程将第二个字节数取出送片内RAM的30H单元中。
程序段如下:
MOV DPTR,#1000H;设指针
MOV A,#01H;序号
MOVC A,@A+DPTR;取1001H单元的数
MOV 30H,A;存到片内
ORG 1000H;伪指令,定义数表起始地址
TAB:DB 55H,67H,9AH;在ROM 1000H开始的空间中定义5单字节
DB 09H,10H
例3-13:设某数N已存于20H单元(N≤10),查表求N的二次方值,存入21H单元。
程序段如下:
MOV A,20H;取数N
ADD A,#03;加查表偏移量
MOVC A,@A+PC;查表
NOP
MOV 21H,A
TAB:DB 00H,01H,04H,09;定义数表
由于PC为程序计数器,总是指向下一条指令的地址。在执行第三条指令MOVC A,@A+PC时,在查表前应在A累加器中加上查表偏移量。
4 堆栈操作指令(2条)
堆栈是在片内RAM区中按“先进后出,后进先出”原则设置的专用存储区,是在内RAM开辟的一个数据的暂存空间,堆栈的一端固定,称为栈底;另一端是活动的,称为栈顶,栈顶的地址由堆栈指针SP指示。堆栈的操作只有进栈和出栈两种,进栈操作地址增加,出栈操作地址减少。堆栈的操作主要用于子程序、中断服务程序中的现场保护和现场恢复。
堆栈操作指令、功能操作、机器代码和执行机器周期数见表3-5。
表3-5 堆栈操作指令、功能操作、机器代码和执行机器周期数
(1)堆栈指令使用的寻址方式是直接寻址
1)片内RAM低端128B的单元:用这些单元的字节地址表示,其中的工作寄存器区的单元也用字节地址表示,不能使用寄存器名,以区别于寄存器寻址。例如,当使用第0组工作寄存器时,R0的di-rect地址应写为00H。
2)片内RAM高端128B中的特殊功能寄存器SFR:通常直接用SFR的符号表示(但累加器ACC此时不能简写为A,否则为寄存器寻址),也可以用它们的字节地址表示。
(2)系统复位时,SP的初值为07H
可见系统默认的堆栈区,将占用工作寄存器区第1组工作寄存器以上的RAM单元,如果编写程序时,需要将这部分单元作为工作寄存器使用,就必须在系统初始化时对SP重新设置,以便将堆栈移至其他地方。
堆栈操作指令对堆栈指针SP而言是寄存器间接寻址指令,对direct而言是直接寻址,所以编写程序时应注意direct所表示的是直接地址。例如,在Keil软件中认定A、R1为寄存器,ACC、01H为直接地址。所以,指令PUSH ACC、PUSH 01H、POP 01H和POP ACC均为正确指令书写格式;而PUSH A、PUSH R1、POP R1和POP A均为错误书写格式。
MOV SP,#5AH;栈底移至5AH
CLOCK:PUSH PSW;保护现场
PUSH ACC
DONE1:POP ACC;恢复现场
POP PSW
利用堆栈指令来完成40H与50H单元内容的交换的示例如图3-11所示。
图3-11 堆栈指令完成单元内容的交换
MOV SP,#6FH;将堆栈设在70H以上RAM空间
PUSH 40H;①将40H单元的23H入栈,之后(SP)=70H
PUSH 50H;②将50H单元的45H入栈,之后(SP)=71H
POP 40H;③将SP指向的71H单元的内容弹到40H单元,之后(SP)=70H
POP 50H;④将SP指向的70H单元的内容弹到50H单元,之后(SP)=6FH
5 数据交换指令(5条)
1)字节交换:3条指令功能是将累加器A的内容和源操作数交换,即将A中的内容与3种寻址方式指定的片内RAM单元中的内容进行相互交换。
例如,若(R0)=30H,(30H)=45H,(A)=67H。执行指令XCH A,@R0后,(A)=45H,(30H)=67H,(R0)不变。
2)半字节交换:功能是累加器A的低4位与@R0或@R1指定的内部RAM低4位交换。各自的高半字节不变。
例如,假设(R0)=30H,(30H)=45H,(A)=67H。执行指令XCHD A,@R0后,(A)=65H,(30H)=47H。(A)和(30H)的高半字节不变。
3)累加器内交换:功能是将累加器内高低半字节交换,即累加器A内的高4位与低4位交换。
例如,假设(A)=67H。执行指令SWAP A后,(A)=76H,即(A)7~4与(A)3~0进行了互换。
数据交换操作指令、功能操作、机器代码和执行机器周期数,如表3-6所示。
表3-6 数据交换操作指令、功能操作、机器代码和执行机器周期数
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。