找回密码
 register

QQ登录

只需一步,快速开始

查看: 44|回复: 0

[汇编语言] [零基础入门学习]·14·寄存器(内存访问)·栈·CPU提供的栈机制

[复制链接]

[汇编语言] [零基础入门学习]·14·寄存器(内存访问)·栈·CPU提供的栈机制

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:91
  • 打卡月天数:14
  • 打卡总奖励:91
  • 最近打卡:2025-01-15 02:59:34
Waylee

主题

0

回帖

1万

积分

仙帝

积分
11890
Waylee 2024-12-27 17:16 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×

3.6 栈

在这里,我们对栈的研究仅限于这个角度:栈是一种具有特殊的访问方式的存储空间,它的特殊性就在于,最后进入这个空间的数据,最先出去。

可以用一个盒子和3本书来描述栈的操作方式。

一个开口的盒子就可以看成一个栈空间,现在就有3本书,《高等数学》、《C语言》、《软件工程》,把它们放到盒子中,操作的过程如图3.7所示。

001.webp

现在的问题是,一次只允许取一本,我们如何将3本书从盒子中取出来?

显然,必须从盒子的最上边取。这样取出的顺序就是:《软件工程》、《C语言》、《高等数学》,和放入的顺序相反,如图3.8所示。

3.8

3.8

从程序化的角度来讲,应该有一个标记,这个标记一直指示盒子最上边的书。

如果说,上例中的盒子就是一个栈,我们可以看出,栈有两个基础的操作:入栈和出栈。入栈就是将一个新的元素放到栈顶,出栈就是从栈顶取出一个元素。栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。栈的这种操作规则被称为:LIFO(Last In First Out,后进先出)。

3.7 CPU提供的栈机制

现今的CPU中都有栈的设计,8086CPU也不例外。8086CPU提供相关的指令来以栈的方式访问内存空间。这意味着,在基础8086CPU编程的时候,可以将一段内存当作栈来使用。

8086CPU提供入栈和出栈的指令,最基本的两个是PUSH(入栈)和POP(出栈)。比如push ax表示将寄存器ax中的数据送入栈中,pop ax表示从栈顶取出数据送入ax。8086CPU的入栈和出栈操作都是以字为单位进行的。

下面举例说明,我们将10000H~1000FH这段内存当作栈来使用。

图3.9描述了下面一段指令的执行过程。

003.webp

mov ax,0123H
push ax
mov bx,2266H
push bx
mov cx,1122H
push cx
pop ax
pop bx
pop cx

注意,字型数据用两个单元存放,高地址单元存放高8位,低地址单元存放低8位。

读者看到图3.9所描述的push和pop指令的执行过程,是否有一些疑惑?总结一下,大概是这两个问题。

其一,我们将10000H~1000FH这段内存当作栈来使用,CPU执行push和pop指令时,将对这段空间按照栈的后进先出的规则进行访问。但是,一个重要的问题是,CPU如何知道10000H~1000FH这段空间被当作栈来使用?

其二,push ax 等入栈指令执行时,要将寄存器中的内容放入当前栈顶单元的上方,称为新的栈顶元素;pop ax 等指令执行时,要从栈顶单元中取出数据,送入寄存器中。显然,push、pop在执行的时候,必须知道哪个单元是栈顶单元,可以,如何知道呢?

这不禁让我们想起另外一个讨论过的问题,就是,CPU如何知道当前要执行的指令所在的位置?我们现在知道答案,那就是CS、IP中存放着当前指令的段地址和偏移地址。现在的问题是:CPU如何知道栈顶的位置?显然,也应该用相应的寄存器来存放栈顶的地址,8086CPU中,有两个寄存器,段寄存器SS和寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在SP中。**任何时刻,SS:SP指向栈顶元素。push指令和pop指令执行时,CPU从SS和SP中得到栈顶的地址。

现在,我们可以完整地描述push和pop指令的功能了,例如push ax。

push ax的执行,由以下两步完成。

(1) SP=SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶;
(2) 将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新的栈顶。

图3.10描述了8086CPU对push指令的执行过程。

004.webp

从图中我们可以看出,8086CPU中,入栈时,栈顶从高地址向低地址方向增长。

问题 3.6

如果将10000H~1000FH这段空间当作栈,初始状态是空的,此时,SS=1000H,SP= ?思考后看分析。

分析:

SP=0010H,如图3.11所示。

001.webp

将10000H~1000FH这段空间当作栈段,SS=1000H,栈空间大小为16字节,栈最低部的字单元地址为1000:000E。任意时刻,SS:SP指向栈顶,当栈中只有一个元素的时候,SS=1000H,SP=00EH。栈为空,就相当于栈中唯一的元素出栈,出栈后,SP=SP-2,SP原来为000EH,加2后SP=10H,所以,当栈为空的时候,SS=1000H,SP=10H。

换一个角度,任意时刻,SS:SP指向栈顶元素,当栈为空的时候,栈中没有元素,也就不存在栈顶元素,所以SS:SP只能指向栈的最底部单元下面的单元,该单元的偏移地址为栈最底部的字单元的偏移地址+2,栈最底部字单元的地址为1000:000E,所以栈空时,SP=0010H。

接下来,我们描述POP指令的功能,例如pop ax。

pop ax 的执行过程和push ax刚好相反,由以下两步完成。
(1)将SS:SP指向的内存单元处的数据送入ax中。
(2)SP=SP+2,SS:SP指向当前栈顶下面的元素,以当前栈顶下面的单元为新的栈顶。

图3.12描述了8086CPU对POP指令的执行过程,

002.webp

注意,图3.12中,出栈后,SS:SP指向新的栈顶1000EH,pop操作前的栈顶元素,1000CH处的2266H依然存在,但是,它已不在栈中。当再次执行push后等入栈指令后,SS:SP移至1000CH,并在里面写入新的数据,它将被覆盖。

您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |天天打卡

GMT+8, 2025-1-15 17:21 , Processed in 0.105076 second(s), 8 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表