小吴学汇编之第二章--寄存器(2)

2.3          几条汇编指令

         前面我们说过,汇编指令通过控制CPU进行工作,那么下表是几条汇编指令。

小吴学汇编之第二章--寄存器(2)

         注意,为了使具有高级语言基础的读者更好理解指令的含义,有时会用文字描述和高级语言描述这两种方式来描述一条汇编指令的含义。在写一条汇编指令或一个寄存器的名称时不区分大小。如:mov ax,18和MOV AX,18的含义相同。

         接下来看一下CPU执行下表中的程序段的每条指令后,对寄存器中的数据进行的改变。

         注意:AX与BX初始值分别为,AX中的值:0000H        BX中的值:0000H

小吴学汇编之第二章--寄存器(2)

小吴学汇编之第二章--寄存器(2)

         其实结合上面两个表,我们可以清楚了解到MOV与ADD指令的作用。MOV就相当于C语言中的对一个变量进行赋值的操作,例如:int ax = 18。ADD相当于C语言中的+=运算,例如: int ax += bx。这么解释,大家都理解吧。

         那么假如在上表中,我们执行这么一条指令:ADD AX,BX,运算后,AX的值是多少?相信不少人认为是1044CH,其实这也是对的,但是在这里是错的。因为我们前面说过,AX寄存器是16位寄存器,只能存放4位十六进制的数据,最大能保存的数据是FFFFH,所以在这里,最高位的1不能保存在AX中。所以最终的结果为:044CH。

         我们再来看一个表

小吴学汇编之第二章--寄存器(2)

         在这里,如果有认真看小吴的笔记,就会知道AL,AH,BL,BH其实就是小吴前面说过的AX16位寄存器中的高8位AH和低8位AL。有人会对ADD AL,BL的运算有疑惑,在这里小吴给大家解释一下。

AX中的数据存放如下表:

0

0

0

0

0

0

0

0

0

0

0

1

1

0

1

0

MSB:15                                                                                                                                              LSB:0

         从上表,我们可以看出,AH中的值为00H,AL中的值为1AH。

BX中的数据存放如下表:

0

0

0

0

0

0

0

0

0

0

0

1

0

1

1

0

MSB:15                                                                                                                                                  LSB:0

         从上表我们我们可以看出,BH中的值为00H,BL中的值为26H。

注意:MSB:15,表示的是寄存器中第16位,LSB:0表示寄存器中第0位。以后都不写了,大家都能懂。

         AL的数据位1AH,BL的数据位26H,1AH + 26H =?,这里涉及到十六进制的运算。我们都知道,二进制逢二进一,八进制逢八进一,以此类推,十六进制逢十六进一。首先我们先算A + 6 =16,在进行 16-16(这个16是十六进制的意思)=0。然后1 + 2 + 1(刚进1)=4。所以经过指令ADD AL,BL后,AL中的数据位40H。后面运算一样,就不多做解释了。

         在执行数据传送或运算的时候,要注意指令的两个操作对象的位数应当一致的。例如:

         MOV AX,BX

         MOV BX,CX

         MOV,AH,BL

         ADD AX,20000

这些操作是正确的,而:

         MOV AX,BL      //在8位寄存器和16位寄存器之间传送数据

         MOV AL,20000        //超过8位寄存器的最大数值255

2.4          地址

         前面介绍到,CPU访问内存单元时,要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,我们将这个唯一的地址称为物理地址。

         CPU通过地址总线送入寄存器的,必须是一个内存单元的物理地址。在CPU向地址总线上发出物理地址之前,必须要在内部先形成这个物理地址。不同的CPU可以有不同的形成物理地址的方法。我们现在讨论的是前面介绍的8086CPU是如何在内部形成内存单元的物理地址的。

2.5          16位结构的CPU

         8086CPU是一款16位结构的CPU。简单地讲,16位结构描述了这么几方面的特性:

  1. 运算器一次最多可以处理16位的数据
  2. 寄存器的最大宽度为16位
  3. 寄存器和运算器之间的通路为16位

8086是16位结构的CPU,也就是说,在其内部,能够一次性处理、传输、暂时存储的信息的最大长度是16位。内存单元的地址在送上地址总线之前,必须在CPU中处理、传输、暂时存放,对于16位CPU,能一次性处理、传输、暂时存储16位的地址。

2.6          8086CPU给出物理地址的方法

         8086CPU有20位地址总线,可以传送20位地址,达到1MB寻址能力。8086CPU又是16位结构,在内部一次性处理、传输、暂时存储的地址为16位。从8086CPU的内部结构来看,如果将地址从内部简单地出发,那么只能送出16位的地址,表现出来的寻址能力只有64KB。

         8086CPU采用一种在内部使用两个16位地址合成的方法来形成一个20位的物理地址。其相关部件的逻辑结构图如下表所示。

小吴学汇编之第二章--寄存器(2)

         当CPU要读写内存时:

  1. CPU中的相关部件提供两个16位的地址,一个称为段地址,另一个称为偏移地址
  2. 段地址和偏移地址通过内部总线送入一个称为地址加法器的部件
  3. 地址加法器将两个16位地址合成一个20位的物理地址
  4. 地址加法器通过内部总线将20位物理地址送入输入输出控制电路
  5. 输入输出控制电路将20位物理地址送上地址总线
  6. 20位物理地址被地址总线传送到存储器

地址加法器采用物理地址=段地址*16+偏移地址的方法用段地址和偏移地址合成物理地址。例如8086CPU要访问地址为123C8H的内存单元,此时,地址加法器的工作过程如图所示

小吴学汇编之第二章--寄存器(2)

  我们刚才说了,段地址*16,这里相当于将段地址1230H先乘以16,通俗一点的说法就是将1230H左移一位,也就是16*1。如果是左移N位,即16*N。除了这种算法外,也可以这么做,将十六进制数1230H转化为二进制,然后*16,也就是左移4位,即24。由此可以看出,对于二进制来说,左移N位就是2N,对于十进制来说,左移N位就是10N,对于十六进制来说,左移N位就是16N。

2.7          段地址*16+偏移地址=物理地址的本质含义

         这里讨论的是8086CPU段地址和偏移地址的本质含义,而不是为了解决具体的问题而在本质含义之上引申出来的更高级的逻辑意义。

         段地址*16+偏移地址=物理地址的本质含义是:CPU在访问内存时,用一个基础地址(段地址*16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。

         更一般地说,8086CPU的这种寻址功能是“基础地址+偏移地址=物理地址”寻址模式的一种具体实现方案。

         例如,学校、体育馆、图书馆在同一直线上,学校位于直线的起点处。

小吴学汇编之第二章--寄存器(2)

         你想要去图书馆,问我那里的地址,我可以用两种方法告诉你图书馆的地址:

  1. 从学校走2826m到图书馆。这2826m可以认为是图书馆的物理地址
  2. 从学校走2000m到体育馆,从体育馆再走826m到图书馆。第一个距离2000m,是相对于起点的基础地址,第二个距离826m是相对于基础地址的偏移地址(以寄出地址为起点的地址)。

第一种方式是直接给出物理地址2826m,然而第二种方式是用基础地址和偏移地址相加来得到物理地址。

         下面在来一个例子。有两张纸条,每张纸条只能写3位数,那么如何表达图书馆的地址呢?

小吴学汇编之第二章--寄存器(2)

         在第一张纸写200(段地址),第二张纸写826(偏移地址)。假设我们事前有关相关约定:得到两张纸后,做这样的运算:200(段地址)*10+826(偏移地址)=2826(物理地址)。

         8086CPU就是这样一个只能提供两张3位数据纸条的CPU

         今天先到这里,今天的东西有点杂,在小吴看来还是有点用的。起码知道了汇编指令是怎么操作CPU的,并且知道了8086CPU对物理地址的计算方法。