【汇编】栈及栈操作的实现

简介: 【汇编】栈及栈操作的实现

前言


计算机编程的世界中,了解底层的硬件运作是非常重要的。而汇编语言作为一种低级语言,直接与计算机的硬件打交道,其核心概念之一就是栈及栈操作。栈不仅是一种数据结构,更是函数调用、数据保存和程序执行的关键工具。在这篇文章中,我们将深入探讨汇编语言中栈的概念,以及如何通过栈操作来实现各种重要的编程任务。通过理解栈,我们将更好地理解计算机程序的底层运作原理,提高编程的深度和效率。


一、栈是什么?


想象一下你有一堆盘子,你每次都把新的盘子放在上面,取的时候总是从最上面拿。这种像是一摞盘子的结构就像计算机中的栈。栈是一种数据结构,数据像是一层一层的盘子,最新的数据放在最上面。


二、栈的特点


后进先出(Last In, First Out,LIFO): 就像盘子一样,最后放上去的先被拿走,因为新的数据总是放在栈的顶部。

只能在栈顶操作: 想象一下你只能在盘子堆的顶部放置或拿取盘子,不能在中间或底部进行操作。栈也是这样,只能在栈顶进行数据的读取和写入。


三、栈操作


在计算机中,栈常常用于保存和管理函数调用时的数据。两个主要的栈操作是 入栈(Push) 和 出栈(Pop)。

入栈(Push): 就像往盘子堆中放一个新的盘子一样,将数据放到栈顶。


出栈(Pop): 就像从盘子堆中拿走最上面的盘子一样,取出栈顶的数据。


举个例子,假设你在玩一个游戏,每个关卡的进度都需要保存,你可以把每个关卡的进度入栈。当你完成一个关卡时,就可以出栈,回到上一个关卡的进度。


在计算机编程中,函数的调用和返回通常也使用栈来管理,保证程序能够正确地跳回到之前的执行点。栈在计算机中有着广泛的运用,它提供了一种简单而有效的数据管理方式。


四、8086cpu操作栈


4.1 汇编指令

PUSH(入栈)和 POP(出栈)指令

push ax:将ax中的数据送入栈中

pop ax:从栈顶取出数据送入ax

(以字为单位对栈进行操作)


4.2 汇编代码讲解

assume cs:codesg
codesg segment
  mov ax,0123H
  push ax
  mov ax,4567H
  push ax
  pop ax
  pop ax
  mov ax,4c00h
  int 21h
codesg ends
end


问题:

1、CPU如何知道一段内存空间被当作栈使用?

2、执行push和pop的时候,如何知道哪个单元是栈顶单元?


回答:

8086CPU中,有两个与栈相关的寄存器:

栈段寄存器SS - 存放栈顶的段地址

栈顶指针寄存器SP - 存放栈顶的偏移地址

——任意时刻,SS:SP指向栈顶元素。


4.3 栈的操作

mov ax, 1000H
mov ss, ax
mov sp, 0010H

1abef23bdf0743e2868795f314b20deb.png

863d31783a31488a914218d42f01bfff.png

mov ax, 001AH
mov bx, 001BH

f55087cbcadd41c88f64d845b3a35741.png

push ax
push bx

9b99c5240465429bae62e6b43409b682.png

d8800879529f486c90c862792754c161.png

pop ax
pop bx

7221857700484f189cace9c06a0de45c.png

4.3 push 指令和pop指令的执行过程

push ax

(1)SP=SP–2;

(2)将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。

pop ax

(1)将SS:SP指向的内存单元处的数据送入ax中;

(2)SP = SP+2,SS:SP指向当前栈顶下面的

单元,以当前栈顶下面的单元为新的栈顶。

栈顶超界问题

如何能够保证在入栈、出栈时,栈顶不会超出栈空间?


执行入栈(push)时,栈顶超出栈空间

78207f8b14cd4986b2433c13ed02179a.png

执行出栈(pop)时,栈顶超出栈空间

52529fb8eb0f487388d50dd9af31daca.png

栈顶超界问题的解决

8086CPU不保证对栈的操作不会超界。8086CPU 只知道栈顶在何处(由SS:SP指示),不知道程序安排的栈空间有多大。我们在编程的时候要自己操心栈顶超界的问题 ,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界;防止出栈时栈空了仍然继续出栈而导致的超界


4.4 栈的小结

push、pop 实质上就是一种内存传送指令,可以在寄存器和内存

之间传送数据,与mov指令不同的是,push和pop指令访问的内

存单元的地址不是在指令中给出的,而是由SS:SP指出的。

执行push和pop指令时,SP 中的内容自动改变。

8086CPU提供的栈操作机制:

在SS,SP中存放栈顶的段地址和偏移地址,入栈和出栈指

令根据SS:SP指示的地址,按照栈的方式访问内存单元。

push指令的执行步骤:

1)SP=SP-2;

2)向SS:SP指向的字单元中送入数据。

pop指令的执行步骤:

1)从SS:SP指向的字单元中读取数据;

2)SP=SP-2。


总结


汇编语言中的栈及栈操作是程序执行过程中至关重要的组成部分。栈的结构和其操作方式直接影响着函数的调用、数据的保存和程序的执行流程。通过入栈和出栈的操作,我们能够实现数据的临时存储与恢复,实现函数的嵌套调用以及处理各种编程任务。总体而言,深入理解栈及栈操作对于汇编语言的学习和实际编程有着重要的意义。通过本文的讨论,希望读者能够对汇编语言中栈的角色和操作有更清晰的认识,并能够运用这些知识更加灵活地进行编程。

相关文章
|
10天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
81 9
|
4天前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
1天前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
8 1
|
7天前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
9天前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
32 4
|
1月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
27 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
13天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
初步认识栈和队列
初步认识栈和队列
57 10
|
26天前
数据结构(栈与列队)
数据结构(栈与列队)
16 1
|
1月前
|
算法
数据结构与算法二:栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式
这篇文章讲解了栈的基本概念及其应用,并详细介绍了中缀表达式转换为后缀表达式的算法和实现步骤。
43 3