单片机自学(二):单片机的指令系统



一、概述

 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条,按指令的功能分为五大类:

     

  1. 数据传递类指令
    这种传送指令的汇编格式MOV 《目的字节》,《源字节》;是将源字节的内容传送到目的字节,源字节内容保持不变。
    1) 以累加器为目的操作数的指令

    MOV ARn;Rn代表的是R0-R7

    MOV Adirect;direct就是指的直接地址

    MOV A@Ri ;间接寻址R0、R1

    MOV A#data ;将立即数data送到A

    下面我们通过一些例子加以说明:

    MOV AR1 ;将工作寄存器R1中的值送入AR1中的值保持不变。

    MOV A,30H ;将内存30H单元中的值送入A30H单元中的值保持不变。

    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中的值为12HDPL中的值为34H。反之,如果我们分别向DPHDPL送数,则结果也一样。如有下面两条指令:MOV DPH#12HMOV 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单元中去。

  1. 要读或写外部的RAM,当然也必须要知道RAM的地址,在后两条指令中,地址是被直接放在DPTR数据指针中的,可寻址64K字节的外部数据存储器。而前两条指令,由于Ri(即R0R1)只是一个8位的寄存器,所以只提供低8位地址。因为有时扩展的外部RAM的数量比较少,少于或等于256个,就只需要提供8位地址就够了,8位的地址和数据均由P0口分时输入/输出。

     

  2. 使用时应当首先将要读或写的地址送入DPTRRi中,然后再用读写命令。

     

  1. 外部程序存储器和累加器A之间传送指令(存储器扩展时使用,初学者可以不去掌握)

    MOVC  A,@A+PC;PC为程序计数器,地址范围只能是以当前PC值为起始地址的256字节单元范围内;

MOVC A@A+DPTR;64k地址

本指令是将ROM中的数送入A中。本指令也被称为查表指令,常用此指令来查一个已做好在ROM中的表格

说明:

  1. 此条指令引出一个新的寻址方法:变址寻址。本指令是要在ROM的一个地址单元中找出数据,显然必须知道这个单元的地址,这个单元的地址是这样确定的:在执行本指令立脚点DPTR中有一个数,A中有一个数,执行指令时,将ADPTR中的数加起为,就成为要查找的单元的地址。

     

  2. 查找到的结果被放在A中,因此,本条指令执行前后,A中的值不一定相同。

     

例:有一个数在R0中,要求用查表的方法确定它的平方值(此数的取值范围是0-5

MOV DPTR#TABLE

MOV AR0

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中,然后SP1

接上:

POP B

POP ACC

执行过程是:将SP中的值(现在是71H)作为地址,取71H单元中的数值(现在是20),送到B中,所以执行完本条指令后B中的值是20,然后将SP1,因此本条指令执行完后,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位寻址区的各位相似。

       
       











              返回单片机与电子制作首页                                       上一课     下一课