汇编中 sp=0是栈顶还是栈低

今天看汇编,
一个栈段最大可以设为多少?为什么?

分析:

这个问题显而易见,提出来只是为了提示我们将相关的知识融会起来。首先从栈操作指令所完成的功能的角度上来看,push、pop等指令在执行的时候只修改SP,所以栈顶的变化范围是0~FFFFH,从**栈空时候的SP=0**,一直压栈,直到**栈满时SP=0**;如果再次压栈,**栈顶将环绕**,覆盖了原来栈中的内容。所以一个栈段的容量最大为64 KB。

根据王爽的话 栈空时候的SP=0 栈满时SP=0,怎样理解

栈顶将环绕指什么

栈顶环绕实际就是计算机中的数的运算的问题,当一个16位的数为ffffh的时候这个数最大了,再将ffffh加1会得到0。
所以sp是指向栈顶元素,当栈为空的时候,栈内没有元素,那么就要指向栈的最后一个位置还要往后一位,既ffffh+1=0。

对于栈空 sp=0,我有两种理解:
理解一:假设,一个栈的大小为 0~0FH ,设置栈顶为 10H,栈大小为 0~1FH,设置栈顶为 20H。而当栈的大小为 0~FFFFH 时,栈顶应该为 1000H,
但因为 sp 为 16 位寄存器,所以 10000H(17 位)的最高位被舍去,使 sp=0000H
理解二:假设,一个栈的大小为 0~FFFFH,栈的段地址为 1000H,那么栈所在的内存地址是:1000:0000~1000:FFFFH(可以用 1000:0000~1FFF:0000)
那么可以假设栈顶的内存地址是 2000:0000H,但因为 push、pop 指令只能修改 sp 值,所以 ss=1000,sp=0

对于满栈时,sp=0:
每次入栈时,sp = 当前sp - 2,入栈第一个 2 字节的数据时,sp=0 - 2 = FFFEH(-2 的补码),入栈第二个 2 字节的数据时,sp=FFFCH(-4 的补码)
入栈最后一个 2 字节数据前 sp=0002H —>入栈最后一个 2 字节数据后 sp=0002H - 2 = 0

栈顶环绕:
从以上理解可以看出,假设段地址为 1000H,栈满时,栈顶地址=1000:0000H。继续入栈时,sp=0 - 2 = FFFEH(-2 补码),栈顶地址=1000:FFFEH
此时的栈顶已经存有数据,入栈将覆盖该地址的数据。当继续入栈到再次满栈时,sp=0,栈顶地址=1000:0000H。

假设 stack设置为 64K
sp 是16Bits 的所以 栈顶 设置为 0xFFFE 包含 0xFFFE 0xFFFF两个单元
压栈后 这两个单元被占用,sp-=2 指针指向 0xFFFC
当 压入最后一个元素的时候 sp 为 0x0000 共压入 0x8000 个元素。
栈满了以后, sp-=2 = 0xFFFE 指针绕回
再继续压栈 0xFFFE处,就被新数据覆盖了

栈底,堆栈从底地址扩张