历史上的今天
返回首页

历史上的今天

今天是:2025年12月12日(星期五)

正在发生

2022年12月12日 | MCS-51单片机指令系统(3)

2022-12-12 来源:zhihu

指令按寻址方式分有 7种寻址方式,直接寻址(direct)、立即寻址(#20H) 、寄存器寻址(Rn)、寄存器间接寻址(@Ri)、相对寻址(rel)、寄存器变址寻址(@A+PC)、位寻址 ( ACC.1)


指令按功能上分有5种 ,传送类指令 、算术运算类指令、逻辑运算及移位类指令、控制转移类指令、位操作类指令。其指令三大属性:功能属性、空间属性(指令站用的字节数)、时间属性(指令执行的机器周期数)。


一、数据传送指令(28):

使用最频繁的一类指令,通用格式:

MOV <目的操作数>,<源操作数>

属“复制”性质,而不是“搬家”。数据传送类指令不影响标志位:Cy、Ac和OV,影响奇偶标志位P。


1.内部RAM数据传送指令(16条)

(1)以累加器为目的操作数的指令(4条)

MOV A,Rn ; (Rn)→A,n=0~7

MOV A,@Ri ; ((Ri))→A,i=0,1

MOV A,direct ;(direct)→A

MOV A,#data ; #data→A

(2) 以Rn为目的操作数的指令(3条)

MOV Rn,A ; (A)→Rn,n=0~7

MOV Rn,direct ;(direct)→Rn,n=0~7

MOV Rn,#dat ; #data→Rn,n=0~7

功能:是把源操作数的内容送入当前一组工作寄存器区的R0~R7中的某一个寄存器。

(3)以直接地址direct为目的操作数的指令(5条)

MOV direct,A ; (A)→direct

MOV direct,Rn;(Rn)→direct, n=0~7

MOV direct1,direct2;

MOV direct,@Ri ; ((Ri))→direct

MOV direct,#data; #data→direct

功能:把源操作数送入直接地址指出的存储单元。direct指的是内部RAM或SFR的地址。

(4)以寄存器间接地址为目的操作数的指令(3条)

MOV @Ri,A ;(A)→((Ri)),i=0,1

MOV @Ri,direct ; (direct)→((Ri))

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

(5)16位数传送指令 (1条)

MOV DPTR,#data16 ; #data16→DPTR

唯一的16位数据的传送指令 ,立即数的高8位送入DPH,立即数的低8位送入DPL。


2.堆栈操作指令(2条)

MCS-51内部RAM中可以设定一个后进先出(LIFO-Last In First Out)的区域称作堆栈。堆栈指针SP指出堆栈的栈顶位置。进栈指令

PUSH direct

先将栈指针SP加1,然后把direct中的内容送到栈指针SP指示的内部RAM单元中。

出栈指令

POP direct

SP指示的栈顶(内部RAM单元)内容送入direct字节单元中,栈指针SP减1。


3.累加器A与外部数据存储器传送指令(4)

MOVX A,@DPTR ;((DPTR))→A,读外部RAM/IO

MOVX A,@Ri ;((Ri))→A,读外部RAM/IO

MOVX @DPTR,A;(A)→((DPTR)),写外部RAM/IO

MOVX @Ri,A ;(A)→((Ri)),写外部RAM/IO

功能:读外部RAM存储器或I/O中的一个字节,或把A中一个字节的数据写到外部RAM存储器或I/O中。

注意:RD*或WR*信号有效。

采用DPTR间接寻址,高8位地址(DPH)由P2口输出,低8位地址(DPL)由P0口输出。

采用Ri(i=0,1)间接寻址,可寻址片外RAM的256个单元。Ri内容由P0口输出。

MOV后 “X”表示单片机访问的是片外RAM存储器或I/O。


4.程序ROM数据传送指令查表指令(2条)

用于读程序存储器中的数据表格的指令,均采用基址寄存器加变址寄存器间接寻址方式。

(1)MOVC A,@A+PC

以PC作基址寄存器,A的内容作为无符号整数和PC中的内容(下一条指令的起始地址)相加后得到一个16位的地址,该地址指出的程序存储单元的内容送到累加器A。

注意:PSEN*信号有效。

优点:不改变特殊功能寄存器及PC的状态,根据A的内容就可以取出表格中的常数。

缺点:表格只能存放在该条查表指令后面的256个单元之内,表格的大小受到限制,且表格只能被一段程序所利用。

(2)MOVC A,@A+DPTR

以DPTR作为基址寄存器,A的内容作为无符号数和DPTR的内容相加得到一个16位的地址,把由该地址指出的程序存储器单元的内容送到累加器A. 本指令的执行结果只和指针DPTR及累加器A的内容有关,与该指令存放的地址及常数表格存放的地址无关,因此表格的大小和位置可以在64K程序存储器中任意安排,一个表格可为各个程序块公用。

两条指令是在MOV的后面加C,“C”是CODE的第一个字母,即代码的意思。


5.数据交换指令(4条)

(1)整字节数据交换指令(3条)

XCH A,Rn

XCH A,direct

XCH A,@Ri

(2)半字节交换指令:累加器的低4位与内部RAM低4位交换。

XCHD A,@Ri


二、算术操作类指令(24条)

单字节的加、减、乘、除法指令,都是针对8位二进制无符号数。执行的结果对Cy、Ac、OV 三种标志位有影响。但增1和减1指令不影响上述标志。

1.加法指令(4条)

ADD A,Rn ;(A)+(Rn)→A,n=0~7

ADD A,direct ;(A)+(direct)→A

ADD A,@Ri ;(A)+((Ri))→A,i=0,1

ADD A,#data ; (A)+#data→A

一个加数总是来自累加器A,而另一个加数可由不同的寻址方式得到。结果总是放在A中。使用加法指令时,要注意累加器A中的运算结果对各个标志位的影响:

(1)如果位7有进位,则置“1”进位标志Cy,否则清“0”Cy

(2)如果位3有进位,置“1”辅助进位标志Ac,否则清“0”Ac(Ac为PSW寄存器中的一位)

(3)如果位6有进位,而位7没有进位,或者位7有进位,而位6没有,则溢出标志位OV置“1”,否则清“0”OV。溢出标志位OV的状态,只有在带符号数加法运算时才有意义。当两个带符号数相加时,OV=1,表示加法运算超出了累加器A所能表示的带符号数的有效范围。


2.带进位加法指令(4条)

标志位Cy参加运算,因此是三个数相加。

ADDC A,Rn ;(A)+(Rn)+C→A,n=0~7

ADDC A,direct ;(A)+(direct)+C→A

ADDC A,@Ri ;(A)+(Ri)+C→A,i=0,1

ADDC A,#data ;(A)+#data+C→A


3.增1指令 (5条)

INC A

INC Rn ;n=0~7

INC direct

INC @Ri ;i=0,1

INC DPTR

不影响PSW中的任何标志。第5条指令INC DPTR,是16位数增1指令。指令首先对低8位指针DPL的内容执行加1的操作,当产生溢出时,就对DPH的内容进行加1操作,并不影响标志Cy的状态。


4.十进制调整指令(1条)

用于对BCD码十进制数加法运算结果的内容修正。

指令格式: DA A

两个BCD码按二进制相加之后,必须经本指令的调整 才能得到正确的压缩BCD码的和数。二进制数的加法运算原则并不能适用于十进制数的加法运算,有时会产生错误结果。


出错原因和调整方法:

BCD码只用了了其中的10个,6个没用到的编码。(1010,1011,1100,1101,1110,1111)为无效码 。凡结果进入或者跳过无效码编码区时,其结果就是错误的。调整的方法是把结果加6调整,即所谓十进制调整修正。

修正方法应是:

(a)累加器低4位大于9或辅助进位位Ac=1,则进行低4位加6修正。

(b)累加器高4位大于9或进位位Cy=1,则进行高4位加6修正。

(c)累加器高4位为9,低4位大于9,则高4位和低4位分别加6修正。

具体是通过执行指令:DA A 来自动实现的 。


5.带借位的减法指令(4条)

SUBB A,Rn ; (A)-(Rn)- Cy→A,n=0~7

SUBB A,direct ; (A)-(direct)- Cy→A

SUBB A,@Ri;(A)-((Ri))- Cy→A, i=0,1

SUBB A,#data ;(A)-#data - Cy→A

从累加器A中的内容减去指定的变量和进位标志Cy的值,结果存在累加器A中。

如果位7需借位则置“1” Cy,否则清“0”Cy;

如果位3需借位则置“1”Ac,否则清“0”Ac;

如果位6需借位而位7不需要借位,或者位7需借位,位6不需借位,则置“1”溢出标志位OV,否则清“0”OV。


6.减1指令(4条)

DEC A ;(A)-1→A

DEC Rn ;(Rn)-1→Rn,n=0~7

DEC direct ;(direct)-1→direct

DEC @Ri ;((Ri))-1→(Ri),i=0,1

减1指令不影响标志位。


7.乘法指令(1条)

MUL AB ;A×B→BA

如果积大于255,则置“1”溢出标志位OV


8.除法指令 (1条)

DIV AB ;A/B→A(商),余数→B

如果B的内容为“0”(即除数为“0”),则存放结果的A、B中的内容不定,并置“1”溢出标志位OV。


三、 逻辑运算指令(25条)

1. 简单逻辑操作指令(2条)

(1) CLR A

功能是累加器A清“0”。不影响Cy、Ac、OV等标志。

(2) CPL A

功能:累加器A的内容按位逻辑取反,不影响标志。

2.左环移指令

RL A

功能是累加器A的8位向左循环移位,位7循环移入位0,不影响标志。

3.带进位左环移指令

RLC A

功能是将累加器A的内容和进位标志位Cy一起向左环移一位,Acc.7移入进位位Cy,Cy移入Acc.0,不影响其它标志。

4.右环移指令

RR A

功能是累加器A的内容向右环移一位,Acc.0移入Acc.7,不影响其它标志。

5.带进位环移指令

RRC A

功能:累加器A的内容和进位标志Cy一起向右环移一位,Acc.0进入Cy,Cy移入Acc.7。

6.累加器半字节交换指令

SWAP A

将累加器A的高半字节(Acc.7~Acc.4)和低半字节(Acc.3~Acc.0)互换。

7.逻辑与指令

ANL A,Rn ; (A)∧(Rn)→A,n=0~7

ANL A,direct ; (A)∧(direct)→A

ANL A,#data ; (A)∧#data→A

ANL A,@Ri ; (A)∧((Ri))→A,i=0~1

ANL direct,A ; (direct)∧(A)→direct

ANL direct,#data ; (direct)∧#data→direct

8.逻辑或指令

ORL A,Rn ;(A)∨(Rn)→A ,n=0~7

ORL A,direct ;(A)∨(direct)→A

ORL A,#data ;(A)∨ data→A

ORL A,@Ri ; (A)∨((Ri))→A,i=0,1

ORL direct,A ;(direct)∨(A)→direct

ORL direct,#data ;(direct)∨#data→direct

9.逻辑异或指令

XRL A,Rn ;(A) ⊕(Rn)→A

XRL A,direct ;(A) ⊕(direct)→A

XRL A,@Ri ;(A)⊕((Ri))→A ,i=0,1

XRL A,#data ;(A)⊕#data→A

XRL direct,A ;(direct)⊕(A)→direct

XRL direct,#data;(direct)⊕ #data →direct


四、 控制转移类指令(17条)

1.无条件转移指令

AJMP addrll

2K字节范围内的无条件跳转指令, 64K程序存储器空间分为32个区,每区2K字节,转移的目标地址必须与AJMP下一条指令的地址的高5位地址码A15-A11相同。执行指令时,先PC加2,然后把addrll送入PC.10~PC.0,PC.15~PC.11保持不变,程序转移到目标地址。

本指令是为能与MCS-48的JMP指令兼容而设的。

2.相对转移指令

SJMP rel

实现的程序转移是双向的。在编写程序时,直接写上要转向的目标地址标号就可以。

3.长跳转指令

LJMP addr16

指令执行时把指令的第二和第三字节分别装入PC的高位和低位字节中,无条件地转向addr16指出的目标地址。目标地址可以在64K程序存储器地址空间的任何位置。

4.间接跳转指令

JMP @A+DPTR

由A中8位无符号数与DPTR的16位数内容之和来确定。以DPTR内容作为基址,A的内容作变址。给A赋予不同的值,即可实现程序的多分支转移。

5.条件转移指令

规定的条件满足,则进行转移,条件不满足则顺序执行下一条指令。当条件满足时,把PC装入下一条指令的第一个字节地址,再把带符号的相对偏移量rel加到PC上,计算出目标地址。

JZ rel ;如果累加器为“0”,则转移

JNZ rel ;如果累加器非“0”,则转移

6.比较不相等转移指令

CJNE A,direct,rel

CJNE A,#data,rel

CJNE Rn,#data,rel

CJNE @Ri,#data,rel

比较前面两个操作数的大小,如果它们的值不相等则转移。如果第一操作数(无符号整数)小于第二操作数(无符号整数),则置进位标志位Cy,否则清“0”Cy。

7.减1不为0转移指令

这是一组把减1与条件转移两种功能结合在一起的指令。共两条指令:

DJNZ Rn,rel ;n=0~7

DJNZ direct,rel

将源操作数(Rn或direct)减1,结果回送到Rn寄存器或direct中去。如果结果不为0则转移。允许程序员把寄存器Rn或内部RAM的direct单元用作程序循环计数器。主要用于控制程序循环。以减1后是否为“0”作为转移条件,即可实现按次数控制循环。

8.调用子程序指令

(1)短调用指令

ACALL addrll

与AJMP指令相类似,是为了与MCS-48中的CALL指令兼容而设的。

(2)长调用指令

LCALL addr16

9.子程序的返回指令

RET

执行本指令时:

(SP)→PCH,然后(SP)-1→SP

(SP)→PCL,然后(SP)-1→SP

功能:从堆栈中退出PC的高8位和低8位字节,把栈指针减2,从PC值开始继续执行程序。

10.中断返回指令

RETI

功能:与RET指令相似,两指令不同之处,是本指令清除了中断响应时,被置“1”的MCS-51内部中断优先级寄存器的优先级状态。

11.空操作指令

NOP

五、 位操作指令

1.数据位传送指令

MOV C,bit

MOV bit,C

2.位变量修改指令

CLR C ;清“0”Cy

CLR bit ;清“0”bit位

CPL C ;Cy求反

CPL bit ;bit位求反

SETB C ;置“1” Cy

SETB bit ;置“1” bit位

这组指令将操作数指出的位清“0”、求反、置“1”, 不影响其它标志。

3.位变量逻辑与指令

ANL C,bit ;bit∧Cy→Cy

ANL C,/bit; ;/bit ∧Cy→Cy

4.位变量逻辑或指令

ORL C,bit

ORL C,/bit

5.条件转移类指令

JC rel ;如果进位位Cy=1,则转移

JNC rel ;如果进位位Cy=0,则转移

JB bit,rel ;如果直接寻址位=1,则转移

JNB bit,rel ;如果直接寻址位=0,则转移

JBC bit,rel ;如果直接寻址位=1, 则转移,并清0直接寻址位

读者可根据指令助记符,迅速查到对应的指令代码(手工汇编)。也可根据指令代码迅速查到对应的指令助记符(手工反汇编)。

应熟练地掌握指令表的使用!!!

因为这是使用MCS-51汇编语言进行程序设计的基础。


推荐阅读

史海拾趣

Aromat Corp公司的发展小趣事

在电子行业快速发展的背景下,Aromat Corp始终坚持创新引领的发展理念。公司不断投入研发资源,推出了一系列具有创新性的电子产品。这些产品不仅满足了市场的多样化需求,还为公司带来了可观的利润增长。同时,Aromat Corp还注重知识产权保护,积极申请专利,保护公司的创新成果。

Crystek公司的发展小趣事

Crystek公司成立于1958年,自创立之初,就致力于成为射频微波和频率控制行业的高性能技术领导者。创业初期,Crystek公司凭借其敏锐的市场洞察力和前瞻性的技术视野,成功开发了一系列高质量的频率产品,包括石英晶振、时钟振荡器(XO)等,逐渐在市场中树立起了良好的口碑。通过不断的努力和创新,Crystek公司逐渐在电子行业中崭露头角,赢得了客户的信任和认可。

Crameda Intersys公司的发展小趣事

随着公司业务的不断发展,Crameda Intersys公司开始寻求与行业内其他企业的战略合作。公司通过与多家知名企业建立紧密的合作关系,共同研发和推广新技术产品,成功将业务扩展到全球市场。这些战略合作不仅拓宽了公司的市场渠道,也提升了公司的品牌影响力和市场竞争力。同时,通过与合作伙伴的深入交流和学习,公司不断吸收新的技术和理念,为自身的创新和发展注入了新的活力。

American Electric公司的发展小趣事

在发展过程中,American Electric公司也面临过各种挑战和危机。例如,XXXX年,公司遭遇了一次严重的自然灾害,导致部分电力设施受损。然而,公司迅速启动了应急响应机制,组织抢修队伍进行抢修,并在最短时间内恢复了供电。此外,在面对政策调整、市场竞争等挑战时,公司也能够灵活应对,通过调整战略、优化管理等方式保持稳健发展。

EDDING公司的发展小趣事

ECLIPSE公司深知,要想在竞争激烈的电子行业中保持领先地位,必须不断创新和满足用户需求。因此,公司投入大量资源用于Eclipse的研发和更新,不断推出新版本和新功能。同时,ECLIPSE公司也非常重视社区建设,通过举办开发者大会、提供在线支持等方式,积极与全球开发者互动和交流。这些努力不仅增强了Eclipse的用户黏性,也为其带来了更多的创新思路和商业机会。

胜利(VICTOR)公司的发展小趣事

胜利公司深知品牌文化对于提升品牌价值的重要性。因此,公司积极开展文化营销活动,如举办羽毛球文化节、赞助羽毛球赛事等。通过这些活动,公司不仅与消费者建立了深厚的情感联系,还提升了品牌的知名度和美誉度。

以上故事均基于虚构,旨在展示一个品牌成长的可能路径和方式。如有需要,请结合实际情况进行调整和修改。

问答坊 | AI 解惑

C语言时钟程序在KEIL中提示出错

#include                         #define uchar unsigned char #define uint unsigned int char DATA_7SEG[10]={0xC0,0xF9,0xA4,0xB0,0x99,     ...…

查看全部问答>

多线程中使用WSAStartup和WSAClearup

我该在那里调用WSAStartup和WSAClearup呢,是每个线程在进入时调用一次WSAStartup、退出时调用一次WSAClearup呢,还是在主函数中调用一次WSAStartup和WSAClearup呢? 我现在有两个类,两个类都使用了网络,都开了一个线程,我现在的做法是在每个类 ...…

查看全部问答>

【转载】房子我喜欢Q版,车子却偏爱大肚腩

前几天看到坛子里有兄弟贴出了B70的平均油耗,着实超出我的意料,没想到2.0MT的平均油耗能控制在8个油,这可是我买车首要参照的系数,不然就真是买车容易养车难了;此外,空间必须足够大,谁让咱的房子已经是Q版了,车子可不能在抠抠嗖嗖的了。 ...…

查看全部问答>

香版主:虚拟串口

香版主:STM32USB的虚拟串口怎么用?我下了这个"VCPDriver_V1.1_Setup"装上去怎么没反映?还有我在"um0424"上没有找到"Software Driver"文件夹,当然也没有inf文件.大家帮帮忙啊,  …

查看全部问答>

STM32 USB HID实现USB双向通信

STM32 和USB HID实现USB双向通信有什么作用??…

查看全部问答>

AD的困扰--AD采集的数据转换后比模拟量值偏小

最近用msp430f2013的SD16采集0.08v到0.4v的电压值,但是AD转换后的数据比模拟值要偏小,而且随着信号的增大,偏差越来越大。量程范围内,最大偏差10mv。各位大侠请指点下小弟,感激不尽。…

查看全部问答>

ARM Cortex-M0 LPC1114入门手册

奉献:ARM Cortex-M0 LPC1114入门手册 第一章 简介第二章 初识LPC1114   2.1 观引脚识功能   2.2 寄存器配置第三章 LPC1114开发环境建立与使用   3.1 安装开发软件   3.2 新建一个LPC1114工程  &nbs ...…

查看全部问答>

做DSP开发最应当懂的34个问题

replyreload += \',\' + 1586804;做DSP开发最应当懂的34个问题 一.什么是DSP?(缺省) 二.DSP的C语言同主机C语言的主要区别? 1)DSP的C语言是标准的ANSI C,它不包括同外设联系的扩展部分,如屏幕绘图等。但在CCS中,为了方便调试,可以将数据通过p ...…

查看全部问答>

求助:EM78P153的代码选项寄存器word0、word1、word2怎么赋值

如题,EM78P153提供了三个代码选项寄存器,datasheet里面又说在执行程序时不能存取,那怎么赋值呢?这是位配置? 写了个延时函数 void delay(unsigned int z),调用的时候 delay(1000);出现warning说是从short转换到unsigned int溢出,改成25 ...…

查看全部问答>

求助

图1D1的作用是什么,工作原理是怎么样的,求解释 …

查看全部问答>