1、字的概念
字,就是两个字节,因为8086是16位结构,用字来表示比较方便。
字在内存中存储时 ,要用两个地址连续的内存单元来存放。
字的低位字节存放在低地址单元中,高位字节存放再高地址单元中。
2、DS寄存器
8086CPU中有一个 DS寄存器,通常用来存放要访问的数据的段地址。
例如:我们要读取10000H单元的内容可以用如下程序段进行:
mov bx,1000H
mov ds,bx
mov al,[0]
上面三条指令将10000H(1000:0)中的数据读到al中。
执行指令时,8086CPU自动取DS中的数据为内存单元的段地址。
注意:段寄存器不能直接赋值,8086CPU不支持将数据直接送入段寄存器的操作,ds是一个段寄存器。
mov ds,1000H 是非法的,一定要通过通用寄存器(硬件设计的问题)
数据-> 通用寄存器 -> 段寄存器。
用 mov 指令要访问内存单元,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中。
3、栈 (重点)
栈是一种具有特殊的访问方式的存储空间。它的特殊性就在于,最后进入这个空间的数据,最先出去。
栈有两个基本的操作:入栈和出栈。
入栈:将一个新的元素放到栈顶;
出栈:从栈顶取出一个元素。
栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。
栈的操作规则:LIFO,(Last In First Out,后进先出)
4、入栈和出栈
8086CPU提供入栈和出栈指令: (最基本的)
PUSH(入栈)
POP (出栈)
push ax:将寄存器ax中的数据送入栈中;
pop ax :从栈顶取出数据送入ax。
8086CPU的入栈和出栈操作都是以字为单位进行的。
任意时刻,SS:SP指向栈顶元素。
5、SS,SP寄存器
8086CPU中,有两个寄存器:
段寄存器SS 存放栈顶的段地址
寄存器SP 存放栈顶的偏移地址
任意时刻,SS:SP指向栈顶元素。
如果我们将10000H~1000FH 这段空间当作栈,初始状态栈是空的,此时,SS=1000H,SP=?
SP = E+2 = 10H,所以SP = 0010H
任意时刻,SS:SP指向栈顶,当栈中只有一个元素的时候,
SS = 1000H,SP=000EH。
SS和SP只记录了栈顶的地址,依靠SS和SP可以保证在入栈和出栈时找到栈顶。
6、栈顶越界
因为我们既然将一段空间安排为栈 ,那么在栈空间之外的空间里很可能存放了具有其他用途的数据、代码等,
这些数据、代码可能是我们自己的程序中的,也可能是别的程序中的。(毕竟一个计算机系统并不是只有我们自己的程序在运行)
持续的入栈和出栈会导致栈顶越界问题,扰乱一些数据。
7、栈空间
栈空间当然也是内存空间的一部分,它只是一段可以以一种特殊的方式进行访问的内存空间。
指令执行时 ,CPU 要知道内存单元的地址,可以在 push、pop 指令中给出内存单元的偏移地址,
在指令执行时,CPU从默认DS中取得段地址。
8、栈的作用
用栈来暂存以后需要恢复的寄存器中的内容时 ,出栈的顺序要和入栈的顺序相反,
因为最后入栈的寄存器的内容在栈顶 ,所以在恢复时,要最先出栈。
例如函数的调用就需要用到栈的原理,调用一个函数时,会将原函数的地址,变量等压入栈中。
等调用的函数执行完后,再将原函数的地址,变量等重新出栈。
9、一道编程题
编程:
(1)将10000H~1000FH 这段空间当作栈,初始状态是空的;
(2)设置AX=002AH,BX=002BH;
(3)利用栈 ,交换 AX 和 BX 中的数据。
MOV AX, 1000H
MOV DS, AX // DS指向的地址为栈空间
MOV SP , 0010H // 栈为空
MOV AX, 002AH
MOV BX, 002BH
PUSH AX
PUSH BX
POP AX
POP BX
10、栈的简单总结
push、pop 等栈操作指令,修改的只是SP。
也就是说,栈顶的变化范围最大为:0~FFFFH。栈段的容量最大为64KB。(16位)
任意时刻,SS:SP指向栈顶元素。
8086CPU只记录栈顶,栈空间的大小我们要自己管理。
用栈来暂存以后需要恢复的寄存器的内容时 ,寄存器出栈的顺序要和入栈的顺序相反。
11、段的总结
我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元。这完全是我们自己的安排。
我们可以用一个段存放数据,将它定义为“数据段”;(由DS:IP指向)
我们可以用一个段存放代码,将它定义为“代码段”;(有CS:IP指向)
我们可以用一个段当作栈,将它定义为“栈段”; (由SS:SP指向)
可见,不管我们如何安排 ,CPU 将内存中的某段内存当作代码 ,是因为CS:IP指向了那里;
CPU将某段内存当作栈 ,是因为 SS:SP 指向了那里。
个人总结: 我觉得本章的重点是学习DS寄存器,以及对栈的理解,涉及到栈,那么必须注意栈顶,以及栈顶越界问题