栈是一种特殊的数据结构,后进先出
8086CPU提供了最基本的入栈和出栈指令,push 和 pop,例如
push ax 把ax的数据入栈
pop ax 取栈顶元素于ax中
对于栈的操作,是以字为单位操作的
计算机如何知道一段地址被当做栈来使用?
在8086中,栈寄存器有 ss:栈段寄存器,sp:栈偏移寄存器
任意时刻,ss:sp指向栈顶,通过cs和ip,以及栈寄存器,就可以判断某个地址是否为栈
把1000 0000到 1000 000F作为栈,则初始时栈段地址,和偏移地址?
通常认为栈逆着内存生长,则且以字为单位,则最后一个元素,1000 000EH
初始时,栈空,相当于最后一个出栈,则1000 000EH+2,则结果为1000 0010H
弹栈后数据并不删除
在执行pop后,sp=sp+2,但数据并没有删除,而仅仅是偏移了指针
如果写入新的数据,旧数据将被覆盖
栈越界不会报错
当push数据超出栈大小,仍会往栈顶溢出后的位置继续写入,这会导致其他未知数据被覆盖。(高级语言会报异常,汇编并不会)
当pop取值时,栈空后仍会往下取值,取出的值已经不是栈中的数据
栈进行寄存器和内存传送
栈可以方便的实现寄存器和内存之间的数据传送
- push [0] 把ds:0000数据压栈
- pop [2] 弹栈, 到ds:0002
编程题
指定10000H~1000FH作为栈空间, 初始状态为空, 设置AX=002AH, BX=002BH, 利用栈交换AX和BX中的数据
mov ax, 1000H
mov ss, ax
mov sp, 0010H ;初始化栈顶
mov ax, 002AH
mov bx, 002BH
push ax
push bx
pop ax
pop bx
需要注意, ss不可以直接赋值, 而sp可以直接赋值, 因为ss是段寄存器, 和ds类似
段寄存器均不可以直接赋值, 而偏移寄存器则可以, 段寄存器需要经过通用寄存器做中间操作