单片机的指令系统:单片机自学(二)
一、概述
1、指令的格式:“标号:操作码助记符[(目的操作数),(源操作数)];注释”
我们已知,要让计算机工作,就得给计算机发指令,并且我们从上一课已知,计算机要完成你所给定的任务,必须为其编写相应的程序(所有指令的集合),计算机是机器只识别机器语言,机器语言是一种用二进制代码“0”和“1”的形式表示的,而如果我们使用者要用这种语言编写指令,将是繁琐费时和困难重重的;为此人们发明了汇编语言,汇编语言是一种用助记符来表示的面向机器的程序设计语言。汇编语句与机器指令是一一对应的,具体的汇编语句格式如上:助记符格式,如MOV P1,#0FFH,这样就方便使用和记忆了。
2、汇编
我们写指令使用汇编格式,而计算机只懂机器码格式,所以要将我们写的汇编格式的指令转换为机器码格式,这种转换有两种方法:手工汇编和机器汇编。手工汇编实际上就是查表,因为这两种格式纯粹是格式不同,所以是一一对应的,查一张表格就行了。不过手工查表不仅麻烦而且随着程序的长度增加完成的可能性越小,所以就有了计算机编译软件,用计算机软件来替代手工查表,这就是机器汇编,所以你起码要在你电脑中安装一种编译软件,如:KeilC51\MedWin等,可在网上下载,如直接输入MedWin搜索。当然要将你编写的程序放进如89C51单片机芯片中让它完成你想的任务,还要烧写芯片,烧写芯片是由编程器来完成的,所以你要购买一款编程器,如TOP851等;
3、指令格式祥解:“标号:操作码助记符[(目的操作数),(源操作数)];注释”
先看一段程序:
MAIN: MOV SP,#70H;将堆栈设置从70H单元地址开始
ACALL DELAY;
。。。
。。。
AJMP MAIN;MAIN为标号,程序将直接跳至该标号出继续执行
END
MAIN即是标号,MOV、ACALL、AJMP即是操作码助记符,SP就是目的操作数,#70H就是源操作数。
标号是指令的符号地址,可根据需要设置。一般用英文字母、数字表示,某个语句一旦赋予某个标号,则在其它语句的操作数中就可以直接引用该标号,以便控制程序的转移或寻址。标号和操作码之间用“:”号分开。
操作码与操作数之间用空格分隔,操作码在汇编语言中用助记符表示,它的作用是命令CPU作何种操作。操作数有目的操作数和源操作数,之间用“,”分隔。
注释是对该指令的解释,可有可无,对初学者来说应多写注释,注释之前用“;”隔开。
4、寻址方式
有7种方式如下:“@ ”表示为间接寻址
序号 寻址方式 相应存储器空间
1 寄存器寻址 R0-R7,ACC、B、Cy(位)DPTR
2 直接寻址 内部RAM区低128字节和特殊功能寄存器
3 寄存器间接寻址 内部RAM(@R0\ @R1,SP)外部数据存储器(@R0,@R1,@DPTR)
4 立即寻址 程序存储器立即数如:#66H
5 基址加变址寄存器间接寻址 程序存储器(@A+DPTR,@A+PC)
6 相对寻址 以PC的当前地址值+指令中给出的偏移量=有效的转移地址
7 位寻址 对RAM的可位寻址单元,特殊寄存器某些单元
二、指令祥解
51汇编指令共有111条,按指令的功能分为五大类:
数据传递类指令
这种传送指令的汇编格式为:MOV 《目的字节》,《源字节》;是将源字节的内容传送到目的字节,源字节内容保持不变。
1) 以累加器为目的操作数的指令
MOV A,Rn;Rn代表的是R0-R7
MOV A,direct;direct就是指的直接地址
MOV A,@Ri ;间接寻址R0、R1
MOV A,#data ;将立即数data送到A中
下面我们通过一些例子加以说明:
MOV A,R1 ;将工作寄存器R1中的值送入A,R1中的值保持不变。
MOV A,30H ;将内存30H单元中的值送入A,30H单元中的值保持不变。
MOV A,@R0 ;先看R0中是什么值,把这个值作为地址,并将这个地址单元中的值送入A中。如执行命令前R0中的值为30H,则是将30H单元中的值送入A中。
MOV A,#34H ;将立即数34H送入A中,执行完本条指令后,A中的值是34H。
2)以工作寄存器Rn为目的操作的指令
MOV Rn,A;
MOV Rn,direct;三字节指令
MOV Rn,#data;三字节指令
这组指令功能是把源地址单元中的内容送入工作寄存器,源操作数不变。
3)以直接地址为目的操作数的指令
MOV direct,A ;如: MOV 30H,A
MOV direct,Rn ;如:MOV 30H,R5
MOV direct1,direct2 ;如:MOV 20H,30H
MOV direct,@Ri ;如:MOV 30H,@R1
MOV direct,#data;如: MOV 20H,#68H;将立即数68H送入以20H为地址的单元中
(4)以间接地址为目的操作数的指令
MOV @Ri,A; 例:MOV @R0,A
MOV @Ri,direct ;MOV R1,30H
MOV @Ri,#data; MOV @R0,#68H
(5)十六位数的传递指令
MOV DPTR,#data16;将16位的地址送入数据指针DPTR中
8051是一种8位机,这是唯一的一条16位立即数传递指令,其功能是将一个16位的立即数送入DPTR中去。其中高8位送入DPH,低8位送入DPL。例:MOV DPTR,#1234H,则执行完了之后DPH中的值为12H,DPL中的值为34H。反之,如果我们分别向DPH,DPL送数,则结果也一样。如有下面两条指令:MOV DPH,#12H,MOV DPL,#34H。则就相当于执行了MOV DPTR,#1234H。
2、累加器A与片外RAM之间的数据传递类指令(存储器扩展时使用,初学者可以不去掌握)
MOVX A,@Ri
MOVX @Ri,A
MOVX A,@DPTR
MOVX @DPTR,A
说明:
1)在51中,与外部存储器RAM打交道的只可以是A累加器。所有需要送入外部RAM的数据必需要通过A送去,而所有要读入的外部RAM中的数据也必需通过A读入。在此我们可以看出内外部RAM的区别了,内部RAM间可以直接进行数据的传递,而外部则不行,比如,要将外部RAM中某一单元(设为0100H单元的数据)送入另一个单元(设为0200H单元),也必须先将0100H单元中的内容读入A,然后再送到0200H单元中去。
要读或写外部的RAM,当然也必须要知道RAM的地址,在后两条指令中,地址是被直接放在DPTR数据指针中的,可寻址64K字节的外部数据存储器。而前两条指令,由于Ri(即R0或R1)只是一个8位的寄存器,所以只提供低8位地址。因为有时扩展的外部RAM的数量比较少,少于或等于256个,就只需要提供8位地址就够了,8位的地址和数据均由P0口分时输入/输出。
使用时应当首先将要读或写的地址送入DPTR或Ri中,然后再用读写命令。
外部程序存储器和累加器A之间传送指令(存储器扩展时使用,初学者可以不去掌握)
MOVC A,@A+PC;PC为程序计数器,地址范围只能是以当前PC值为起始地址的256字节单元范围内;
MOVC A,@A+DPTR;64k地址
本指令是将ROM中的数送入A中。本指令也被称为查表指令,常用此指令来查一个已做好在ROM中的表格
说明:
此条指令引出一个新的寻址方法:变址寻址。本指令是要在ROM的一个地址单元中找出数据,显然必须知道这个单元的地址,这个单元的地址是这样确定的:在执行本指令立脚点DPTR中有一个数,A中有一个数,执行指令时,将A和DPTR中的数加起为,就成为要查找的单元的地址。
查找到的结果被放在A中,因此,本条指令执行前后,A中的值不一定相同。
例:有一个数在R0中,要求用查表的方法确定它的平方值(此数的取值范围是0-5)
MOV DPTR,#TABLE
MOV A,R0
MOVC A,@A+DPTR
.
.
TABLE: DB 0,1,4,9,16,25
设R0中的值为2,送入A中,而DPTR中的值则为TABLE,则最终确定的ROM单元的地址就是TABLE+2,也就是到这个单元中去取数,取到的是4,显然它正是2的平方。其它数据也可以类推。
堆栈操作指令
PUSH direct;入栈操作将direct中的内容送入堆栈中
POP direct;出栈操作将堆栈中的内容送回到direct中
首先将SP中的值加1,然后把SP中的值当作地址,将direct中的值送进以SP中的值为地址的RAM单元中。例:
MOV SP,#6FH
MOV A,#10
MOV B,#20
PUSH ACC
PUSH B
执行第一条PUSH ACC指令是这样的:将SP中的值加1,即变为70H,然后将A中的值送到70H单元中,因此执行完本条指令后, 内存70H单元的值就是10,同样,执行PUSH B时,再将SP+1,即变为71H,然后将B中的值送入到71H单元中,即执行完本条指令后,71H单元中的值变为20。
POP指令的执行是这样的,首先将SP中的值作为地址,并将此地址中的数送到POP指令后面的那个direct中,然后SP减1。
接上:
POP B
POP ACC
执行过程是:将SP中的值(现在是71H)作为地址,取71H单元中的数值(现在是20),送到B中,所以执行完本条指令后B中的值是20,然后将SP减1,因此本条指令执行完后,SP的值变为70H,然后执行POP ACC,将SP中的值(70H)作为地址,从该地址中取数(现在是10),并送到ACC中,所以执行完本条指令后,ACC中的值是10。
以上的操作看起来无意义,实际上在执行PUSH ACC后,就将刚才程序运算的结果保护起来,累加器ACC可以做别的运算了而不影响上一段程序运算的结果,在多任务处理时堆栈很有用。
--------------------------------------------------------------------------------
*在学习下一课算术运算之前先学习一下由于加、减、乘、除四则运算所影响的标志位;
程序状态字PSW
MCS-51有一个程序状态字寄存器PSW,用来保存指令执行结果的标志,供程序查询和判别。PSW是特殊功能寄存器中的一个,其格式如下:
D7位 D6 D5 D4 D3 D2 D1 D0位
Cy AC F0 RS1 RS0 OV --- P
PSW各位的功能:
PSW。7---(CY)既是累加器C,又是进位标志CY、如果操作结果在最高位有进位输出(加法时)或借位输入(减法时),置位CY,否则清“0”CY;
AC----辅助进位(半进位)标志 。如果操作结果的低4位有进位(加法时)或向高4位借位时(减法),置 位 AC,否则清“0”AC,AC主要用于二---十进制加法调整。
OV----溢出标志。如果操作结果有进位进入最高位,但最高位没有产生进位,或者最高位产生进位而低位没有向最高位进位,这时置位溢出标志位,否则OV清“0”溢出标志位用于补码运算,当有符号的数运算结果不能用8位二进制数表示时,OV将置位。
P----累加器A的奇偶标志位,如果累加器A的8位的模和为(奇),则P=1;否则P=0。由于P总是表示A的奇偶性,随着A的内容变化的,所以一个值写入PSW的P位值不变。
RS1、RS0----指示当前使用的工作寄存器区。
F0----用户标志位。可作为软件标志,它的作用和内部RAM位寻址区的各位相似。
0