数据传送是计算机中最基本的操作,它将源操作数送到目的操作数。这类指令共29条,指令执行后,源操作数不变,目的操作数被源操作数取代。数据传送类指令一般不影响标志寄存器的状态位,这里说的标志指C、AC和OV,不包括检验累加器奇偶性的标志P。
源操作数可采用寄存器、寄存器间接、直接、立即、变址这5种寻址方式寻址。目的操作数可以采用寄存器、寄存器间接、直接寻址这3种寻址方式寻址。
单片机的数据存储空间有片内和片外之分,访问不同空间的数据传送类指令有很多,常用到的有如下助记符。
· 片内数据存储器数据传送:MOV、XCH、XCHD、SWAP、PUSH、POP等。
· 片外数据存储器数据传送:MOVX。
· 查表指令:MOVC。
数据传送指令是应用最频繁的指令,MCS-51单片机提供了丰富的数据传送指令,它也是数量最多的一类指令。数据传送指令的助记符为MOV,其汇编语言指令格式为:
MOV [目的操作数],[源操作数];
片内RAM单元有A、Rn、@Ri、direct这4种表示形式,以此为目的操作数,结合对片内RAM可进行的立即寻址、直接寻址、寄存器寻址、寄存器间接寻址4种寻址方式,得到如下全部MOV指令。MCS-51单片机片内数据传送途径如图3-7所示。
图3-7 MCS-51单片机片内数据传送图
(1)以A为目的操作数。
MOV A,Rn ;A←Rn
MOV A,direct ;A←(direct)
MOV A,@Ri ;A←(Ri)
MOV A,#data ;A←#data
例如,已知A=30H,R0=40H,(40H)=50H,执行下面各条指令:
MOV A,R0 ;将R0中的数据取出送入A,A=40H
MOV A,40H ;将40H单元中的数据取出送入A,A=50H
MOV A,@R0 ;将R0间接寻址的40H单元的内容送入A,A=50H
(2)以Rn为目的操作数。
MOV Rn,A ;Rn←A
MOV Rn,direct ;Rn←(direct)
MOV Rn,#data ;Rn←#data
例如,已知A=2BH,R1=16H,(40H)=50H,执行下面3条指令后,R1=2BH,R2=50H,R3=55H。
MOV R1,A ;将A中数据取出送入R1
MOV R2,40H ;将40H单元中数据取出送入R2
MOV R3,#55H ;将立即数55H送入R3
(3)以直接地址为目的操作数。
MOV direct,A ;(direct) ←A
MOV direct,Rn ;(direct) ←Rn
MOV direct,direct1 ;(direct) ←(direct1)
MOV direct,@Ri ;(direct) ←(Ri)
MOV direct,#data ;(direct) ←#data
例如,已知A=30H,(30H)=40H,(40H)=5EH,执行下面4条指令后,(20H)=30H,(30H)=5EH,R0=30H,(40H)=40H。
MOV 20H,A ;将A中的数据取出送入20H单元
MOV 30H,40H ;将40H单元中的数据送入30H单元
MOV R0,A ;将A中的数据取出送入R0
MOV 40H,@R0 ;将R0间接寻址的单元中的数据送入40H单元
(4)以间接地址为目的操作数。
MOV @Ri,A ;(Ri) ←A
MOV @Ri,direct ;(Ri) ←(direct)
MOV @Ri,#data ;(Ri) ←#data
例如,设(30H)=6FH,R1=40H,执行MOV@R1,30H后,30H单元中的数据被取出送入R1间接寻址的40H单元,(40H)=6FH。
【例3-1】RAM中30H单元的内容50H,试分析执行下面程序后各有关单元的内容。
解:
MOV 60H,#30H ;立即数30H送60H单元,即(60H)=30H
MOV R0,#60H ;立即数60H送入R0,即RO=60H
MOV A,@R0 ;间接寻址,将(R0)=60H的单元内容送入A,即A=30H
MOV R1,A, ;将A中的内容送入R1,即R1=30H
MOV 40H,@R1 ;间接寻址,将(R1)=30H中的内容送入40H单元,即(40H)=50H
MOV 60H,30H ;30H单元的内容送入60H,即(60H)=50H
程序执行结果是:A=30H,R0=60H,R1=30H,60H=50H,40H=50H,30H=50H内容未变。
【例3-2】将累加器A中的内容送入外部数据存储器的60H单元。
解:根据题意编程如下。
MOV R0,#60H ;设置地址指针寄存器
MOVX @R0,A ;(R0) ←A,A中内容送外部数据存储器的60H单元
(5)以DPTR为目的操作数。
MOV DPTR,#data16 ;DPTR←#data 16
例如,执行MOV DPTR,#2000H后,DPTR=2000H。
注意:(1)应严格按照上述指令的格式使用,不能任意创造指令,否则视为非法。
(2)向同一个地址中多次传送数据,前面的数据将被覆盖,以最后一次传
送的数据为结果。
(3)以累加器A为目的寄存器的传送指令只会影响PSW中的奇偶标志位。
(4)某些指令的功能相同,但指令的机器码可能不同,执行的周期数也不
相同。如累加器A的地址为E0H,指令MOV A,#01H和MOV E0H,
#01H的功能完全相同,而它们的机器码不同,指令的长度和执行的
时间也不相同。
(6)数据交换。
字节变换指令实现内部RAM与累加器A之间的数据交换,可完成整字节或半字节数据交换。与A进行变换的内部RAM单元可寻址的方式有寄存器寻址、寄存器间接寻址、直接寻址。示意图见图3-8。
图3-8 字节交换示意图
① 字节交换。
XCH A,Rn ;A<=>Rn
XCH A,direct ;A<=>(direct)
XCH A,@Ri ;A<=>(Ri)
例如:已知A=23H,(30H)=45H,执行XCH A,30H后,A=45H,(30H)=23H。
又如,已知A=20H,R1=30H,(30H)=66H,执行XCH A,@R1后,A=66H,(30H)=20H,R1不变。
② 半字节交换。
XCHD A,@Ri ;A0~3<=>(Ri)0~3
SWAP A ;A0~3<=>A4~7
例如:已知A=45H,R1=30H,(30H)=67H,执行XCH A,@R1后,A=47H,(30H)=65H,R1不变。
又如,已知A=20H,执行SWAP A后,A=02H。
(7)堆栈操作。
所谓堆栈是在片内RAM中,按“先进后出,后进先出”原则设置的专用存储区。数据的进栈出栈由指针SP统一管理,采用以SP为间址寄存器的间接寻址方式。堆栈的操作有进栈和出栈两条专用指令,在指令中指针SP被隐含,只需指出操作数的直接地址。
PUSH direct ;SP←SP+1,(SP)←(direct)
POP direct ;(direct) ←(SP),SP←SP-1
PUSH是进栈(或称为压入操作)指令。在数据入栈之前,SP指针自动加1,然后将直接寻址单元中的数据压入到SP指针所指的单元。
POP是出栈(或称为弹出操作)指令。执行该指令时,会将SP指针所指示单元的数据弹出到直接寻址单元中,然后将SP的内容减1。
例如:设SP=10H,(40H)=50H,执行PUSH 40H指令后,SP=11H,(40H)的数据50H送入SP(=11H)单元。指令执行过程如图3-9所示。
又如:设SP=11H,(11H)=34H,执行指令POP 30H后,堆栈指针所指单元中的数据34H被弹出,送入30H单元,SP=10H。指令执行过程如图3-10所示。
图3-9 PUSH指令操作示意图 图3-10 POP指令操作示意图
【例3-3】进入中断服务程序后,SP=30H,DPTR=5544H。执行下列指令:
PUSH DPL ;将DPL压入堆栈,指令代码C082H
PUSH DPH ;将DPH压入堆栈,指令代码C083H
执行结果将把44H和55H两个8位数据分别压入片内RAM的31H和32H两个地址单元,SP的内容两次增1后将变成32H。
对外部扩展的RAM及I/O口的数据传送,必须由累加器A通过数据总线与外部RAM或I/O口之间进行。指令助记符为MOVX,使用DPTR或Ri作间接寻址寄存器,指令有如下4条:
MOVX A,@DPTR ;A←(DPTR)
MOVX @DPTR,A ;(DPTR) ←A
MOVX A,@Ri ;A←(P2Ri)
MOVX @Ri,A ;(P2Ri) ←A
上述指令中DPTR是16位地址指针,因此前两条指令的寻址范围为64KB。Ri是8位地址指针,后两条指令的寻址范围只限于外部RAM的256个单元,其高8位地址由当前P2的状态来提供。
例如:已知DPTR=1000H,片外地址为1000H的数据RAM存储器或端口中的内容为10H,执行MOVX A,@DPTR后,A=10H。
又如:已知P2=20H,R1=10H,A=45H,执行MOVX@R1,A后,片外地址为2010H数据寄存器或I/O端口的值为45H。
【例3-4】将外部数据存储器的2000H单元的内容传送到内部RAM的70H单元。
解:程序如下。
MOV DPTR,#2000H ;将外部数据指针DPTR指向2000H
MOVX A,@DPTR ;从外部将数据送到A
MOV 70H,A ;再将数据送到70H
程序存储器只能读而不能写,其中存放着监控程序和用户应用程序,由CPU完成对其程序的读取,指令不能控制。常用程序存储器存放一些常用的数据表格(例如各种代码表格、平方表、复杂算式的计算结果),在程序执行过程中对其进行表格数据查询,并将查询结果送入累加器A,这个过程称为查表。这类指令有以下两条:
MOVC A,@A+DPTR ;A←(A+DPTR)
MOVC A,@A+PC ;A←(A+PC)
例如:已知A=30H,DPTR=3000H,程序存储器单元(3030H)=50H,执行MOVC A,@A+DPTR后,A=50H。
这两条指令都是单字节指令,并且都为变址寻址方式,但其寻址范围不同。第一条指令采用DPTR为基址寄存器,查表时用来存放表格的起始地址,查表范围可达整个程序存储器的64KB空间。第二条指令以PC为基址寄存器,PC的值由该查表指令的存储地址确定,一旦指令在程序中的位置确定以后,PC中的内容也被确定,累加器A的内容是无符号的8位数0~255,查表地址为PC的当前值和累加器A中的地址偏移量相加,因此,数据表格只能安排在PC以下256个地址范围内,表格大小也受限制。
【例3-5】执行下列指令。
1232H:MOV A,#30H
1234H:MOVC A,@A+PC
1235H:MOV 60H,A
……
1265H:3FH
……
当执行查表指令时,PC的当前值为1235H,所以查表指令访问的程序存储器单元的地址为:
(A)+(PC)=30H+1235H=1265H
表3-3为数据传送指令总表,包含了指令的助记符、功能说明、字节数和振荡器周期数。
表3-3 数据传送指令总表
助 记 符 |
功能说明 |
字 节 数 |
振荡器周期 |
MOV Rn,A |
累加器内容传送到工作寄存器 |
1 |
12 |
MOV Rn,direct |
直接寻址字节传送到工作寄存器 |
2 |
24 |
MOV Rn,#data |
立即数传送到工作寄存器 |
2 |
12 |
MOV direct,A |
累加器内容传送到直接寻址字节 |
2 |
12 |
MOV direct,Rn |
工作寄存器内容传送到直接寻址字节 |
2 |
24 |
MOV direct,direct |
直接寻址字节传送到直接寻址字节 |
3 |
24 |
MOV direct,@Ri |
间接RAM传送到直接寻址字节 |
2 |
24 |
MOV direct,#data |
立即数传送到直接寻址字节 |
3 |
24 |
MOV @Ri,A |
累加器内容传送到间接寻址RAM |
1 |
12 |
MOV @Ri,direct |
直接寻址字节传送到间接寻址RAM |
2 |
24 |
MOV @Ri,#data |
立即数传送到间接寻址RAM |
2 |
12 |
MOV DPTR,#data16 |
16位立即数传送到地址寄存器 |
3 |
24 |
MOVX A,@Ri |
外部RAM(8位地址)传送到累加器 |
1 |
24 |
MOVX A,@DPTR |
外部RAM(16位地址)传送到累加器 |
1 |
24 |
MOVX @Ri,A |
累加器传送到外部RAM(8位地址) |
1 |
24 |
MOVX @DPTR,A |
累加器传送到外部RAM(16位地址) |
1 |
24 |
MOVC A,@A+DPTR |
程序存储器字节传送到累加器 |
1 |
24 |
MOVC A,@A+PC |
程序存储器字节传送到累加器 |
1 |
24 |
SWAP A |
累加器内半字节交换 |
1 |
12 |
XCHD A,@Ri |
间接寻址RAM和累加器低半字节交换 |
1 |
12 |
XCH A,Rn |
寄存器和累加器交换 |
l |
12 |
XCH A,direct |
直接寻址字节和累加器交换 |
2 |
12 |
XCH A,@Ri |
间接寻址RAM和累加器交换 |
1 |
12 |
PUSH direct |
直接寻址字节压入栈顶 |
2 |
24 |
POP direct |
栈顶弹到直接寻址字节 |
2 |
24 |