一、段寄存器DS
在上章中,我们熟悉了通用寄存器和CS、IP寄存器,知道通用寄存器AX,BX,CX,DX是用来存放一般性数据的,而CS:IP是指示CPU当前所要读取指令的地址的。这一章中,将了解段寄存器DS的使用。DS的全称是Data Segment,意为数据寄存器。那它有什么作用呢?CPU在读写一个内存单元的时候,必须知道内存单元的地址,而地址又是由“段地址:偏移地址”确定的。DS就是用来存放这个段地址的。这样在访问内存单元的时候,只需要用"[x]"(x表示偏移地址)的格式给出偏移地址就行了,段地址默认从DS中取出。
有个注意点是,并不能直接把某个内存单元的数据传送到DS中去,必须由一个寄存器进行中转。如:
①mov ds,1000h (✗)
②mov ax,1000h;mov ds,ax (✔)
二、mov ,add,sub指令
指令的含义都清楚,这里提一下使用的注意事项。这三者都有2个操作对象,它们可以是寄存器,内存单元,段寄存器,常数,但是并不是任何两者之间都可以传送。具体如下:
mov指令
寄存器 | 内存单元 | 段寄存器 | 常数 | |
寄存器 | ✔ | ✔ | ✔ |
✔ |
内存单元 | ✔ | ✗ | ✔ | ✔ |
段寄存器 | ✔ | ✔ | ✗ | ✗ |
常数 | ✗ | ✗ | ✗ | ✗ |
(行为左操作对象,列为右操作对象)
add指令/sub指令
寄存器 | 内存单元 | 段寄存器 | 常数 | |
寄存器 | ✔ | ✔ | ✗ |
✔ |
内存单元 | ✔ | ✗ | ✗ | ✔ |
段寄存器 | ✗ | ✗ | ✗ | ✗ |
常数 | ✗ | ✗ | ✗ | ✗ |
(行为左操作对象,列为右操作对象)
总结:1.常数不能作为目的操作数
2.常数作第2个操作数(源操作数)时,如果最高位是十六进制的a~f或A~F,前面要加零,如:mov ax, 0A400H
3.两个内存单元之间不能直接传送数据。
4.两个段寄存器之间不能直接传送
5.不能把常数送到段寄存器。
6.两个内存单元不能直接使用add或sub指令相减
三、栈
栈是一种具有“先进后出”或“后进先出”特性的数据结构。它有2个基本操作:入栈和出栈。8086CPU的入栈和出栈都是以字为单位进行的。与栈相联系的寄存器是SS和SP,在任意时刻,SS:SP指向栈顶元素。
入栈(push):①SP=SP-2;②数据-->栈顶
出栈(pop):①取出栈顶数据-->其他位置②SP=SP+2;
注意:入栈时,栈顶从高地址向低地址方向增长。
四、段的小结
1.「段」是一个逻辑上的概念。 编程时,可根据需要指定一段内存区用作数据段、代码段或是栈段。
2.用作数据段时,要把段地址→DS ;用作栈段时,要把段地址→SS,栈顶偏移地址 → SP ;用作代码段时,段地址→CS,要取的指令偏移地址→IP。但CS和IP的值不能使用mov改变。
3.一段内存可以同时用作代码段、数据段、栈段。 由编程时灵活确定。
4.在8086CPU中,每个段的最大长度不能超过64KB。 (因为寄存器是16位的,能表示的地址范围只能是0000H~FFFFH,即0~216-1)