栈:
栈是什么?
存放数据的容器
栈 和一般的容器有什么区别,如何存取呢?
先进后出, 类似于 往密闭的盒子放东西
每一次只能拿出最顶部的东西,每一次只能在最顶部放入东西
放入的过程 被称为 入栈,一般用 push 表示
eg:
push ax
取出的过程 被称为 出栈,一般用 pop 表示
eg:
pop ax
栈如何表示栈顶:
存在标志 标识栈顶,称作栈顶标志
如何标识栈顶标志?
无论是出栈的位置还是入栈的位置,
在内存中 都 被视为 内存地址
前面说过由于 8086 的的 地址总线 与 CPU 处理能力存在出入 ,
所以 内存地址 由 段地址 和 偏移地址 来表示
分为 栈顶表示 被分别存储到两个寄存器中,
段地址寄存器:SS, 偏移地址寄存器:SP
SS:SP
出栈和入栈 栈顶标记该如何变化?
在内存中 栈 的地址是有高到低增长
每一次 push SP -= 2
每一次 pop SP += 2
思考一下如何 如何将10000H ~ 1000FH作为 栈 并实现 AX 与 Bx 的交换
mov ax, 1000H
mov ss, ax
mov sp, 10H
push ax
push Bx
pop ax
pop bx
ps:内存也可以,记得交换前确定ds指向那个段地址
内存角度分析栈:
无论是 pop 还是 push,操作的都是数据
数据的来源:寄存器 内存
数据长度也有两种 字节 和 字
8086的 栈 操作的是字型数据·
栈 内存的哪里?
栈没有固定的区域, 没有固定的大小,但栈有最大值 FFFF, 64KB,16位处理器的原因
无论是指令、数据 还是 栈 都没有固定的区域,
SS:SP指向的就是栈的空间,为了避免溢出 因注意选择的边界和大小
CPU 没有检测溢出的能力
一个很有意思的实验:
mov ax, 2000
mov ss, ax
mov sp, 10
mov ax, 3123
push ax
mov ax, 3366
push ax
在执行汇编指令之前先将 2000:0~F的空间全部置0
用 -d 指令查看 该 内存值的变化
思考:为什么值在执行完栈的设定之后就发生了数值的变化?
通过实验我发现 没有压栈就发生变化的值是 几个寄存器
分别是ax,CS,IP,个人觉得应该是为了实现递归或者函数调用时返回原来的
CS IP 指向的位置
从设计者的角度思考
我到现在都没想明白,问题放着,书上说悟性够的人想得出来……,显然我没有悟性 一天的实验我都没想明白
前面的遗留问题:call 指令把 IP的值存储在哪了
call 指令存储在栈中
ret 可以从栈中将数提取出来
利用了栈临时存储数据的功能
来源:https://www.cnblogs.com/daker-code/p/12380164.html