特权同学

51手记之指令篇

0
阅读(1532) 评论(0)

分类指令

在介绍各条分类指令之前,将指令 中的操作数及注释中的符号说明如下。

Rn:当前指定的工作寄存器组中的Ro-R7(其中n=0,1,2,…,7)。

Ri:当前指定的工作寄存器组中的RO,R1(其中i=0,1)。

(Ri):Ri间址 寻址指定的地址单元。

((Ri)):Ri间址 寻址指定地址单元中的内容。

dir:8位直接 字节地址(在片内RAM和SFR存储空间中)。

#data8:8位立即 数。

#datal6:16位立 即数。

addrl6:16位地 址值。

addrll:11位地 址值。

bit:位地址(在 位地址空间中)。

rel:相对偏移量(一 字节补码数)。

下面介绍各条分类指令的主要功能 和操作,详细的指令操作说明及机器码形式可见附录。

一、数据传送与交换类指令

共有28条指令,包括以A,Rn,DPTR,直接地址单元,间接地址单元为目的的操 作数的指令;访问外部RAM的指令;读程序存储器的指令;数据交换指令以及准栈操作指令。

1.  以A为目的的操作数

MOV     A,Rn   ; A="Rn"

MOV     A,dir  ; A=(dir)

MOV     A,@Ri  ; A=((Ri))

MOV     A,#data; A="#data"

2.  以Rn为目的的操作数

MOV     Rn,A   ; Rn="A"

MOV     Rn,dir; Rn=(dir)

MOV     Rn,#data   ; Rn="#data"

3.  以DPTR为目的的操作数

MOV     DPTR,#data16  ;DPTR=#data16

4.  以直接地址为目的的操作数

MOV     dir,A      ; dir="A"

MOV     dir,Rn     ; dir="Rn"

MOV     dir,dir’  ; dir=(dir’)

MOV     A,@Ri      ; dir=((Ri))

MOV     A,#data    ; dir="#data"

5.  以间接地址为目的的操作数

MOV     @Ri,A      ; (Ri)=A

MOV     @Ri,dir    ; (Ri)=dir

MOV     @Ri,#data  ; (Ri)=#data

6.  访问外部数据RAM

MOVX    A,@DPTR    ;A=((DPTR))

MOVX    A,@Ri      ;A=((P2 Ri))

MOVX    @DPTR,A    ;(DPTR)=A

MOVX    Ri,A       ;(P2 Ri)=A

例1:DPTR=2000H,外部RAM(2000H)=18H, 指令MOVX A,@DPTR执行后,A=18H。

例2:P2=10H,R1=50H,A=64H,指令MOVX @R1,A执行后,外部RAM(1050H)=64H。

7.  读程序存储器

MOVC    A,@A+DPTR     ;A=((A+DPTR))

MOVC    A,@A+PC       ;A=((A+PC))

8.堆栈操作

PUSH dir   ;SP十1-6P,(dir)一(SP)

POP dir    ;((SP))一dir,SP-1--P ,

例1:SP=07H,(35H)=55H,指令PUSH 35H执行后,55H送入08H地址单元,SP=08H。

例2:SP=13H,(13H)= 1FH,指令POP 25H执行后,1FH压入25H地址单元,SP此时为12H。

 

二、算术运算类指令

共有24条指令,主要包括加、减、乘、除、增量、减量和十进制调整等指令。其中,大多数指令都同时以A为源操作数之一和目的操作数。

1.     加指令

ADD    A,Rn   ; A+Rn=A

ADD    A,dir  ; A+(dir)=A

ADD    A,@Ri  ; A+((Ri))=A

ADD    A,#data; A+#data=A

2.     带进位加

ADDC   A,Rn   ; A+Rn+C=A

ADDC   A,dir  ; A+(dir)+C=A

ADDC   A,@Ri  ; A+((Ri))+C=A

ADDC   A,#data; A+#data+C=A

3.     带借位减

SUBB   A,Rn   ; A-Rn-C=A

SUBB   A,dir  ; A-(dir)-C=A

SUBB   A,@Ri  ; A-((Ri))-C=A

SUBB   A,#data; A-#data-C=A

说明:借位位来自程序状态字PSW中的进位位C,只是在作减法运算时,被用作借位 位。

例:A=38H,R1=20H,(20H)=23H,C=1 指令SUBB A,@R1执 行后,A=14H。

4.乘法指令

MUL AB     ;A×B = BA

说明:本指令实现8位无符号乘法。A,B中各放一个8位乘数,指令执行后,16位积的高位在B中,低位在A中。

例A=50H,B=40H, 指令MUL AB执行后,A=00H,B=32H

5.除法指令

DIV AB     ;A÷B的商在A中,余数在B中

说明:本指令实现8位无符号除法。A放被除数,B放除数,指令执行后,A中为商,B中为 余数。若除数B=00H,则指令执行后,溢出标志OV=1,且A,B内 容不变。

例1:A=28H,B=12H,指令DIV AB执行后,A=02H,B=04H。

例2:A=08H,B=09H,指令DIV AB执行后,A=00H,B=08H。

6.增量

INC    A

INC    Rn

INC    dir

INC    @Ri

INC    DPTR

7.减量

DEC    A

DEC    Rn

DEC    dir

DEC    @Ri

DEC    DPTR

8. 十进制调整

DA  A   ;把A中按二进制相加后的结果调整成按BCD数相加的结果

综合例1:把在R4和R5中 的两字节数取补(高位在R4中)

CLR    C

MOV    A,R5

CPL    A

INC    A

MOV    R5,A

MOV    A,R4

CPL    A

ADDC   A,#00H

MOV    R4,A

SJMP   $

综合例2:把R7中的无符号数扩大10D倍(设原数小于25D)

MOV    A,R7

MOV    B,#0AH

MUL    AB

MOV    R7,A

SJMP   $

综合例3:把R1R0和R3R2中 的2个4位跃D数相加,结果送入R5R4中,如有进位则存于进位位C中。

CLR    C

MOV    A,R0

ADD    A,R2

DA     A

MOV    R4,A

MOV    A,R1

ADDC   A,R3

DA     A

MOV    R5,A

SJMP   $

在MCS-51系列单片机的算术运算类指令中,乘除法指令是许多8位 微处理器和一些8位单片机所没有的,执行时间为4个 机器周期。这种指令对编制比较复杂的运算程序,例如,比例-积分-微分(PID)运算、浮点运算、多字节数乘除运算等是 经常要用到的。

 

三、逻辑运算与循环类指令

共有24条指令。逻辑运算指令主要包括逻辑"与"、"或"、"异或"、求反和清零;循环指令则都是对A的大循环操作,包括有左、右方向以及带与不带进位位的不同循环方式。

1.  与操作

ANL     A,Rn

ANL     A,dir

ANL     A,@Ri

ANL     A,#data

执行该指令后相与的记过保存在A中

ANL     dir,A

ANL     dir,#data

2.  或操作

ORL     A,Rn

ORL     A,dir

ORL     A,@Ri

ORL     A,#data

执行该指令后相与的记过保存在A中

ORL     dir,A

ORL     dir,#data

 

例A=16H,指令RR A执行后,A=0BH。

综合例:把R2R3中的16位 补码数(高位在R2中)右移一位,并不改变符号。

MOV    A,R2

MOV    C,ACC.7 ;把符号位存入进位位C

RRC    A

MOV    R2,A

MOV    A,R3

RRC    A

MOV    R3 , A

SJMP   $

 

四、子程序调用与转移类指令

共有14条指令。子程序调用类有绝对调用和长调用两种;转移类分为无条件转移和条件转移两组。无条件转移包括绝对转 移、长转移、短转移和间接转移;条件转移包括结果为零、结果为非零、减一后结果为非零以及两数不相等的转移条件,它们全部采用相对转移的方式。

绝对于程序调用和绝对转移指令的 机器码形式比较特殊,操作码不是在前面而是在中间,并且调用和转移的范围都只在2K地址范围内,这 在使用时应予以注意。

1.     绝对调用

ACALL addrll ;addrll一PC0-10,PC11-16不变

说明:

①调用范围:本指令在2K地址范围内的子程序调用。本指令实现的操作将不改变原PC的 高5位(PC1l-15),仅把11位地址addrll送入PC的低11位(PC0-10), 以此确定子程序的入口地址。由于整个64K程序存储器空间被分成32个基本2K地址范围(见表2.1), 编程时,必须保证紧接AC从L指令后面的那 一条指令的第一字节与被调用于程序的入口地址在同一2K范围内,否则将不能使用ACALL指令实现这种调用。

②机器码形式:本指令为二字节指 令。设子程序入口地址addrll的各位是a10a9a8a7a6a5a4a3a2a1a。,则ACALL指 令的二进制机器码为a10a9a810001a7a6a5a4a3a2a1a0,其中10001为ACALL指令的操作码。

例:子程序调用指令ACALL在程序存储器中的首地址为0100H,子程序 入口地址为0250H。试确定能否使用ACALL指 令实现调用?如果能使用,确定该指令的机器码。

解:因为ACALL指令的首地址在0100H,而ACALL是2字节指令,所以下一条指令的首地址在0102H。由表2.1可见,0102H和0250H在同一2K地址范围内,故可用ACALL调用。调用入口地址为0250H的ACALL指令的机器码形式为:0101000101010000B=5150H

2. 长调用

LCALL addrl6 ;addrl6一PCo-l5

说明:本指令为64K程序存储器空间中的全范围子程序调用指令,子程序入口地址可在64K地 址空间中的任一处。本指令为3字节指令。

3.无条件转移指令

(1)绝对转移

AJMP addrll ;addrll一PC0-10

说明:①转移范围:本指令为2K地址范围内的转移指令。对转移目的地址的要求与ACALL指 令中对于程序入口地址的要求相同。

②机器码形式:本指令为2字节指令。设addrll的各位是a10a9a8a7a6a5a4a3a2a1a0,则指令AJMP addrll的二进制机器码为al0a9a800001a7a6a5a4a3a2ala0。

例:绝对转移指令AJMP在程序存储器中的首地址为2500H,要求转移 到2250H地址处执行程序,试确定能否使用AJMP指 令实现转移?如能实现,其指令的机器码形式是什么?

解:因为AJMP指令的首址为2500H,其下一条指令的首址为2502H,由表2.1可见,2502H与转移目的地址2250H在同一2K地址范围内,故可用AJMP指令实现程序的转移。指令的机器码:0100000l01010000B=4150H

(2)长转移

LJMP addrl6 ;addrl6一PC0-15

说明:本指令为64K程序存储器空间的全范围转移指令。转移地址可为16位 地址值中的任一值。本指令为3字节指令。

(3)短转移

SJMP rel ;PC十2十rel-PC

说明:本指令为一页地址范围内的 相对转移指令。因为rel为l字节补码(偏移量),且SJMP rel 指令为2字节指令,所以转移范围为一126D到十129D。

(4)间接转移

JMP @A十DPTR ;A十DPTR-PC

例1:A=02H,DPTR=2000H,指令JMP @A十DPTR执 行后,PC=2002H。也就是说,程序转 移到2002H地址单元去执行。

例2:现有一段程序:

MOV    DPTR ,#TABLE

JMP    @A十DPTR

TABLE:AJMP   RoUT0

AJMP   RoUTl

AJMP   RoUT2

: :

AJMP ROUTn

根据JMP @A十DPTR指 令的操作可知,当A=00H时,程序转入到 地址ROUT0处执行;当A=02H时,转到ROUTl处执行……。可见这是一段多路 转移程序,进入的路数由A确定。因为AJMP指 令是2字节指令,所以要求A必定为偶数。

4.条件转移指令

(1)累加器为零(非 零)转移

JZ rel ;A=0则转移(PC十2十rel一PC),A≠0程序顺序执行

JNZ rel ;A≠0 则转移(PC+2+rel-PC),A=0程序顺序执行

(2)减一非零转移

DJNZ Rn,rel ;Rn一1-Rn,Rn≠0,则转移(PC十2十re- PC),Rn=0,程序顺序执行

DJNZ dir,rel ;(dir)一l-dir,(dir)≠0则转移(PC十3十rel-PC),(dir)=0,程序顺序执行

说明:UNZ Rn,rel是2字节指令,而DJNZ dir,rel是3字节指令,所以在满足转移的条件后,前者是PC十2十rel一PC,而后者是PC十3十rel一PC。

例:试说明下列一段程序运行后A中的结果。

MOV 23H,#0AH

CLR    A

LOOP:  ADD    A,23H

       DJNZ   23H,LOOP

    SJMP   $

    根据程序可知,运算结果A=10+9+8+7+6+5+4+3+2+1=55D=37H

    (2)两数不等转移

    CJNE   A,dir,rel

    CJNE   A,#data,rel

    CJNE   Rn,#data,rel

    CJNE   @Ri,#data,rel

说明:1CJNE指令都是3字 节指令。

2若第一操作数大于或等于第二操作数,则影响标志C=0(如指令CJNE A,dir,rel中A>=(dir)等);若第一操作数小于第二操 作数,则C=l(如指令CJNE A,dir,rel中A<(d5r)等)。利用对C的判断,可使这几条指令实现两操作数相等 与否的判断,还可完成两数大小的比较。

例1:R7=56H, 指令CJNE R7,#34H,$十08H执行后,程序转移到放本条CJNE指令的首地址($)加08H后 的地址单元去执行。

例2:安排程序,要求读Pl端口上的信息,若不为55H则程序停着等待,只有到P1端口为55H时,程序往下顺序执行。

程序为:   MOV    A,#55H

CJNE   A,P1,$'

5.相对偏移量rel的 求法

在短转移和条件转移中,用偏移量rel和转移指令所处的地址值来计算转移的目的地址。rel是1字节补码值,如rel是正数的补码,程序往前转移; 如rel是负数的补码,程序往回转移。下面介绍计算rel大 小的方法。

设本条转移指令的首地址为ad--源地址,字节数为Bn-2字节或3字节,要转移到的地址为ad--目的地址,这三者之间 的关系为:

ad=as十Bn十rel补

于是reI=(Ad-As一8n)补

这就是在已知源地址,目的地址和 指令的长度时,计算rel大小的公式。

由于程序中的时、分、秒数是已经 作过十进制调正后的BCD数,因此#60H,#60H,#24H虽以十六进制数出现,但却表示BCD数。

在于程序调用与转移指令中,由于 绝对转移和绝对调用指令AJMP和ACALL指 令字节少,转移范围大,因而是常用的指令。但使用时应注意其机器码形式及允许使用的条件。相对转移类指令因本身长度有2字节和3字节之分,这会影响到偏移量大小的计算,因而 也要十分注意。此外,条件转移指令中,由于没有结果为正和结果为负等转移条件的指令,因而这些转移的要求,只能由CJNE指 令加上对进位位的判断来实现。

 

五、 位操作类指令

共有17条指令。其共同特点是对进位位C和 直接位地址Nt的操作。其中包括清零、置1、 求反、逻辑与、逻辑或、传送以及判断转移。MCS-51单片机中这些丰富的位操作指令表现出其具有 优异的布尔处理能力

1.  清位

CLR     C   ;C=0

CLR     bit ;bit=0

2.  置位

SETB    C   ;C=1

SETB    bit ;bit=1

3.  位求反

CPL     C   ;C取反

CPL     bit ;bit取反

4.  位与

ANL     C,bit  ;C = bit and C

5.  位或

ORL     C,bit  ;C = C or bit

6.  位传送

MOV     C,bit  ;C = bit

MOV     bit,C  ;bit = C

7.  位转移

JC  rel    ;C=1,则转移PC=PC+2+rel,否则程序顺序执行

JNCrel    ;C=0,则转移PC=PC+2+rel,否则程序顺序执行

JB  bit,rel    ;(bit)=1,则转移PC=PC+3+rel,否则程序顺序执行

JNBbit,rel    ;(bit)=0,则转移PC=PC+3+rel,否则程序顺序执行

JBCbit,rel    ;(bit)=1,则转移PC=PC+3+rel,且该位清零,否则程 序顺序执行

 

六、CPU控制类 指令

   共有3条指 令,包括返回指令和空操作指令。

    RET        ;从调用子程序返回,与LCALL或ACALL指令配合使用

    RETI       ;从中断服务程序中返回

    NOP        ;空操作