51单片机指令系统详解

指令系统

微型机的功能是由指令系统体现的。所以,寻址方式和指令系统是衡量微型机的重要指标。

MSC-51的指令系统一共有111条指令,包括单字节49条,双字节46条和三字节16条。按周期分,有单周期,双周期和三周期指令。在晶振频率为12MHZ时,三种不同周期的指令执行的时间分别为1 μ s {\mu}s μs、2 μ s {\mu}s μs、4 μ s {\mu}s μs.

按照功能来分一共可以分为以下五类

  • 数据传送类指令
  • 算数运算类指令
  • 逻辑运算类指令
  • 程序控制类指令
  • 位(布尔)操作类指令
  1. 数据传送类指令:

    数据传送类指令是最常用,最基本的一类指令。它们可以实现寄存器与寄存器之间、寄存器与片内RAM之间、片内RAM单元之间的数据传送等。

    1. 八位数通用传送指令
      • MOV 目的,源

        指令中,源操作数是指带传送的数据源,它可以是立即数、累加器A,工作寄存器或片内RAM存储单元;目的操作数是指数据源传送到的目的地,不能是立即数。

        指令执行后,源操作数不变,目的操作数被改变。

        1. 累加器A为目的的操作数的指令

          MOV A,Rn;A<-Rn
          MOV A,direct;A<-(direct)
          MOV A,@Ri;A<-(Ri)
          MOV A,#data;A<-data
          
        2. 工作寄存器Rn为目的的操作数的指令

          MOV Rn,A;Rn<-A 传送的是A中保存的数
          MOV Rn,direct;Rn<-(direct)
          MOV Rn,#data;Rn<-data
          ;把源操作数的累加器A,片内RAM单元,SFR内容或立即数传送到R0~R7的某个寄存器中
          
        3. 直接地址为目的操作数的指令

          MOV direct,A;(direct)<-A
          MOV direct,Rn;(direct)<-Rn
          MOV direct,direct;(direct)<-(direct)
          MOV direct,@Ri;(direct)<-Ri
          MOV direct,#data;(direct)<-data
          ;需要注意的是:MOV direct,direct和MOV direct,#data均为三字节指令,但汇编后,它们的指令机器代码排列顺序不同。
          ;操作码 源direct 目的direct(源地址在前,目的地址在后)
          ;操作码 direct data 目的地址在前,源操作数在后
          
        4. 间接地址为目的操作数的指令

          MOV @Ri,A;(Ri)<-A 把A中的数传送给(Ri)地址下保存的数。比如Ri=30H,A=20H,则操作后(30H)=20H
          MOV @Ri,direct;(Ri)<-(direct)
          MOV @Ri,#data;(Ri)<-data
          
    2. 16位数目标地址传送指令
      MOV DPTR,#data 16
      ;唯一的16位立即数传送指令
      ;DPTR是一个16位的地址寄存器,所以通常称16位立即数为目标地址
      ;这也是一个三字节的指令。汇编成机器码的时候,立即数的高位字节在前,低位字节在后
      MOV DPTR,#2068H
      ;机器代码 90 20 68
      
    3. 堆栈操作指令
      PUSH direct ;SP<-SP+1,(SP)<-(direct)
      POP direct ;(direct)<-(SP),SP<-SP-1
      ;SP始终指向栈顶,PUSH是入栈指令,POP是出栈指令
      ;eg:设SP=30H,(50H)=80H
      PUSH 50H ;SP从30H变为31H,同时把(50H)->(31H)
      POP 40H ;把(31H)->(40H),同时SP从31H变为30H
      
    4. 查表指令(程序存储器内容送累加器A)
      • 主要有两条

        1. 查表指令(以PC作为基址)

          MOVC A,@A+PC ;PC<-PC+1,A<-(A+PC)
          ;通过将PC当前值与累加器A中的地址偏移量相加,将得到的地址中间的数取给A
          ;步骤如下:
          ;1.将地址偏移量(待查数据表的项数)送累加器A
          ;2.用加法指令(ADD A,#data)对累加器A进行修正,修正量data由PC(CURRENT)+data=数据表首地址计算出
          ;若data=1,则可以采用INC A指令对A进行修正
          ;这里主要是通过参考PC地址在PC后面进行查表。这里面数据只能存放在PC的后面,且需要与命令保持一定的间距
          
        2. 查表指令(以DPTR作为基址)

          MOVC A,@A+DPTR  ;A<-A+DPTR
          ;这是一条单字节指令,以DPTE为基址寄存器,存放数据表的首地址
          ;由于DPTR为一个十六位的寄存器,可以任意设定初值,因此数据表可以随意设置。
          ORG 0200H
          HEXABC: MOV DPTR,#DTAB ;置数据表首地址
          	  MOVC A,@A+DPTR ;查表
          	  RET 
          DTAB:  DB 30H
          	 ;...
          	 DB 39H
          	 ;...
          	 DB 46H
          ;这里面取DTAB的值就是DTAB所在的地址
          
    5. 累加器A与片外数据存储器传送指令
      • CPU访问片外数据存储器RAM时,只能通过累加器A进行,包括读取片外RAM的数据和把数据写到片外RAM存储单元中。指令如下:

        MOVX A,@Ri ;A<-(Ri)
        MOVX A,@DPTR ;A<-(DPTR)
        MOVX @Ri,A ;(Ri)<-A
        MOVX @DPTR,A ;(DPTR)<-A
        

        例如,把片内RAM 40H单元中的内容送到片外RAM2000H单元中去:

        MOV A,40H
        MOV DPTR,#2000H
        MOVX @DPTR,A
        ;访问外部只有上面的四个操作,其他操作都是违规的
        
    6. 交换指令

      • 交换指令一共有五条:

        1. 字节交换指令

          XCH A,Rn ;A<->Rn
          XCH A,direct ;A<->direct
          XCH A,@Rn ;A<->(Ri)
          ;XCH的功能是将累加器A中的内容与源操作数所指的数据互相交换
          
        2. 半字节交换指令

          XCHD A,@Ri ;A.3~A.0<->(Ri.3~Ri.0)
          ;该指令的功能是,将累加器A中的低四位与Ri间接寻址单元内容的低四位相互交换,而各自的高四位的内容不变。
          ;对于十六进制位来说,就是只交换个位的数字
          
        3. 累加器A的高四位与低四位内容呼唤指令

          SWAP A ;A.3~A.0<->A.7~A.4
          ;将A的高、低两半字节相互交换。本指令也可以看作4位循环移位指令
          
  2. 算数运算类指令

    • MCS-51算数运算类指令主要是对8位无符号二进制数进行加减乘除四则运算。增一,减一;实现对BCD码的压缩。一共有24条

    • 在加法,带进位的假发和带借位的剑法的指令中,累加器A中总是存放着目的操作数,并存放操作的中间结果。这些指令都影响程序状态字寄存器PSW的进位位CY,溢出位OV,半进位位AC和奇偶标志位P。乘法和除法只影响标志位OV和P

      1. 加法类指令

        主要有四条

        ADD A,Rn ;A<-A+Rn
        ADD A,direct ;A<-A+(direct)
        ADD A,@Ri ;A<-A+(Ri)
        ADD A,#data ;A<-A+data
        
      2. 带进位的加法指令

        ADDC A,Rn ;A<-A+Rn+CY
        ADD A,direct ;A<-A+(direct)+CY
        ADD A,@Ri ;A<-A+(Ri)+CY
        ADD A,#data ;A<-A+data+CY
        
      3. 加一指令

        INC A
        INC Rn 
        INC direct
        INC @Ri
        INC DPTR
        ;把操作数所指定单元的内容加一。其操作除了第一条指令影响奇偶标志位外,其余指令操作均不影响PSW。程序设计中,+1指令的使用十分频繁,通常配合寄存器间址指令使用,用于修改地址指针。
        
      4. 带借位的减法指令

        SUBB A,Rn 
        SUBB A,direct
        SUBB A,@Ri
        SUBB A,#data
        ;A<-A-Rn-CY
        
      5. 减一指令

        DEC A ;A<-A-1
        DEC Rn
        DEC direct
        DEC @Ri
        ;这组指令的功能是把操作数所指定的单元内容减一,其操作除了第一条指令影响奇偶标志外,其余指令操作均不影响PSW标志
        
      6. 乘法指令

        MUL AB
        ;将A,B,两个八字节位的无符号数相乘。结果为16字节数。结果的高八位保存在B中,低八位保存在A中。如果B中有数,则OV(溢出位)置为一。
        
      7. 除法指令

        DIV AB ;A/B 商保存在A中,余数保存在B中
        ;如果被除数B为零,则OV置为1,否则置为零
        
  3. 逻辑运算类指令

    • 这类指令主要用于对八字节数进行逻辑运算。包括逻辑与,或,异或,取反,以及逻辑移位指令。

      1. 逻辑“与”指令

        ANL A,Rn
        ANL A,direct
        ANL A,@Ri
        ANL A,#data
        ANL direct,A
        ANL direct,#data
        ;前四条指令的目的操作数是累加器A,源操作数可以是工作寄存器,片内RAM和立即数。指令的功能是,将A中的内容和源操作数所指定的内容按位逻辑与,结果存入目的操作数中。
        ;逻辑与指令常用于屏蔽某些位
        
      2. 逻辑“或”指令

        ORL A,Rn
        ORL A,direct
        ORL A,@Ri
        ORL A,#data
        ORL direct,A
        ORL direct,#dataORL  
        ;使用逻辑和逻辑与一样。两个的缩写也可以看出,一个是AND LOGICAL 一个是OR LOGICAL
        
      3. 逻辑异或指令

        XRL  A,Rn
        XRL A,direct
        XRL A,@Ri
        XRL A,#data
        XRL direct,A
        XRL direct,#dataORL  
        ;使用逻辑与上面一样。 X OR LOGICAL
        
      4. 累加器A清零指令

        CLR A;A<-0
        
      5. 累加器A取反指令

        CPL A ;A<-!A
        ;这条指令的功能是将累加器A的内容逐位取反
        
      6. 累加器A循环移位指令

        RL A ;(REMOVE LEFT的缩写),循环向左移动一位。比如说0000 1111B移动之后变成0001 1110B 后面的操作同理
        RR A ;循环向右移动一位
        RLC A ; REMOVE LEFT C 将累加器A的内容连同进位位CY向左循环移动一位(CY D0~D7)可以看成九位数的循环移位
        RRC A ;带进位位的循环向右移位
        
  4. 控制转移类指令

    • 控制转移类指令属于程序控制指令。其作用是改变程序执行的方向,或者调用子程序,或者从子程序返回。这些都是通过改变程序计数器PC实现的。

    • 这类指令可以分为转移指令,调用子程序指令和返回指令。

      1. 转移类指令

        转移类指令通过改变PC的内容,以改变正在执行的指令顺序,转向新的地址继续执行下去,从而实现程序的分支。根据指令转移的条件,转移指令可以分为无条件转移指令和条件转移指令。前者CPU无条件的转移到指定位置执行程序,后者只有当条件满足的时候才能实现程序的转移,否则继续执行下一条指令。

        • 无条件转移指令

          LJMP addr16 ;PC<-addr16
          AJMP addr11 ;PC<-PC+2,PC.10~PC.0<-addr11
          JMP @A+DPTR ;PC<-A+DPTR
          SJMP rel ;PC<-PC+rel
          ;第一条指令(LJMP LONG J MOVE POSITION)是长转移指令。它的功能是把转移地址addr16送入程序计数器PC,CPU便会无条件转移到addr16处执行程序。由于addr16是16位二进制数,因此,程序可以转移到64KB范围内的任何地址单元去执行(2^16=64K).
          ;第二条指令(AJMP addr11)叫绝对转移指令,因为指令中只提供了低11位的地址。所以程序只能转移到下一条指令开始的2KB范围内执行。AJMP是二字节指令。执行过程为:先进行取指令操作,PC中的内容加一两次。PC+2,形成PC的当前地址;第二步是PC当前值的高五位地址PC.15~PC.11和指令机器码中的低11位地址一起构成16位的转移地址。(+2的步骤不能省)
          ;第三条指令(JMP @A+DPTR)是编制寻址转移指令,为单字节无条件转移指令。在指令执行之前,应该预先把目标地址的基本地址送入DPTR,目标转移地址对基本地址的偏移量放在累加器A中,在指令执行的时候,CPU把DPTR中的基地址和累加器A中的地址偏移量相加,形成目标转移地址送入程序计数器PC.如果结果超过64KB,那么会从最后一位转向零重新开始计数。
          ;第四条指令(SJMP)是短转移指令(short JMP),是无条件相对转移指令。指令的操作数是相对地址。该指令执行后,程序便转移到当前PC值与REL值之和所只是的地址单元。
          

          MCS-51单片机的指令系统中没有停机指令,但在程序中,为了等待中断或者程序结束,需要使程序“原地踏步”,通常可以使用SJMP指令来完成,即反复让CPU执行SJMP指令,这就是动态停机。如果有中断发生,或者CPU复位,就可以脱离该状态。

          SJMP $
          
        • 条件转移指令

          多数情况下,程序的转移是有条件的。根据给定的条件进行检测,若条件得到满足,则程序转向指定的目标地址去执行;否则,不转移,继续往下执行程序。这类条件转移指令都是相对转移指令,其转移的范围是以 转移指令的下一条指令的第一个字节地址为起始地址的-128~127个字节内。

          1. 判0转移指令

            JZ rel ;(J ZERO)
            JNZ rel ;(J NOT ZERO)
            ;上述两条指令都是对累加器A的内容进行检测,根据A中的内容是否为0来决定程序是否转移。指令执行后,A的内容不变。
            
            NO
            YES
            JZ rel
            A=0?
            PC<-PC+2
            PC<-PC+rel
          2. 判CY转移指令

            JC rel ;J CY
            JNC rel ;J NOT CY
            ;这两条指令是以PSW中的进位标志CY作为检测条件,根据CY标志的情况来决定程序是否转移。程序流程与JZ类似
            
          3. 比较转移指令

            CJNE A,direct,rel ;COMPARE J NOT EQUATION 比较A和DIRECT是否相等判断是否转移
            CJNE A,#data,rel
            CJNE Rn,#data,rel
            CJNE @Ri,#data,rel
            ;值得注意的是,CJNE是三字节指令,所以判断为不转移之后,PC<-PC+3.
            ;三字节的相对转移指令的偏移量计算规则如下:
            ;向后转移: 偏移量=目的地址-(源地址+3)
            ;向前转移: 偏移量=(目的地址+0100H)-(源地址+3)
            
          4. 循环转移指令

            DJNZ Rn,rel
            DJNZ direct,rel
            ;在程序设计时,可以设置一个计数器,计数器的值就是要重复执行的次数,每执行一次某段程序,计数器的值减一;若计数器的值不为零,则循环转移继续进行,直到计数器的值减为零为止,循环转移结束。指令执行示意图如下图
            ;注意,在使用DJNZ指令之前,应该将循环次数赋值给计数器,即Rn或(direct)
            ;EG:
            CLR A
            MOV 50H,#64H ;设置循环次数
            L1: INC A
            DJNZ 50H,L1 ;50H不为零则转L1
            
            Rn,rel
            Y
            N
            return
            PC
            DJNZ
            Rn-1->Rn
            Rn=0?
            PC<-PC+2
            PC<-PC+rel
        • 调用子程序以及返回指令

          1. 调用子程序指令

            LCALL addr16  ;PC<-PC+3,SP<-SP+1,(SP)<-PC.7~PC.0  SP<-SP+1,(SP)<-PC.15~PC.8,PC<-addr16
            ACALL addr11  ;PC<-PC+2,SP<-SP+1,(SP)<-PC.7~PC.0  SP<-SP+1,(SP)<-PC.15~PC.8,PC.10~PC.0<-addr11
            ;第一条指令LCALL为长调用指令,addr16是子程序入口地址。执行的时候,先将断口处分成两部分压入堆栈。子程序执行完之后,需要返回到主程序原来的断口地址处。其实也就是说,堆栈起到保存初始地址的作用。
            ;ACALL的执行逻辑和LCALL类似,只不过ACALL只有两个字节大小,同时转移范围只有PC的前11位。
            
          2. 返回指令

            RET  ;PC.15~PC.8<-(SP),SP<-SP-1  PC.7~PC.0<-(SP),SP<-SP-1
            RETI  ;PC.15~PC.8<-(SP),SP<-SP-1  PC.7~PC.0<-(SP),SP<-SP-1
            ;子程序返回指令,功能是将堆栈内的断口地址弹出送入PC,CPU返回到原断口地址处,继续执行原程序。
            ;第二条指令为中断返回指令。这条指令除了执行RET指令的功能之外,还会清除内部相应的中断状态寄存器(该寄存器由CPU相应中断时置位)的内容。所以这条指令只能用于中断服务程序,返回之后原程序不会继续向下运行。
            
          3. 空操作指令

            NOP  ;(NONE POINTER)PC<-PC+1
            ;单字节指令。无任何影响。这条指令通常用于产生一个机器周期的延迟或者在程序中补空,便于程序调试时指令的增删。
            
  5. 位操作类指令

    • 单片机从硬件到软件构成了完整的按位操作的不二处理器,也称为位处理器。在这里面,CPU不是以字节或者字而是以位作为处理对象进行操作的。进行位操作的时候,以进位标志CY作为位累加器,具有一套按位处理指令集,包括数据传送,位逻辑运算和位条件控制转移等指令。

    • MSC-51单片机内部诗句存储器中,有两部分按位寻址的存储地址空间:一部分是片内RAM的20H~2FH共16个字节单元128位,位地址为00H-7FH,各位地址相应于从20H字节单元的最低位开始,到2FH字节单元的最高位;另一部分是特殊功能寄存器区,字节地址能被8整除的专用寄存器也具有位地址,其位地址从80H-F7H.中间有极少数位没有被定义,这部分不能按位寻址。

    • 在汇编语言中,位地址的表达方式有以下几种:

      1. 直接用位地址表示,如

        D4H,2FH

      2. 用点操作符号表示。点操作符前面部分是字节地址或者是可以被位寻址的专用寄存器,后面部分的数字表示它们的位。

        例如:(D0H).4,PSW.4

      3. 寄存器的位定义名称。如:RS1.0V

      4. 用户定义的位符号地址。例如:L1 BIT PSW.4,将PSW.4定义为位符号地址L1之后,允许在指令中使用L1代替PSW.4

    • 位数据传送指令

      MOV C,bit ;CY<-(bit)
      MOV bit,C 
      ;注意的是,其中的一个操作数必须是位累加器CY,另一个操作数可以是任何可以被直接寻址的位
      
    • 位状态修改指令

      CLR C ;清零
      CLR bit
      CPL C ;逻辑取反
      CPL bit
      SETB C ;重置位1
      SETB bit
      
    • 位逻辑运算指令

      ANL C,bit  ;C AND BIT
      ANL C,/bit ;C AND !BIT
      ORL C,bit
      ORL C,/bit
      
    • 位条件转移指令

      JB bit,rel  ;若(bit)=1,则PC<-PC+rel,否则,PC<-PC+3  J BIT
      JNB bit,rel  ;若(bit)=0,则PC<-PC+rel,否则,PC<-PC+3 J NOT BIT
      JBC bit,rel  ;若(bit)=1,则PC<-PC+rel,同时bit清零;否则,PC<-PC+3,bit清零  J B CLR
      

你可能感兴趣的:(51单片机,单片机)