51的指令系统

51单片机共有111条指令。可以大致分为以下五类:
(1)数据传送类(29条)

(2)算术操作类(24条)

(3)逻辑运算类(25条)

(4)控制转移类(17条)

(5)位操作类(17条)

可用的指令是固定的、每种指令对应一个物理电路的实际运行过程,如果指令是指令集中不存在的,电路内部无法实现,指令就会出错。

数据传送类指令

一般形式为 MOV <目的操作数> , <源操作数>

操作码包括MOV、MOVC、MOVX、PUSH、POP、XCH、XCHD、SWAP。

(1)首先是MOV。MOV是数据传送中使用的最多的一条操作码。MOV指令用于内部RAM之间数据的传送。具体内容见下表:

指令作用
MOV A,Rn工作寄存器的内容送A,n取0-7
MOV A,direct将内部RAM中地址为direct的单元的内容送A
MOV A,@Ri利用R0和R1实现间接寻址,i只能取0或1
MOV A,#data立即数寻址,将立即数data送到累加器A中
MOV Rn,A将累加器A的内容送给工作寄存器
MOV Rn,direct直接寻址,内容送工作寄存器
MOV Rn,#data立即数寻址,将data送给工作寄存器,目的地址为Rn时无间接寻址
MOV direct,AA送地址为direct的RAM单元
MOV direct,RnRn送RAM
MOV direct,dir2RAM送RAM
MOV direct,@Ri寄存器间接寻址送RAM
MOV direct,#data立即数送RAM
MOV @Ri,AA送间接寻址地址
MOV @Ri,directRAM内容送工作寄存器间接寻址地址
MOV @Ri,data立即数送寄存器间接寻址地址
MOV DPTR,#data1616位立即数送DPTR

需要注意的是,间接寻址只针对工作寄存器R0和R1,其他寄存器无法完成该工作。此外,direct所指代的可以是16进制的编码地址,也可以是由助记符所表示的内部RAM地址,比如DPH、DPL、SP、P0、P1等等。在实际使用的时候,我们一般不会使用16进制字符作为direct,因为这样写的程序可读性差,这些地址被称为magic number。

(2)MOVC指令用于程序存储器与累加器A的内容传输,多用于查表。MOVC用法十分固定,只有下面两条指令。MOVC在使用时是访问内部程序存储器还是外部程序存储器由PSEN引脚决定。

指令作用
MOVC A,@A+DPTRDPTR基址加变址寻址,将程序存储器中的内容存在累加器A中
MOVC A,@A+PCPC基址加变址寻址,将程序存储器中的内容存在累加器A中,PC保存的是下一条指令的首地址(程序存储器编址)。

需要注意的时,MOVC的用法是完全固定的,不可以创造指令,初学容易使用类似MOVC A,@DPTR这样的指令。

(3)MOVX指令用于对外部RAM进行访问。外部RAM编址由0开始,故必须区分MOV、MOVX才能避免冲突。

指令作用
MOVX A,@RiRi间接寻址,将外部RAM内容写到A中
MOVX A,@DPTRDPTR间接寻址,将外部RAM内容写到A中
MOVX @Ri,ARi间接寻址,将A内容写到外部RAM中
MOVX @DPTR,ADPTR间接寻址,将A内容写到外部RAM中

可以看到,外部RAM只能通过间接寻址的方式进行访问。由于51单片机支持最大64K的外部RAM扩展,所以必须使用16位的DPTR来完成所有地址空间的访问,在使用工作寄存器Ri对外部RAM进行访问时,Ri只能充当低八位地址,高八位地址,也就是P2口的输出需要人为给定。

(4)PUSHPOP指令。压栈和弹栈指令。

指令作用
PUSH direct直接寻址,将内容保存在SP所指向的地址单元,SP+1
POP direct直接寻址,将SP所指向的地址单元内容弹到新地址,SP-1

其实压栈和弹栈指令的本质就是将SP作为间接寻址寄存器,和内部RAM单元进行内容传输。只不过SP会自动增加或减少以在逻辑上维护这个一个平平无奇的内部RAM空间并将其称为栈。

(5)XCHXCHDSWAP等交换指令

指令作用
XCH A,Rn寄存器和A内容交换
XCH A,directA和内部RAM内容交换
XCH A,@Ri间接寻址,内容交换
XCHD A,@Ri间接寻址,只交换低4位
SWAP AA的高四位和低四位交换

算数操作类指令

操作码有ADDADDCSUBBINCDECMULDIVDA

具体内容见如下表格

指令作用
ADD A,Rn寄存器内容加到累加器
ADD A,direct直接寻址内容加到累加器
ADD A,@Ri寄存器间接寻址内容加到累加器
ADD A,#data立即数加到累加器
ADDC A,Rn寄存器内容加到累加器(考虑进位位Cy)
ADDC A,direct直接寻址内容加到累加器(考虑进位位Cy)
ADDC A,@Ri寄存器间接寻址内容加到累加器(考虑进位位Cy)
ADDC A,#data立即数加到累加器(考虑进位位Cy)
SUBB A,Rn累加器内容减寄存器内容(考虑Cy)A-(Rn)-Cy
SUBB A,direct累加器减直接寻址内容(考虑Cy)A-(direct)-Cy
SUBB A,@Ri累加器减寄存器间接寻址内容(考虑Cy)
SUBB A,#data累加器减立即数(考虑Cy)
INC A累加器加1
INC Rn工作寄存器加1
INC direct直接寻址地址内容加1
INC @Ri寄存器间接寻址地址内容加1
DEC A累加器减1
DEC Rn工作寄存器减1
DEC direct直接寻址地址内容减1
DEC @Ri寄存器间接寻址地址内容减1
INC DPTRDPTR加1,实际就是DPL+1并自动向DPH进位
MUL ABA内容乘寄存器B内容保存到A中
DIV ABA内容除寄存器B内容保存到A中
DA A累加器十进制调整

几点说明:

(1)单片机在进行运算操作时会影响程序状态寄存器PSW中的程序状态标志位。

PSW

P标志位只考虑A中1的奇偶个数,所以,只要对A的内容进行修改均会影响P的内容。

Cy和Ac仅在加减操作时会被影响:
当运算发生进位或借位时,Cy置1;否则清0;
当低四位向高四位发生进位或借位时,Ac置1,否则清0;

加减乘除均影响OV位,OV实际保存的是第六位与第七位进位异或的结果。也就是说,只有当第六位和第七位只有一个发生进位或借位时,OV才会置1,否则清0。

对PSW的影响

(2)十进制调整

这是一个特殊的操作,前提是我们将4位2进制数看作是一个10进制数。这样的话1010-1111是无效的。

举个例子,A=53H,R1=63H。当我们将这两个数用BCD编码表示为十进制数时,其值就是53和63。当我们进行加运算的时候,我们希望A中的结果应该是16H,而Cy保存的是1,这样我们好像就完成了一个十进制的加法运算,但在执行ADD指令时,53H和63H是被当作16进制数进行计算的,运算结果也是以16进制数的格式保存在A中,为了解决直观性的问题,我们可以利用DA指令处理运算后累加器A中的内容从而将其变为16H。

逻辑运算指令

指令作用
CLR A清零A
CPL A按位取反,不影响标志位
RL A循环左移
RLC A带进位的循环左移,Cy作为第九位
RR A循环右移
RRC A带进位的循环右移
ANL A,Rn逻辑按位与,保存到A
ANL A,direct逻辑按位与,保存到A
ANL A,#data逻辑按位与,保存到A
ANL A,@Ri逻辑按位与,保存到A
ANL direct,A逻辑按位与,保存到direct
ANL direct,#data逻辑按位与,保存到direct
ORL A,Rn逻辑按位或,保存到A
ORL A,direct逻辑按位或,保存到A
ORL A,#data逻辑按位或,保存到A
ORL A,@Ri逻辑按位或,保存到A
ORL direct,A逻辑按位或,保存到direct
ORL direct,#data逻辑按位或,保存到direct
XRL A,Rn逻辑按位异或,保存到A
XRL A,direct逻辑按位异或,保存到A
XRL A,#data逻辑按位异或,保存到A
XRL A,@Ri逻辑按位异或,保存到A
XRL direct,A逻辑按位异或,保存到direct
XRL direct,#data逻辑按位异或,保存到direct

这块比较简单,没什么好说的,一般我们可以通过移位操作实现对数据的倍乘。

控制转移类指令

用于控制程序的走向,实际大多是修改PC指针的值来完成的。我们首先列出所有的控制转移类指令,就几个难点讨论一下。

指令作用
AJMP addr112k空间内的无条件绝对跳转指令
SJMP relrel是一个补码,该条指令是一个无条件相对跳转指令
LJMP addr1664k空间无条件绝对跳转指令
JMP @A+DPTR基质加变址绝对跳转指令
JZ rel判断累加器A的值,为0则执行相对跳转
JNZ rel判断累加器A的值,非0则执行相对跳转
CJNE A,direct,rel不相等相对跳转指令,A大于direct空间的值则置位Cy
CJNE A,#data,rel不相等相对跳转指令,A大于#data则置位Cy
CJNE Rn,#data,rel不相等相对跳转指令,Rn的值大于#data则置位Cy
CJNE @Ri,#data,rel不相等相对跳转指令,Ri间接寻址的值大于#data则置位Cy
DJNZ Rn,rel减1不为0相对跳转指令,Rn执行完后会减1
DJNZ direct,rel减1不为0相对跳转指令,direct单元内容会减1
ACALL addr11与AJMP类似,不过会将PC压入堆栈
LCALL addr16长调用指令,PC+3后压入堆栈,实际就是将这条指令的下一条指令的地址压入了堆栈,先低字节后高字节,SP+2
RETSP-2,堆栈的内容弹到PC中,先高后低
RETI与RET差不多,用在中断服务程序中,会清除中断优先触发器
NOP空操作,PC+1,无其他操作

几点说明:

1、AJMP指令。首先它是一个2字节的指令,机器代码格式如下:

AJMP

高字节的高三位和低字节的8位组成一个11位的绝对地址。在执行该语句时,由于这是一个2字节指令,所以PC+2,随后将这11位地址保存到PC的低11位上实现绝对寻址。从逻辑上可以看出,这条指令实际将64K的程序空间划分为32个2K空间,只要PC+2不向PC的高5位发生进位,程序空间就会被限制在一个2K的子空间内。ACALL同理。

2、SJMP指令。这是一个无条件相对跳转指令。相对体现在他不是至今对PC进行赋值操作,而是对PC进行运算操作。且rel应该被当作一个有符号数来进行计算。执行这条指令后PC的值为PC+2+rel,rel是一个有符号数。但是在实际写代码时,rel常常写作一个标号类似Loop、Main之类的,这个时候我们可以把SJMP看成是一个绝对跳转指令,因为汇编软件帮我们完成了相对地址逆运算的过程。这部分可以套用到所有相对跳转指令中去

3、相对跳转指令PC的值一定要记得加上跳转指令本身的字节长度,这个是随着指令不同而变化的。

4、关于RET和RETI的详细区别:[RET和RETI]((162条消息) 51中ret和reti的区别_astrotycoon的博客-CSDN博客_汇编语言reti)

位操作指令

主要对PSW中的进位标志位进行操作。

指令具体如下:

指令作用
MOV C,bit将bit位的内容送到进位标志位C中
MOV bit,C将进位标志位C中的内容送到bit位
CLR C清零C
CLR bit清零一个bit位
CPL C取反C
CPL bit取反一个bit位
SETB C置1C
SETB bit置1一个bit位
ANL C,bit直接寻址位与C与,结果保存在C中
ANL C,/bit直接寻址位的反与C与,结果保存在C中不影响bit的值
ORL C,bit直接寻址位与或,结果保存在C中
ORL C,bit直接寻址位的反与C或,结果保存在C中不影响bit的值
JC relC为1则跳转
JNC relC为0则跳转
JB bit,relbit为1则跳转
JNB bit,relbit为0则跳转
JBC bit,relbit为1则跳转,并将bit清零

几点说明:

上面提到的bit为支持位寻址的存储空间,主要包括字节地址20H-2FH的RAM单元以及低四位地址为0或8的SFR。

C不能简单的看成是一个简单的位地址,但也可以通过位地址索引到C。
这句话的意思是C本身是一个特殊的关键字,而不可以看成是一个位地址的助记符号,否则MOV C,bit会与MOV direct,dorect2命令冲突。而我们可以通过C的位地址索引到C,比如我们可以执行 JBC 0D7H(C),rel来对C进行跳转判断清零操作。

伪指令一览

伪指令是控制汇编软件的关键字,实际不会写到程序存储器中的一些工具指令。

伪指令

  • 15
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值