一、DS和[address]
CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在8086PC中内存地址有段地址和偏移地址组成。DS(数据寄存器)中通常存放要访问数据的段地址。比如要读取1000H单元的内容,可以用下面这段代码:
mov bx,1000H
mov ds,bx
mov al,[0]
注意:由于ds是一个段寄存器,8086CPU不支持将数据直接送入段寄存器的操作。为什么?(这就时8086硬件设计问题了) 所以mov ds 1000H是非法的。只能通过将数据先放到普通寄存器中,然后在放到ds寄存器中。
mov指令可以完成两种传送:
1、将数据直接送入寄存器(在8086CPU中,不能讲数据直接送入DS中)
2、将一个寄存器中的内容送入另一个寄存器
mov指令访问内存单元,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中。
二、CPU提供的栈机制
现在的CPU中都有栈的设计,在基于8086CPU编程的时候,可以将一段内存当做栈来使用。8086CPU提供入栈和出栈指令,最基本的两个是PUSH和POP。push ax 表示将寄存器ax中的数据送入栈中,pop ax表示从栈顶取出数据送入ax。8086CPU的出入栈操作都是以字节为单位进行的。
CPU如何知道当前栈顶的地址? 这个问题和CPU如何知道当前指令的地址一样,CS IP存放在当前指定的段地址和偏移地址。SS SP存放当前段地址和偏移地址。
三、栈顶超界问题
8086CPU不保证我们对栈的操作不会超界,它只记录栈顶的位置,需要开发人员自己操心栈顶超届问题。
四、段的综述
我们可以将一段内存定义为一个段,用一个段地址指示段,用便宜地址访问段内的单元。这完全是我们自己的安排。我们可以有用一个段存放数据,将它定义为“数据段”。用一段存放代码,将它定义为“代码段”,用一段当做栈,将它定义为“栈段”。我们可以这样安排,但是若要让CPU按照这样的安排访问这些段,就要:对于数据段,将它的段地址放到DS中,用mov、add、sub等访问内存单元的指令时,CPU就将我们定义的数据段中的内容当做数据来访问。对于代码段,将它的段地址放在CS中,将段中第一条指令的偏移地址放在IP中,这样CPU就将执行我们定义的的代码段中的指令。
可见,不管我们如何安排,CPU将内存中的某段内容当做代码,是因为CS:IP指向哪里。CPU将某段内存当做栈,是因为SS:SP指向哪里。