第三章、寄存器(内存访问)

3.1、内存中的字的存储

CPU中,用16位寄存器来存储一个字。高8位存放高位字节,低8位存放低位字节。在内存中存储时,由于内存单元时字节单元,则一个字要用两个地址连续的内存单元来存放。这个字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。

3.2、DS和[address]

CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在8086CPU中,内存地址由段地址和偏移地址组成。8086CPU中有一个DS寄存器,通常用来存放要访问数据的段地址。比如我们要读取10000H单元的内容,可以用如下程序段进行:

mov bx,1000H
mov ds,bx
mov al,[0]
上面的3条执行将10000H(1000:0)中的数据读到al中

前面我们使用mov指令,可以完成两种传送:1、将数据直接送入寄存器,2、将一个寄存器中的内容送入另一个寄存器。

[0]表示内存单元的偏移地址。

3.3、字的传送

前面我们用mov指令在寄存器和内存之间进行字节型数据的传送,因为8086CPU是16位结构,有16根数据线,所以一次性传送16位的数据,也就是说可以一次性传送一个字。只要在mov指令中给出16位的寄存器就可以进行16位数据传送了:

mov bx,1000h
mov ds,bx
mov ax,[0]
mov [0],cx

3.4、mov、add、sub指令

mov指令可以有以下几种形式
mov 寄存器,数据 比如: mov ax,8
mov 寄存器,寄存器 比如: mov ax,bx
mov 寄存器,内存单元 比如: mov ax,[0]
mov 内存单元,寄存器 比如: mov [0],ax
mov 寄存器,寄存器 比如: 段寄存器 ds,ax

3.5、数据段

如何访问数据段中的数据呢?将一段内存当做数据段,是我们在编程时的一种安排。

3.6、栈

栈有两个基本的操作:入栈和出栈。入栈是将一个新的元素放到栈顶,出栈就是从栈顶取出一个元素。栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中去取出。栈的这种操作规则被称为:后进先出。

3.7、CPU提供的栈机制

8086CPU提供入栈和出栈指令,最基本的两个是push入栈和pop出栈。比如,push ax 表示将寄存器ax中的数据传入栈中,pop ax表示从栈顶取出数据送入ax。8086CPU的入栈和出栈都是以字位单位进行的。

8086CPU中有两个段寄存器SS和SP,栈顶的段地址存放在SS中偏移地址存放在SP中。 任意时刻,SS:SP指向栈顶元素

3.8、栈顶超界问题

栈顶超界是危险的,因为我们既然将一段空间安排为栈,那么在栈空间之外的空间里很有可能存放具有其他用途的数据、代码等。但是由于我们在入栈出栈时的不小心,将会引发一连串的错误。

我们在编程的时候要自己操心栈顶超界的问题,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界;执行出栈操作的时候也要注意,以防栈空的时候继续出栈而导致的超界。

3.9、push、pop指令

前面我们一直在使用push ax 和pop ax, push 和pop 指令是可以在寄存器和内存之间传送数据的。

push 寄存器
pop 寄存器
push 段寄存器
pop 段寄存器
push 内存单元
pop 内存单元

3.10、栈段

将一段内存当做栈段,仅仅是我们在编程时的一种安排,cpu并不会由于这种安排,就在执行push pop 等栈操作指令时自动地将我们定义的栈段当做栈空间来访问。