8086汇编学习笔记05

系列文章

栈的概念

(stack)是一种具有特殊访问方式的内存空间。栈有两个基本的操作:

栈顶的元素总是最后入栈,最先出栈,栈的这种操作规则被称为LIFO(Last In First Out,后进先出)。

CPU允许将一段内存当做栈来使用,这样的内存被称为栈段

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

SS 是段寄存器,因此不能直接将十六进制数移动到 SS 上,也不能对其使用 ADDSUB 指令。
但是 SP 是普通寄存器,没有这个限制。

注意,8086CPU提供的入栈和出栈操作都是以字为单位进行的。

栈操作:PUSH和POP指令

8086CPU提供的入栈和出栈指令,最基本的两个就是 PUSHPOP

PUSH指令(入栈指令)
格式:
PUSH data
用途:
data 对应的字型数据送入栈顶。
POP指令(出栈指令)
格式:
PUSH container
用途:
将栈顶对应的字型数据送入合适的寄存器或内存空间 container 中。

PUSHPOP 指令执行时,CPU从 SS:SP 得到栈顶的地址

PUSH AX ”的执行,由以下两步完成:

  1. SP-=2SS:SP 指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶
  2. AX 中的内容送入 SS:SP 指向的内存单元处,SS:SP 此时指向新栈顶

PUSH AX ”的执行过程则相反,由以下两步完成:

  1. SS:SP 指向的内存单元中的数据送入 AX
  2. SP+=2SS:SP 指向当前栈顶下面的内存单元,以当前栈顶下面的单元为新的栈顶

由于入栈时先改变 SP 再送入数据,出栈时先送出数据再改变 SP ,因此入栈时 SS:SP 指向的内存单元并没有改变(操作的是低2位的字单元),但出栈时,SS:SP 指向的内存数据被直接取出。

栈顶与栈顶越界

PUSH、POP等栈操作指令,修改的只是 SP ,也就是说,栈顶的变化范围最大为0~FFFFH。因此,一个栈段的容量最大为64KB

CPU只记录栈顶,栈大小、栈空间都是自定的,CPU中不会有相应记录。因此,一般将内存空间中一块无用的16倍数字节大小的空间当做栈使用。

当栈满的时候再使用 PUSH 指令入栈,或当栈空的时候再使用 POP 指令出栈,都会发生栈顶越界问题。

栈顶越界是危险的,因为它可能会覆盖掉其余指令或应用程序的数据,可能引发一连串的错误。