汇编第二课课后整理——寄存器(1)

第二章 寄存器

2.1 寄存器及数据存储

CPU是计算机系统的运算和控制核心,是信息处理、程序运行的最终执行单元。CPU一般由运算器、控制器、寄存器等器件构成。CPU中各个部件之间的数据交互是通过内部总线完成的,而前面一章讲的CPU和内存之间的数据交互是通过外部总线完成的,它们的原理和大体结构基本一致。汇编语言中CPU的学习重点放在寄存器的学习上。
汇编第二课课后整理——寄存器(1)

不同CPU,寄存器的个数、结构和功能是不一样的,本书是基于8086CPU学习,所以就来探讨一下8086CPU中寄存器。8086CPU寄存器有14个寄存器,这些寄存器的功能和名称都不同,都会在之后的学习中一个一个进行逐步了解。

今天我们来学第一类寄存器——通用寄存器:AX、BX、CX、DX 。8086CPU的寄存器都是十六位的寄存器,即可以存储两个字节的数据(一个字)。因为这四个寄存器用来存放一般性的数据,所以被称为通用寄存器。
汇编第二课课后整理——寄存器(1)
8086CPU的上一代CPU(8080、8085等)中的寄存器都是8位的,为了让原来写好的程序仍能在8086上使用(兼容性),8086CPU的一个16位通用寄存器由两个独立的8位寄存器组成,分别称为AH、AL(以AX举例,其他三个都一样)。高八位数据被存放在AH寄存器中,低八位数据被存放在AL寄存器中。
汇编第二课课后整理——寄存器(1)

2.2 mov和add指令

mov指令举例:

  • mov ax,FFFFH
  • 它的意义是:将十六进制数FFFF放入通用寄存器AX中
  • 相当于高级语言的赋值语句: ax=FFFFH

add指令举例:

  • add ax,000FH
  • 它的意义是:将十六进制数000F和AX寄存器中的数据相加,再放入AX寄存器中
  • 相当于高级语言的加法语句:ax=*ax+000FH

注意:在汇编语言中,字母是不区分大小写的,ax和AX是完全一致的。

在add指令中,注意进位溢出舍去的情况:最高位加法如果产生了一个进位,那么这个进位是无法保存下来的,需要舍去。如:F000H+F000H=1E000H,这里最高位的1是溢出的,需要舍去,最后结果就是E000H。

还有一个特别容易错的:我们说AX,一般就值16位通用寄存器,不会刻意去区分AH和AL,换句话说就是说AX就是AX这一个整体。但是我们一旦说了AX或者AL,那么它就是指8位寄存器,说出其中的一种,和另一种没有任何关系,就是一个独立的寄存器。(专门指出在AL中进行的加法,若产生溢出,其最高位的进位是不会传递到AX中的)

关于这个原理,我上网是没搜着,大概想想了,我的猜想是:运算是在ALU单元进行的,8086CPU是十六位,那么ALU传出去的总线也是十六位的,AX作为整体看待,是16位二进制数,而运算单元一次也能处理十六位数,所以AX整体运算时是没有高低位之分。但是我们只用AL运算时,数据只有八位,也就是还有八根导线在运算时是不参与的(说不定此时导线就是被CPU锁死的),即使高位进位放在第九根导线上,那也不可能再把第九根导线的值给高位,因为AH中没有加法器,一旦这个进位给了AH中,那么这就不是加一,而是强制赋值。这种操作显然是错误的,故CPU不会允许这种操作。

2.3 确定物理地址的方法

物理地址就是之前那一章学的地址,是内存的编号。但是8086CPU有个矛盾:8086CPU是十六位的,也就是CPU内部只能处理、发送出16位二进制数,那么它只能输送出16位地址值,但是8086CPU有20位地址总线,一个16一个20这就产生了矛盾,有矛盾就要解决啊,看看8086是怎么解决的:
汇编第二课课后整理——寄存器(1)
汇编第二课课后整理——寄存器(1)
就一句话,准确的说是一个式子:物理地址=段地址×16+偏移地址

段地址和偏移地址都是不固定的,只要能满足这个式子就行。

2.4 内存的分段表示法

需要提前说明一下:内存本身没有进行实质上的分段,就是一个完整的线性空间。段的划分只是CPU对内存的一个划分,换句话说就是基于上述式子中的一个划分。

汇编第二课课后整理——寄存器(1)
段地址可以计算出起始地址(基础地址),这个起始地址由于是一个数×16的产物,故起始地址必然是16的倍数。而偏移地址位决定了一个段的最大长度。段地址和偏移地址共同计算出唯一的物理地址。

依据习惯说法,对于一个物理地址是21F60H的内存单元,我们一般不会直接说这个物理地址,而是以段地址和偏移地址共同来说明(强调那个算法式子吧),假设规定的段地址是2000H(不唯一)。
我们会说:

  • 地址是内存的2000H段中的1F60单元

我们会写成:

  • 内存2000:1F60单元

汇编第二课课后整理——寄存器(1)