注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
zjjone1023的个人空间 https://home.eeworld.com.cn/space-uid-144059.html [收藏] [复制] [分享] [RSS]
日志

单片机MSC-51学习笔记之2

已有 3620 次阅读2011-5-18 01:14 |

51汇编学习第三章小结

本章重点

MCS-51的寻址方式和寻址空间

       MCS-51的指令分类

       MCS-51指令系统中各指令的执行过程

       MCS-51指领的应用特点

 

一、MCS-51单片机指令系统概述

1、  指令格式

指令操作码用8位二进制数编码,共有255种,指令不同操作码和操作数也不同,有些两者加起来只有一个字节称为单字节指令,有些是操作码和操作数各占一个字节称为双字节指令,有的操作码战一个字节,操作数占两个字节称为3字节指令

A、 单字节指令有的没有指定操作数的指令,如INC DPTR,有的有操作数指令,如MOV A,Rn

B、 双字节指令在程序存储器中占两个字节单元,操作码字节在前,操作数在后,如ADD A,#08H

C、 三字节指令第一个字节为操作码,第二和第三为操作数或者操作数地址如 MOV DPTR,#1234

2、  指令分类

A、 数据传送指令:可用于在单片机CPU内部寄存器、内部RAM、特殊功能寄存器、外部RAMI/O口、程序存储器之间传送数据

B、 算术运算指令:用于两个操作数进行加减乘除等,绝大多数指令要求一个操作数必须存放在累加器A内,而且运算结果仍存回A

C、 逻辑运算和循环移位指令:用于对两个操作希特勒按位进行与、或、异或、取反等操作,大多数也要求把一个操作数和结果放入累加器A

D、位操作指令:可实现位的传送、修改、运算和位控制转移

E、 流程控制类指令:实现无条件转移、条件转移、子程序调用和返回等具体方法就是修改程序计数器PC的值

3、指令系统中使用的符号RnA,B……..

 

51单片机的寻址方式

学习汇编程序设计,要先了解CPU的各种寻址法,才能有效的掌握各个命令的用途,寻址法是命令运算码找操作数的方法。

指令的寻址方式 MOV P1,#0FFH这条指令,第一个词MOV是命令动词,也就是决定做什么事情的,MOV是MOVE少写了一个E,所以就是“传递”,这就是指令,规定做什么事情,数据传递必须要有一个“源”也就是你要送什么数,必须要有一个“目的”,也就是你这个数要送到什么地方去,显然在上面那条指令中,要送的数(源)就是0FFH,而要送达的地方(目的地)就是P1这个寄存器。

寻址方式:指定操作数所在单元的方法。

注意:源操作数、目的操作数都有各自的寻址方式。 掌握指令的7种寻址方式的作用以及不同寻址方式所查询的存储空间及范围,对于常用的指令,能够给出指令的寻址方式。

在我们学习的8051单片机中,有7种寻址方法,下面我们将逐一进行分析。

立即寻址

所要找的操作数是一二进制数或十进制数,出现在指令中,用“#”作前缀
MOV A,#20H
在这种寻址方式中,指令多是双字节的,一般第一个字节是操作码,第二个字节是操作数。该操作数直接参与操作,所以又称立即数,有“#”号表示。立即数就是存放在程序存储器中的常数,换句话说就是操作数(立即数)是包含在指令字节中的。

例如:
MOV  A,#3AH
这条指令的指令代码为74H、3AH,是双字节指令,这条指令的功能是把立即数3AH送入累加器A中。
MOV  DPTR,#8200H
在前面学单片机的专用寄存器时,我们已学过,DPTR是一个16位的寄存器,它由DPH及DPL两个8位的寄存器组成。这条指令的意思就是把立即数的高8位(即82H)送入DPH寄存器,把立即数的低8位(即00H)送入DPL寄存器。
这里也特别说明一下:在80C51单片机的指令系统中,仅有一条指令的操作数是16位的立即数,其功能是向地址指针DPTR传送16位的地址,即把立即数的高8位送入DPH,低8位送入DPL

直接寻址

指令中直接给出操作数的地址。
MOV    A,30H
MOV   30H,DPH


直接寻址方式是指在指令中操作数直接以单元地址的形式给出,也就是在这种寻址方式中,操作数项给出的是参加运算的操作数的地址,而不是操作数

例如:MOV  A,30H 
这条指令中操作数就在30H单元中,也就是30H是操作数的地址,并非操作数。

在80C51单片机中,直接地址只能用来表示特殊功能寄存器、内部数据存储器以及位地址空间,具体的说就是:
1、内部数据存储器RAM低128单元。在指令中是以直接单元地址形式给出。
我们知道低128单元的地址是00H-7FH。在指令中直接以单元地址形式给出这句话的意思就是这0-127共128位的任何一位,例如0位是以00H这个单元地址形式给出、1位就是以01H单元地址给出、127位就是以7FH形式给出。
2、位寻址区。20H-2FH地址单元。
3、特殊功能寄存器。专用寄存器除以单元地址形式给出外,还可以以寄存器符号形式给出。例如下面我们分析的一条指令 MOV  IE,#85H 前面的学习我们已知道,中断允许寄存器IE的地址是80H,那么也就是这条指令可以以MOV  IE,#85H 的形式表述,也可以MOV  80H,#85H的形式表述。

关于数据存储器RAM的内部情况,请查看我们课程的第十二课。

直接寻址是唯一能访问特殊功能寄存器的寻址方式!

大家来分析下面几条指令:
MOV  65H,A       ;将A的内容送入内部RAM的65H单元地址中
MOV  A,direct    ;将直接地址单元的内容送入A中
MOV  direct,direct;将直接地址单元的内容送直接地址单元
MOV  IE,#85H      ;将立即数85H送入中断允许寄存器IE

前面我们已学过,数据前面加了“#”的,表示后面的数是立即数(如#85H,就表示85H就是一个立即数),

数据前面没有加“#”号的,就表示后面的是一个地址地址(如,MOV 65H,A这条指令的65H就是一个单元地址)。

寄存器寻址

操作数存放在工作寄存器R0 ~ R7中,或寄存器B中。
MOV A,R2

寄存器寻址的寻址范围是:
1、4个工作寄存器组共有32个通用寄存器,但在指令中只能使用当前寄存器组(工作寄存器组的选择在前面专用寄存器的学习中,我们已知道,是由程序状态字PSW中的RS1和RS0来确定的),因此在使用前常需要通过对PSW中的RS1、RS0位的状态设置,来进行对当前工作寄存器组的选择。
2、部份专用寄存器。例如,累加器A、通用寄存器B、地址寄存器DPTR和进位位CY。

寄存器寻址方式是指操作数在寄存器中,因此指定了寄存器名称就能得到操作数。
例如:MOV A,R0
这条指令的意思是把寄存器R0的内容传送到累加器A中,操作数就在R0中。
INC R3
这条指令的意思是把寄存器R3中的内容加1

从前面的学习中我产应可以理解到,其实寄存器寻址方式就是对由PSW程序状态字确定的工作寄存器组的R0-R7进行读/写操作

寄存器间接寻址

指令中寄存器的内容作为操作数存放的地址,指令中间接寻址寄存器前用
“@”表示前缀。
举“两个抽屉,两把钥匙”的例子。
MOV R0,#30H
MOV A,@R0
MOV A,#20H
MOV R1,#40H
MOV @R1,A


寄存间接寻址方式是指寄存器中存放的是操作数的地址,即操作数是通过寄存器间接得到的,因此称为寄存器间接寻址。

MCS-51单片机规定工作寄存器的R0、R1做为间接寻址寄存器。用于寻址内部或外部数据存储器的256个单元。为什么会是256个单元呢?我们知道,R0或者R1都是一个8位的寄存器,所以它的寻址空间就是2的八次方=256。
例:MOV  R0,#30H  ;将值30H加载到R0中
    MOV  A,@R0    ;把内部RAM地址30H内的值放到累加器A中
    MOVX A,@R0    ;把外部RAM地址30H内的值放到累加器A中

大家想想,如果用DPTR做为间址寄存器,那么它的寻址范围是多少呢?DPTR是一个16位的寄存器,所以它的寻址范围就是2的十六次方=65536=64K。因用DPTR做为间址寄存器的寻址空间是64K,所以访问片外数据存储器时,我们通常就用DPTR做为间址寄存器。
例:MOV   DPTR,#1234H  ;将DPTR值设为1234H(16位)
    MOVX  A,@DPTR      ;将外部RAM或I/O地址1234H内的值放到累加器A中 

在执行PUSH(压栈)和POP(出栈)指令时,采用堆栈指针SP作寄存器间接寻址。
例:PUSH  30H    ;把内部RAM地址30H内的值放到堆栈区中
堆栈区是由SP寄存器指定的,如果执行上面这条命令前,SP为60H,命令执行后会把内部RAM地址30H内的值放到RAM的61H内。

那么做为寄存器间接寻址用的寄存器主要有哪些呢?我们前面提到的有四个,R0、R1、DPTR、SP

寄存器间接寻址范围总结:
1、内部RAM低128单元。对内部RAM低128单元的间接寻址,应使用R0或R1作间址寄存器,其通用形式为@Ri(i=0或1)。

2、外部RAM 64KB。对外部RAM64KB的间接寻址,应使用@DPTR作间址寻址寄存器,其形式为:@DPTR。
例如MOVX A,@DPTR;其功能是把DPTR指定的外部RAM的单元的内容送入累加器A中。
外部RAM的低256单元是一个特殊的寻址区,除可以用DPTR作间址寄存器寻址外,还可以用R0或R1作间址寄存器寻址。
例如MOVX  A,@R0;这条指令的意思是,把R0指定的外部RAM单元的内容送入累加器A。

堆栈操作指令(PUSH和POP)也应算作是寄存器间接寻址,即以堆栈指针SP作间址寄存器的间接寻址方式。

寄存器间接寻址方式不可以访问特殊功能寄存器!!

寄存器间接寻址也须以寄存器符号的形式表示,为了区别寄存器寻址我寄存器间接寻址的区别,在寄存器间接寻址方式式中,寄存器的名称前面加前缀标志“@”

基址寄存器加变址寄存器的变址寻址

操作数地址 = 变地址 + 基地址
基地址寄存器 DPTR 或 PC
变址寄存器 @A
该寻址方式常用于访问程序存储器,查表。
MOV A,@A + DPTR

这种寻址方式以程序计数器PC或DPTR为基址寄存器,累加器A为变址寄存器,变址寻址时,把两者的内容相加,所得到的结果作为操作数的地址。这种方式常用于访问程序存储器ROM中的数据表格,即查表操作。
变址寻址只能读出程序内存入的值,而不能写入,也就是说变址寻址这种方式只能对程序存储器进行寻址,或者说它是专门针对程序存储器的寻址方式。
例:MOVC  A,@A+DPTR
这条指令的功能是把DPTR和A的内容相加,再把所得到的程序存储器地址单元的内容送A
假若指令执行前A=54H,DPTR=3F21H,则这条指令变址寻址形成的操作数地址就是54H+3F21H=3F75H。如果3F75H单元中的内容是7FH,则执行这条指令后,累加器A中的内容就是7FH。

变址寻址的指令只有三条,分别如下:
JMP    @A+DPTR
MOVC   A,@A+DPTR
MOVC   A,@A+PC

第一条指令JMP @A+DPTR
这是一条无条件转移指令,这条指令的意思就是DPTR加上累加器A的内容做为一个16位的地址,执行JMP这条指令是,程序就转移到A+DPTR指定的地址去执行。

第二、三条指令MOVC   A,@A+DPTR和MOVC   A,@A+PC指令
这两条指令的通常用于查表操作,功能完全一样,但使用起来却有一定的差别,现详细说明如下。
我们知道,PC是程序指针,是十六位的。DPTR是一个16位的数据指针寄存器,按理,它们的寻址范围都应是64K。我们在学习特殊功能寄存器时已知道,程序计数器PC是始终跟踪着程序的执行的。也就是说,PC的值是随程序的执行情况自动改变的,我们不可以随便的给PC赋值。而DPTR是一个数据指针,我们就可以给空上数据指针DPTR进行赋值。我们再看指令MOVC   A,@A+PC这条指令的意思是将PC的值与累加器A的值相加作为一个地址,而PC是固定的,累加器A是一个8位的寄存器,它的寻址范围是256个地址单元。讲到这里,大家应可明白,MOVC   A,@A+PC这条指令的寻址范围其实就是只能在当前指令下256个地址单元。所在,这在我们实际应用中,可能就会有一个问题,如果我们需要查询的数据表在256个地址单元之内,则可以用MOVC   A,@A+PC这条指令进行查表操作,如果超过了256个单元,则不能用这条指令进行查表操作。刚才我们已说到,DPTR是一个数据指针,这个数据指针我们可以给它赋值操作的。通过赋值操作。我们可以使MOVC   A,@A+DPTR这条指令的寻址范围达到64K。这就是这两条指令在实际应用当中要注意的问题

变址寻址方式是MCS-51单片机所独有的一种寻址方式。

位寻址

80C51单片机有位处理功能,可以对数据位进行操作,因此就有相应的位寻址方式。所谓位寻址,就是对内部RAM或可位寻址的特殊功能寄存器SFR内的某个位,直接加以置位为1或复位为0。

位寻址的范围,也就是哪些部份可以进行位寻址:

1、我们在学习51单片机的存储器结构时,我们已知道在单片机的内部数据存储器RAM的低128单元中有一个区域叫位寻址区。它的单元地址是20H-2FH。共有16个单元,一个单元是8位,所以位寻址区共有128位。这128位都单独有一个位地址,其位地址的名字就是00H-7FH
这里就有一个比较麻烦的问题需要大家理解清楚了。我们在前面的学习中00H、01H。。。。7FH等等,所表示的都是一个字节(或者叫单元地址),而在这里,这些数据都变成了位地址。我们在指令中,或者在程序中如何来区分它是一个单元地址还是一个位地址呢?这个问题,也就是我们现在正在研究的位寻址的一个重要问题。其实,区分这些数据是位地址还是单元地址,我们都有相应的指令形式的。这个问题我们在后面的指令系统学习中再加以论述。

2、对专用寄存器位寻址。这里要说明一下,不是所有的专用寄存器都可以位寻址的。具体哪些专用寄存器可以哪些专用寄存器不可以,请大家回头去看看我们前面关于专用寄存器的相关文章。一般来说,地址单元可以被8整除的专用寄存器,通常都可以进行位寻址,当然并不是全部,大家在应用当中应引起注意。

相对寻址

把指令中给定的地址偏移量与本指令所在单元地址(PC内容)相加得到真正有效的操作数所存放的地址。
举“李同学20岁,张同学比李同学大3岁”的例子。
JC 60H ;设(PC) = 2000H,
则当C = 1时,
转移的目的地址 = (PC)+ 2 + 60H

专用寄存器的位寻址表示方法:

下面我们以程序状态字PSW来进行说明

 

 

D7

D6

D5

D4

D3

D2

D1

D0

CY  

AC

F0

RS1

RS0

OV

 

P

1、直接使用位地址表示:看上表,PSW的第五位地址是D5,所以可以表示为D5H
   MOV  C,D5H

2、位名称表示:表示该位的名称,例如PSW的位5是F0,所以可以用F0表示
   MOV  C,F0

3、单元(字节)地址加位表示:D0H单元位5,表示为DOH.5

   MOV  C,D0H.5

4、专用寄存器符号加位表示:例如PSW.5

   MOV C,PSW.5

这四种方法实现的功能都是相同的,只是表述的方式不同而已。

 

例题:

  1. 说明下列指令中源操作数采用的寻址方式。

  MOV R5,R7 答案:寄存器寻址方式

  MOV A,55H 直接寻址方式

  MOV A,#55H 立即寻址方式

  JMP @A+DPTR 变址寻址方式

  MOV 30H,C 位寻址方式

  MOV A,@R0 间接寻址方式

  MOVX A,@R0 间接寻址方式

改错题

  请判断下列的MCS-51单片机指令的书写格式是否有错,若有,请说明错误原因。

  MOV R0,@R3 答案: 间址寄存器不能使用R2~R7。

  MOVC A,@R0+DPTR 变址寻址方式中的间址寄存器不可使用R0,只可使用A。

  ADD R0,R1 运算指令中目的操作数必须为累加器A,不可为R0。

  MUL AR0 乘法指令中的乘数应在B寄存器中,即乘法指令只可使AB寄存器组合。

 

 

三、数据传送指令

以实现把源操作数复制到目的地址的操作,如果要保留目的地址中操作数(目的操作数),可以使用数据交换指令

1、  内部数据传送指令:实现内部寄存器、RAM、特殊功能寄存器之间的数据传送,用MOV

A、 A为目的操作数的8位传送指令

MOV      A,#data

MOV      A,direct

MOV      A,Rn

MOV      A,@Ri

B、 direct为目的操作数的8位传送指令

MOV      direct,A

MOV      direct, #data

MOV      direct1 direct2

MOV      direct,Rn

MOV      direct,Ri

C、 Rn为目的操作数的8位传送指令,不能从一个寄存器传到另一个寄存器

MOV      Rn,A

MOV      Rn, #data

MOV      Rn, direct

D、@Ri的操作数的8位传送指令

MOV      @RiA

MOV      @Ri,#data

MOV      @Ri,direct

       E16位数据传送指令作用把16位立即数装入数据指针DPTR,高8位(指令的第二

              个字节)送入DPTR的高8PDH,低8位送入DPTR的低8PDL

              MOV     DPTR,#data16

2、  外部数据传送指令:在CPU与外部数据存储器或外部I/O口之间传送数据,每次传送一个字节,该操作只能使用累加器A来实现,

A、将外部数据送到累加器

      MOVX     A,@Ri

MOVX     A,@DPTR

       B、将累加器内容送入外部

      MOVX     @RiA

MOVX     @DPTR A

       C、查表指令用于读取程序存储器的内容,或者在程序存储器中存储的固定表格中查找

      一项

              MOVC      A,@A+DPTR

              MOVC      A,@A+PC

       D、堆栈操作指令:当通过子程序调用、返回等指令使程序的执行流程发生改变时,通

          常使用堆栈保存返回地址

              PUSH    direct

              POP      direct

F、 数据交换指令用以完成累加器与工作寄存器、内部RAM单元、特殊功能寄存器内容全部或部分互换

字节交换:将累加器A内容与源操作数互换

XCH       A,direct

XCH       A,Rn

XCH          A,@Ri

半字节交换将累加器A的低4位与由Ri内容指定的内部RAM单元的低4位互换,高4位不变

XCHD     A,@Ri

       练习:假设在内部RAM地址20H处存放着一个BCD25,编写程序将它转换ASCII码表示,存储在内部RAM地址30H开始的两个单元中

              BCD25H其实表示十进制数25,用ASCII表示时,应转换成字符“2”、“5”的ASCII32H35H

              MOV   R0,#20H           ; R0内容为25H存放位置

              MOV   R1#30H           R1内容为转换后ASCII码存放位置

              MOV   @R1,#30H         ASCII存放外,先初始化为30H

              MOV   A,@R0            A25H

              XCHD  A,@R1            A30H互换低4位内容,A20H30H内容为35H

              SWAP   A                A高低4位互换,为02H

              INC    R1                R131H

              MOV   @R1,#30H         ;初始化为30H

              XHCD  A,@R1            A31H互换低4位内容,A00H30H内容为32H

问题1、指令的范围,

       2、操作数和地址的区分

                             算术运算类指令分析

算术运算指令共有24条,算术运算主要是执行加、减、乘、除法四则运算。另外MCS-51指令系统中有相当一部分是进行加、减1操作,BCD码的运算和调整,我们都归类为运算指令。虽然MCS-51单片机的算术逻辑单元ALU仅能对8位无符号整数进行运算,但利用进位标志C,则可进行多字节无符号整数的运算。同时利用溢出标志,还可以对带符号数进行补码运算。需要指出的是,除加、减1指令外,这类指令大多数都会对PSW(程序状态字)有影响。这在使用中应特别注意。

[1]. 加法指令(4条)
这4条指令的作用是把立即数,直接地址、工作寄存器及间接地址内容与累加器A的内容相加,运算结果存在A中。

ADD  A,#data   ;(A)+#data→(A) 累加器A中的内容与立即数#data相加,结果存在A中
ADD  A,data    ;(A)+(data)→(A) 累加器A中的内容与直接地址单元中的内容相加,结果存在A中
ADD  A,Rn     ;(A)+(Rn)→(A) 累加器A中的内容与工作寄存器Rn中的内容相加,结果存在A中
ADD  A,@Ri    ;(A)+((Ri))→(A) 累加器A中的内容与工作寄存器Ri所指向地址单元中的内容相加,结果存在A中

这些指令所用到的源操作数都是累加器ACC,目的操作数则根据自已的需要来选择。

上述这四条指令的用途是:将A中的值与后面的值相加,最终结果存回到累加器A中。
例:MOV  A,#30H
    ADD  A,#10H
则执行完本条指令后,A中的值就是40H
下面的题目请大家自行练习
    MOV  34H,#10H
    MOV  R0,#13H
    MOV  A,34H
    ADD  A,R0
    MOV  R1,#34H
    ADD  A,@R1

练习题说明:
MOV 34H,#10H
这条指令的目的是将立即数10H送入34H这个存储单元
MOV R0,#13H
这条指令的目的是将立即数13H送入R0这个寄存器
MOV A,34H
这条指令大家要特别注意了,这条指令的源操作数在哪里呢?它的源操作数是在34H这个存储单元里,也就是34H是个存储单元,而不是一个数
这条指令用的是直接寻址,大前看前面的指令,第一条指令将10H这个立即数送入了34H这个存储单元。那么,也就是34H中存储着10H这么一个常数。
执行MOV  A,34H单元后,累加器A中的值是多少呢?前面说了34H存储单元中的值是10H,所以这时累加器的值就是10H。
ADD A,R0
这条指令其实就是把前面三条指令的数据求个总和。第二条指令MOV  R0,#13H执行完后。R0寄存器里的值是13H。第三条指令MOV A,34H执行完后,累加器的值是10H。
这条指令的意思就是把R0寄存器中的值(13H)与累加器A中的值(10H)相加,其结果是(23H)送入累加器A。
MOV R1,#34H
这条指令是将常数34H送入寄存器R1,执行完这条指令后,R1寄存器中的值是34H
ADD A,@R1
这个时候求和,大家请注意了。这条指令是寄存器间接寻址方式。前面我们已知道,累加器中的值是23H,MOV  R1,#34H执行完后,R1寄存器的值是34H。大家注意,在间接寻址方式MOV  A,@Ri(Ri为R0或R1,在这条指令中用的是R1)中。R1内的值指的就不是一个常数了,而是一个直接地址。这条指令的意思就是把寄存器R1中存储的34H存储单元的内容(10H)与累加器中的内容(23H)相加,其结果为33H。

根据前面我们用的MedWin仿真软件大家进行模拟仿真,同时打开DATA窗口及寄存器窗口观察程序执行时内部寄存器及数据区的变化情况。软件使用如有不凝问,请到我们论坛提出。我们会尽力为大家解答。

[2]. 带进位加法指令(4条)
这4条指令除与[1]功能相同外,在进行加法运算时还需考虑进位问题。

ADDC    A,data    ;(A)+(data)+(C)→(A) 累加器A中的内容与直接地址单元的内容连同进位位相加,结果存在A中

ADDC    A,#data   ;(A)+#data +(C)→(A) 累加器A中的内容与立即数连同进位位相加,结果存在A中
ADDC    A,Rn      ;(A)+Rn+(C)→(A) 累加器A中的内容与工作寄存器Rn中的内容、连同进位位相加,结果存在A中
ADDC    A,@Ri     ;(A)+((Ri))+(C)→(A) 累加器A中的内容与工作寄存器Ri指向地址单元中的内容、连同进位位相加,结果存在A中

 

用途:将A中的值和其后面的值相加,并且加上进位位C中的值。
说明:由于51单片机是一种8位机,所以只能做8位的数学运算,但8位的运算范围只有0-255,这在实际工作中是不够的,因此就要进行扩展,一般是将2个8位的数学运算合起来,成为一个16位的运算,这样,可以表达的数的范围就可以到达0-65535。如何合并呢?其实很简单,让我们看一个十进制数的例子吧:
66+78
这两个数相加,我们根本不在意这个过程,但事实上我们是这样做的:先做6+8(低位),然后再做6+7,这是高位。做了两次加法,只是我们做的时候并没有刻意分成两次加法来做罢了,或者说我们并没有意识到我们做了两次加法。之所以要分成两次来做,是因为这两个数超过了一位数所能表达的范围(0-9)。
在做低位时产生了进位,我们做的时候是在适当的位置点一下,然后在做高位加法时将这一点加进去。那么计算机中做16位加法时同样如此,先做低8位的,如果两数相加后产生了进位,也要“点一下”做个标记,这个标记就职进位位C,在程序状态字PSW中。在进行高位加法是将这个C加进去。
例如:1067H+10A0H,先做67H+A0H=107H,而107H显然超过了0FFH,因此,最终保存在A中的数是7,而1则到了PSW中的CY位了,换言之,CY就相当于100H。然后再做10H+10H+CY,结果是21H,所以最终的结果是2107H。

[3]. 带借位减法指令(4条)
这组指令包含立即数、直接地址、间接地址及工作寄存器与累加器A连同借位位C内容相减,结果送回累加器A中。
这里我们对借位位C的状态作出说明,在进行减法运算中,CY=1表示有借位,CY=0则无借位。OV=1声明带符号数相减时,从一个正数减去一个负数结果为负数,或者从一个负数中减去一个正数结果为正数的错误情况。在进行减法运算前,如果不知道借位标志位C的状态,则应先对CY进行清零操作。


SUBB  A,data      ;(A)-(data) - (C)→(A) 累加器A中的内容与直接地址单元中的内容、连同借位位相减,结果存在A中
SUBB  A,#data     ;(A)-#data -(C)→(A) 累加器A中的内容与立即数、连同借位位相减,结果存在A中
SUBB  A,Rn       ;(A)-(Rn) -(C)→(A) 累加器A中的内容与工作寄存器中的内容、连同借位位相减,结果存在A中
SUBB  A,@Ri      ;(A)-((Ri)) -(C)→(A) 累加器A中的内容与工作寄存器Ri指向的地址单元中的内容、连同借位位相减,结果存在A中

[4]. 乘法指令(1条)
这个指令的作用是把累加器A和寄存器B中的8位无符号数相乘,所得到的是16位乘积,这个结果低8位存在累加器A,而高8位存在寄存器B中。如果OV=1,说明乘积大于0FFFFH(65536),否则OV=0,但进位标志位CY总是等于0。

MUL  AB       ;(A)×(B)→(A)和(B) 累加器A中的内容与寄存器B中的内容相乘,结果存在A、B中

例:(A)=4EH,(B)=5DH,执行指令
    MUL  AB后,乘积是1C56H,所以在B中放的是1CH,而A中放的则是56H。

[5].  除法指令(1条)
这个指令的作用是把累加器A的8位无符号整数除以寄存器B中的8位无符号整数,所得到的商存在累加器A,而余数存在寄存器B中。除法运算总是使OV和进位标志位CY等于0。如果OV=1,表明寄存器B中的内容为00H,那么执行结果为不确定值,表示除法有溢出。

DIV  AB       ;(A)÷(B)→(A)和(B) 累加器A中的内容除以寄存器B中的内容,所得到的商存在累加器A,而余数存在寄存器B中。

 


例如:13/5,其商是2,余数是3。除了以后,商会放在A中,余数放在B中,CU和OV都是0。如果在做除法前B中的值是00H,也就是除数为0,那么OV=1。

[6]. 加1指令(5条)
这5条指令的的功能均为原寄存器的内容加1,结果送回原寄存器。上述提到,加1指令不会对任何标志有影响,如果原寄存器的内容为FFH,执行加1后,结果就会是00H。这组指令共有直接、寄存器、寄存器减间址等寻址方式:

INC  A          ;(A)+1→(A) 累加器A中的内容加1,结果存在A中
INC  data       ;(data)+1→(data) 直接地址单元中的内容加1,结果送回原地址单元中
INC  @Ri       ;((Ri))+1→((Ri)) 寄存器的内容指向的地址单元中的内容加1,结果送回原地址单元中
INC  Rn         ;(Rn)+1→(Rn)寄存器Rn的内容加1,结果送回原地址单元中
INC  DPTR      ;(DPTR)+1→(DPTR)数据指针的内容加1,结果送回数据指针中

用途很简单,就是将后面目标中的值加1。
例:(A)=12H,(R0)=33H,(21H)=32H,(34H)=22H,DPTR=1234H。执行下面的指令;
INC  A   ;(A)=13H
INC  R0  ;(R0)=34H
INC  21H ;(21H)=33H
INC  @R0 ;(34H)=23H
INC  DPTR;(DPTR)=1235H
这些指令执行后的结果都附在了指令的后面。
说明:从结果上看,INC  A和ADD A,#1差不多,但INC  A是单字节,单周期指令,而ADD  A,#1则是双字节双周期指令,而且INC  A不会影响PSW位,如(A)=0FFH,INC  A后(A)=00H,而CY依然保持不变。如果是ADD A,#1,则(A)=00H,而CY一定是1。因此加1指令并不适合做加法运算,事实上它主要是用来做计数、地址增加等用途。另外,加法类指令都是以A为核心的,其中一个数必须放在A中,而运算结果也必须放在A中,而加1类指令的对象则广泛得多,可以是寄存器、内存地址、间址寻址的地址等等。

在INC  data这条指令中,如果直接地址是I/O,其功能是先读入I/O锁存器的内容,然后在CPU进行加1操作,再输出到I/O上,这就是“读—修改—写”操作。

[7].  减1指令(4条)
这组指令的作用是把所指的寄存器内容减1,结果送回原寄存器,若原寄存器的内容为00H,减1后即为FFH,运算结果不影响任何标志位,这组指令共有直接、寄存器、寄存器间址等寻址方式,当直接地址是I/O口锁存器时,“读—修改—写”操作与加1指令类似。

DEC  A         ;(A)-1→(A)累加器A中的内容减1,结果送回累加器A中
DEC  data      ;(data)-1→(data)直接地址单元中的内容减1,结果送回直接地址单元中
DEC  @Ri      ;((Ri))-1→((Ri))寄存器Ri指向的地址单元中的内容减1,结果送回原地址单元中

DEC  Rn      ;(Rn)-1→(Rn)寄存器Rn中的内容减1,结果送回寄存器Rn中

[8]. 十进制调整指令(1条)
在进行BCD码运算时,这条指令总是跟在ADD或ADDC指令之后,其功能是将执行加法运算后存于累加器A中的结果进行调整和修正。

DA      A

综合练习:
   MOV   A,#12H

MOV   R0,#24H
   MOV   21H,#56H
   ADD   A,#12H
   MOV   DPTR,#1234H
   ADD   A,DPH
   ADD   A,R0
   CLR   C
   SUBB  A,DPL
   SUBB  A,#25H
   INC   A
   SETB  C
   ADDC  A,21H
   INC   R0
   SUBB  A,R0
   MOV   24H,#16H
   CLR   C
   ADD   A,@R0
先写出每步运行结果,然后将以上题目键入,并在软件仿真中运行,观察寄存器及有关单元的内容的变化。

逻辑运算及移位指令分析

逻辑运算和移位指令共有25条,有与、或、异或、求反、左右移位、清0等逻辑操作,有直接、寄存器和寄存器间址等寻址方式。这类指令一般不影响程序状态字(PSW)标志。

[1]. 循环移位指令(4条)
这4条指令的作用是将累加器中的内容循环左或右移一位,后两条指令是连同进位位CY一起移位。

RL  A     ;累加器A中的内容左移一位
RR  A     ;累加器A中的内容右移一位
RLC  A    ;累加器A中的内容连同进位位CY左移一位
RRC  A
   ;累加器A中的内容连同进位位CY右移一位

[2]. 累加器半字节交换指令(1条)
这条指令是将累加器中的内容高低半字节互换,这在上一节中内容已有介绍。

SWAP  A  ; 累加器中的内容高低半字节互换

[3]. 求反指令(1条)
这条指令将累加器中的内容按位取反。

CPL  A    ; 累加器中的内容按位取反

[4]. 清零指令(1条)
这条指令将累加器中的内容清0。

CLR  A    ; 0→(A),累加器中的内容清0

[5].  逻辑与操作指令(6条)
    这组指令的作用是将两个单元中的内容执行逻辑与操作。如果直接地址是I/O地址,则为“读—修改—写”操作。

ANL  A,data    ;累加器A中的内容和直接地址单元中的内容执行与逻辑操作。结果存在寄存器A中。
ANL  data,#data  ;直接地址单元中的内容和立即数执行与逻辑操作。结果存在直接地址单元中。
ANL  A,#data   ;累加器A的内容和立即数执行与逻辑操作。结果存在累加器A中。
ANL  A,Rn      ;累加器A的内容和寄存器Rn中的内容执行与逻辑操作。结果存在累加器A中。
ANL  data,A    ;直接地址单元中的内容和累加器A的内容执行与逻辑操作。结果存在直接地址单元中。
ANL  A,@Ri    ;累加器A的内容和工作寄存器Ri指向的地址单元中的内容执行与逻辑操作。结果存在累加器A中。

[6].  逻辑或操作指令(6条)
这组指令的作用是将两个单元中的内容执行逻辑或操作。如果直接地址是I/O地址,则为“读—修改—写”操作。

ORL  A,data    ;累加器A中的内容和直接地址单元中的内容执行逻辑或操作。结果存在寄存器A中。
ORL  data,#data  ;直接地址单元中的内容和立即数执行逻辑或操作。结果存在直接地址单元中。
ORL  A,#data   ;累加器A的内容和立即数执行逻辑或操作。结果存在累加器A中。
ORL  A,Rn      ;累加器A的内容和寄存器Rn中的内容执行逻辑或操作。结果存在累加器A中。
ORL  data,A    ;直接地址单元中的内容和累加器A的内容执行逻辑或操作。结果存在直接地址单元中。
ORL  A,@Ri    ;累加器A的内容和工作寄存器Ri指向的地址单元中的内容执行逻辑或操作。结果存在累加器A中。

[7].  逻辑异或操作指令(6条)
这组指令的作用是将两个单元中的内容执行逻辑异或操作。如果直接地址是I/O地址,则为“读—修改—写”操作。

XRL  A,data    ;累加器A中的内容和直接地址单元中的内容执行逻辑异或操作。结果存在寄存器A中。
XRL  data,#data  ;直接地址单元中的内容和立即数执行逻辑异或操作。结果存在直接地址单元中。
XRL  A,#data   ;累加器A的内容和立即数执行逻辑异或操作。结果存在累加器A中。
XRL  A,Rn      ;累加器A的内容和寄存器Rn中的内容执行逻辑异或操作。结果存在累加器A中。

XRL  data,A    ;直接地址单元中的内容和累加器A的内容执行逻辑异或操作。结果存在直接地址单元中。
XRL  A,@Ri    ;累加器A的内容和工作寄存器Ri指向的地址单元中的内容执行逻辑异或操作。结果存在累加器A中

控制转移类指令分析

控制转移指令用于控制程序的流向,所控制的范围即为程序存储器区间,MCS-51系列单片机的控制转移指令相对丰富,有可对64kB程序空间地址单元进行访问的长调用、长转移指令,也有可对2kB字节进行访问的绝对调用和绝对转移指令,还有在一页范围内短相对转移及其它无条件转移指令,这些指令的执行一般都不会对标志位有影响。

[1]. 无条件转移指令(4条)
这组指令执行完后,程序就会无条件转移到指令所指向的地址上去。长转移指令访问的程序存储器空间为16地址64kB,绝对转移指令访问的程序存储器空间为11位地址2kB空间。

LJMP  addr16     ;addr16→(PC),给程序计数器赋予新值(16位地址)

AJMP  addr11     ;(PC)+2→(PC),addr11→(PC10-0)程序计数器赋予新值(11位地址),(PC15-11)不改变

SJMP  rel         ;(PC)+ 2 + rel→(PC)当前程序计数器先加上2再加上偏移量给程序计数器赋予新值

JMP  @A+DPTR   ;(A)+ (DPTR)→(PC),累加器所指向地址单元的值加上数据指针的值给程序计数器赋予新值

这几条指令,如果要他细分析的话,区别较大,但初学者时,可以不理会那么多,统统理解成LJMP标号,也就是跳转到一个标号处,但事实上,JMP标号,在前面的例程中我们已接触过,并且也知道如何来使用了,AJMP和SJMP也是一样,那么这几条指令它们的区别何在呢?在于跳转的范围不一样。好比跳远,LJMP一下就能跳64K那么远(当然近了就更没关系了)。而AJMP最多只能跳2K距离,而SJMP则最多只能跳256这么远,原则上,所有用AJMP或SJMP的地方都可以用LJMP来替代。因此在初学者时,需要跳转时可以全用LJMP。

但是在查表时要注意会出错,因为他们的机器周期不一样,取得的数也不一样。

[2]. 条件转移指令(8条)
条件转移指令是指在满足一定条件时进行相对转移

JZ  rel               ; A=0,(PC)+ 2 + rel→(PC),累加器中的内容为0,则转移到偏移量所指向的地址,否则程序往下执行

JNZ  rel              ; A≠0,(PC)+ 2 + rel→(PC),累加器中的内容不为0,则转移到偏移量所指向的地址,否则程序往下执行

这两条指令是判断A内容是否为0转移指令
第一条指令的功能是:如果(A)=0,则转移,否则顺序执行(执行本指令的下一条指令)。转移到什么地方去呢?如果按照传统的方法,就要算偏移量,很麻烦,好在现在我们可以借助机器汇编了,因此这条指令我们可以这样理解:
JB  标号
即转移到标号处,下面举一例说明:
   MOV  A,R0
   JZ   L1
   MOV  R1,#00H
   AJMP L2
L1:MOV  R1,#0FFH
L2:SJMP L2
   END
在执行上面这段程序前,如果R0中的值是0的话,就转移到L1执行,因此最终的执行结果是R1中的值为0FFH。而如果R0中的值不等于0,则顺序执行,也就是执行MOV  R1,#00H指令。最终的执行结果是R1中的值等于0。
第一条指令的功能清楚了,第二条当然就好理解了,如果A中的值不等于0,就转移。把上面的例子中的JZ改成JNZ试试看,程序执行的结果是怎样的?

CJNE  A, data, rel     ; A≠(data),(PC)+ 3 + rel→(PC),累加器中的内容不等于直接地址单元的内容,则转移到偏移量所指向的地址,否则程序往下执行

CJNE  A, #data, rel    ; A≠#data,(PC)+ 3 + rel→(PC),累加器中的内容不等于立即数,则转移到偏移量所指向的地址,否则程序往下执行

CJNE  Rn, #data, rel  ; A≠#data,(PC)+ 3 + rel→(PC),工作寄存器Rn中的内容不等于立即数,则转移到偏移量所指向的地址,否则程序往下执行

CJNE  @Ri, #data, rel ; A≠#data,(PC)+ 3 + rel→(PC),工作寄存器Ri指向地址单元中的内容不等于立即数,则转移到偏移量所指向的地址,否则程序往下执行

 

第一条指令的功能是将A中的值和立即数data比较,如果两者相等,就顺序执行(执行程序的下一条指令),如果不相等,就转移,同样的,我们可以将rel理解成标号。即CJNE  A,#data,标号。这样利用这条指令,我们就可以判断两数是否相等,这在很多场合是非常有用的。但有时还想得知两数比较后哪个大,哪个小。本条指令也具有这样的功能,如果两数不相等,则CPU还会反映出哪个数大,哪个数小,这是用CY(进位位)来实现的。如果前面的数(A中的)大,则CY=0,否则CY=1,因此在程序转移后再次利用CY就可判断出A中的数比data大还是小了。
例:
   MOV  A,R0
   CJNE A,#10H,L1
   MOV  R1,#0FFH
   AJMP L3
L1:JC   L2
   MOV  R1,#0AAH
   AJMP L3
L2:MOV  R1,#0FFH
L3:SJMP L3
上面的程序中有一条指令我们还没学过,即JC,这条指令的原型是JC  rel,作用我上面的JZ类似,但是它是判断CY是0,还是1进行转移,如果CY=1,则转移到JC后面的标号处执行,如果CY=0则顺序执行(执行它的下面的一条指令)。
分析一下上面的程序,如果(A)=10H,则顺序执行,即R1=0。如果(A)不等于10H,则转到L1处继续执行,在L1处,再次进行判断,如果(A)大于10H,则CY=1,将顺序执行,即MOV  R1,#0AAH指令,而如果(A)小于10H,则将转移到L2处运行,即执行MOV  R1,#0FFH指令。
因此最终结果是:本程序执行前,如果(R0)=10H,则(R1)=00H,如果(R0)大于10H,则(R1)=0AAH,如果(R0)小于10H,则(R1)=0FFH。
弄懂了这条指令,其它的几条就类似了,第二条是把A当中的值和直接地址的中的值比较,第三条则是将直接地址中的值和立即数比较,第四条是将间址寻址得到的数和立即数比较,这里就不详谈了,下面给出几个相应的例子。
CJNE  A,10H   ;把A中的值和10H中的值比较(注意和前面题目的区别)
CJNE  10H,#35H;把10H中的值和35H中的值比较
CJNE  @R0,#35H;把R0中的值作为地址,从此地址中取数并和35H比较。

DJNZ  Rn, rel ; (Rn)-1→(Rn),(Rn)≠0,(PC)+ 2 + rel→(PC)工作寄存器Rn减1不等于0,则转移到偏移量所指向的地址,否则程序往下执行

DJNZ  data, rel ; (Rn)-1→(Rn),(Rn)≠0,(PC)+ 2 + rel→(PC)直接地址单元中的内容减1不等于0,则转移到偏移量所指向的地址,否则程序往下执行

这两条指令在前面我们已有提到,这里就不多说了。

[3]. 子程序调用指令(1条)
子程序是为了便于程序编写,减少那些需反复执行的程序占用多余的地址空间而引入的程序分支,从而有了主程序和子程序的概念,需要反复执行的一些程序,我们在编程时一般都把它们编写成子程序,当需要用它们时,就用一个调用命令使程序按调用的地址去执行,这就需要子程序的调用指令和返回指令。

LCALL  addr16 ; 长调用指令,可在64kB空间调用子程序。此时(PC)+ 3→(PC),(SP)+ 1→(SP),(PC7-0)→(SP),(SP)+ 1→(SP),(PC15-8)→(SP),addr16→(PC),即分别从堆栈中弹出调用子程序时压入的返回地址

ACALL  addr11 ; 绝对调用指令,可在2kB空间调用子程序,此时(PC)+ 2→(PC),(SP)+ 1→(SP),(PC7-0)→(SP),(SP)+ 1→(SP),(PC

15-8)→(SP),addr11→(PC10-0

 

上面这两条指令就是在主程序中调用子程序的。

RET  ; 子程序返回指令。此时(SP)→(PC15-8),(SP)- 1→(SP),(SP)→(PC7-0),(SP)- 1→(SP)

子程序返回指令
子程序执行完后必须回到主程序,如何返回呢?只要执行一条返回指令就可以了,即执行RET。


RETI  ; 中断返回指令,除具有RET功能外,还具有恢复中断逻辑的功能,需注意的是,RETI指令不能用RET代替

[4]. 空操作指令(1条)
所谓空操作,就是什么也不做,停一个周期,一般用作短时间的延时。

NOP     ; 这条指令除了使PC加1,消耗一个机器周期外,没有执行任何操作。可用于短时间的延时

 

布尔变量操作指令分析

布尔处理功能是MCS-51系列单片机的一个重要特征,这是出于实际应用需要而设置的。布尔变量也即开关变量,它是以位(bit)为单位进行操作的。

    在物理结构上,MCS-51单片机有一个布尔处理机,它以进位标志做为累加位,以内部RAM可寻址的128个为存储位。

   既然有布尔处理机功能,所以也就有相应的布尔操作指令集,下面我们分别谈论。

[1]. 位传送指令(2条)
    位传送指令就是可寻址位与累加位CY之间的传送,指令有两条。

        MOV  C,bit        ;bit→CY,某位数据送CY

        MOV  bit,C        ;CY→bit,CY数据送某位

[2]. 位置位复位指令(4条)
    这些指令对CY及可寻址位进行置位或复位操作,共有四条指令。

        CLR  C           ; 0→CY,清CY

        CLR  bit          ; 0→bit,清某一位

        SETB  C          ; 1→CY,置位CY

        SETB  bit         ; 1→bit,置位某一位

[3]. 位运算指令(6条)
    位运算都是逻辑运算,有与、或、非三种指令,共六条。

        ANL  C,bit        ;(CY)∧(bit)→CY

        ANL  C,/bit        ;(CY)∧()→CY

        ORL  C,bit        ;(CY)∨(bit)→CY

        ORL  C,/bit        ;(CY)∧()→CY

        CPL  C           ;()→CY

        CPL  bit          ;()→bir

[4]. 位控制转移指令(5)
    位控制转移指令是以位的状态作为实现程序转移的判断条件,介绍如下:

        JC  rel            ; (CY)=1转移,(PC)+2+rel→PC,否则程序往下执行,(PC)+2→PC。

        JNC  rel          ; (CY)=0转移,(PC)+2+rel→PC,否则程序往下执行,(PC)+2→PC。

        JB  bit, rel        ; 位状态为1转移。

        JNB  bit, rel       ; 位状态为0转移。

JBC  bit, rel       ; 位状态为1转移,并使该位清“0”。

    后三条指令都是三字节指令,如果条件满足,(PC)+3+rel→PC,否则程序往下执行,(PC)+3→PC。

 

这章内容应该说是汇编的重点,也是汇编的基础,所以看了书和网上找了很多资料看,觉得这个解释是最清楚的最容易理解的

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章