速通汇编(六)认识栈,SS、SP寄存器,push和pop指令的作用
一,栈
(一)栈的特点
栈是一种具有特殊访问方式的存储空间,特殊在于,进出这块存储空间的数据,“先进后出,后进先出”
由于栈的这个“先进后出”的特点,我们可以利用其来很好的操作内存
在《王爽汇编》中,作者用三本书十分形象地来描述了入栈和出栈的操作,对栈比较陌生的同学可以仔细理解,很理解的同学则可跳过
入栈:将数据放在栈的顶部
出栈:将栈顶部的数据取出
也就是说,无论是入栈和出栈,当前操作的数据一定是当前栈中最顶部的数据,我们假想有一个指针,它会一直指着栈顶数据,帮助我们定位
(二)CPU中的栈机制
栈先进后出的这个特点对于我们操作数据是十分方便的一个机制,因此CPU中设计好了提供给我们相关的指令用这种机制来访问内存
简而言之,我们可以主观地将某块内存视作栈(实际上它在内存中是没变的,只是我们主观去刻意认为),然后用相关指令来操作它
最基本的两个入栈和出栈命令是:push(入栈),pop(出栈)
注意,入栈和出栈的操作都是以字(一个字等于两个字节,1 word == 2 byte)为单位的,这意味着任何一次出入栈操作的数据一定是十六位的
例:
push ax (√)
push bh (×)bh是bx的高八位寄存器
pop cx (√)
pop dl (×)dl是dx的低八位寄存器
①初始空栈
规定为,如果将一块内存视作栈,那么这块内存最小的地址处(低地址)为栈顶,反之(高地址)为栈底,例如下图,[10000]为栈顶,[1000F]为栈底,你可以认为只不过是把从左到右(由低地址到高地址)的一块内存顺时针旋转了90度立起来方便我们看而已
此时栈指针指向[10010]处,即栈最底部[1000F]的再下一处,因为是空栈
下面将10000~1000F这段内存视作栈,并用相关指令来操作它
②【mov ax,0123】【push ax】
将0123赋值给ax,然后把ax的值压入栈中
这里再次涉及到小端存储数据的方式(现有的机器基本都是小端存储),ax分为ah高位的01和al低位的23
因此高位的01应该放在[1000F]处,低位的23放在[1000E]处,因此执行完这两条汇编之后,栈中的数据应如下图所示
此时栈指针指向[1000E]处,栈顶数据是23
③【mov bx,2266】【push bx】
这一步和②同理,高位的22被压入相对高位的[1000D]处,低位的66被压入相对低位的[1000C]处
此时栈指针指向[1000C]处,栈顶数据是66
④【mov cx,1122】【push cx】
这一步和②③同理,高位的11被压入相对高位的[1000B]处,低位的22被压入相对低位的[1000A]处
此时栈指针指向[1000C]处,栈顶数据是22
(接下来3步我们整合在一起)
形如【pop 寄存器】指令的作用:将当前栈指针指向的数据放入寄存器中
⑤【pop ax】,栈指针指向[1000A]处,因此将66放入al,22放入ah(别忘了push和pop一定是以字为单位操作数据的,而不是字节),因此执行完后,ax==1122
⑥【pop bx】,同理,栈指针指向的是[1000C],将66放入bl,22放入bh,bx==2266
⑦【pop cx】,同理,栈指针指向的是[1000E],将23放入cl,01放入ch,cx==0123
最后,栈指针再次归位到[10010]处,因为栈空
总结:
①内存中地址从左到右由低到高,栈中地址从上到下由低到高,可以认为栈不过是一块内存顺时针旋转了90度立起来方便我们看而已
②假想一个栈指针,它会时刻指向栈中目前最顶部的数据
③push、pop指令操作的是至少是一个字(不能单独操作一个字节),一个字(word)==两个字节(byte)
④每使用push指令压入一个字,栈指针会向栈顶(低地址)处移动一个字的大小(相当于-2);每使用pop指令弹出一个字,栈指针会向栈底(高地址)处移动一个字的大小(相当于+2)
二,SS、SP寄存器和push、pop的作用
(一)SS、SP寄存器
在前文中,我们反复提到以下两点:
①栈是我们主观假想出来的具有特殊存储方式的内存,与普通内存别无二致
②假想一个栈指针,它会时刻指向栈中目前最顶部的数据
怎么让cpu知道我们把哪块内存视作栈了呢?这个假想出来的栈指针要如何表现呢?cpu提供给我们两个寄存器解决了这两个问题
回想一下,其实就像学习CS、IP寄存器时一样,我们当时解决的问题是“汇编指令和普通数据在内存中存储起来后没有差别(都是二进制数),但是cpu会将[CS:IP]指向的地址视作汇编来执行”;
所以现在举一反三,又需要两个这样的寄存器,一个用来标识段地址,一个用来标识偏移地址,它们共同指向我们主观视作栈的一块内存的栈顶数据,它的地址则是[SS:SP]
因此,[SS:SP]就是实际cpu中的栈指针
(二)push指令
push指令主要有两种用法:
①push 寄存器,例如:【push ax】
此处必须是十六位寄存器(前文已经阐述过)
当本条指令被执行之后,cpu会将指定寄存器ax的数据赋值给[SS:SP]处(即栈顶)
执行完后,SP寄存器的值会-2,因为新压入了两个字节的数据成为了新的栈顶数据,栈指针会向低地址偏移两个字节
②push [偏移地址],例如:【push [0011]】
当本条指令被执行之后,cpu会将指定物理地址[DS:0011]处(不明白为什么是DS的,请仔细复习上一篇<速通汇编(五)>)的数据(同样是十六位数据,如FFFF)赋值给[SS:SP]处(即栈顶)
执行完后,SP寄存器的值会-2,因为新压入了两个字节的数据成为了新的栈顶数据,栈指针会向低地址偏移两个字节
实例:
①先用r命令查看寄存器,观察到SS和SP的值,然后用d命令查询[SS:SP]处内存的值

②在[0000:0000]处提前写入数据12ab34cd,修改DS的值为0000(这样待会push [0]时,[0]就代表[0000:0000])


④a命令在[CS:IP]即[073f:0100]处写入汇编
【mov ax,1234】【push ax】
【push [0]】

⑤执行前两条汇编【mov ax,1234】【push ax】,执行完后查看栈的变化

观察到,ax中的1234被压入栈中,ah的12在高地址,al的34在低地址,且SP==00FD-2==00FB,符合预期
(注:观察到此处栈顶数据左边的内存数据发生变化,这是正常现象,无需关心)

⑥执行第3条汇编【push [0]】,执行完后查看栈的变化

观察到,[0000:0000]处的两个字节12和AB,分别被压入栈的低和高地址处,且SP==00FB-2==00F9,符合预期

(三)pop指令
(pop指令用来弹出栈顶数据,弹出后不是说消失了,你要找个其它位置存放的)
pop指令主要有两种用法:
①pop 寄存器,例如:【pop ax】
此处必须是十六位寄存器(前文已经阐述过)
当本条指令被执行之后,cpu会将[SS:SP]处(即栈顶)的数据弹出,赋值给指定寄存器ax
执行完后,SP寄存器的值会+2,因为弹出了栈顶数据,栈指针会向高地址处偏移2个字节
②pop [偏移地址],例如:【pop [0011]】
当本条指令被执行之后,cpu会将[SS:SP]处(即栈顶)的数据弹出,赋值给指定物理地址[DS:0011]处
执行完后,SP寄存器的值会+2,因为弹出了栈顶数据,栈指针会向高地址处偏移2个字节
实例:
①a命令在在[CS:IP]处写入汇编
【pop ax】【pop [0011]】

②执行第一条汇编【pop ax】,执行完后查看栈与ax的变化

观察到,栈顶数据12AB被弹出,低位的12放入al中,高位的AB放入ah中,ax==AB12
且SP==00F9+2==00FB,符合预期

③执行第二条汇编【pop [0011]】,执行完后查看栈与[0000:0011]处的变化

观察到,栈顶数据3412被弹出,低位的34放入低位的[0000:0011]处,高位的12放入高位的[0000:0012]处
且SP==00FB+2==00FD,符合预期

三,栈越界相关问题
(以下是《王爽汇编》原文节选,提到的CPU通指8086CPU)
上文已经完全说明,CPU由SS和SP来指向栈顶地址,并提供push和pop指令来出入栈
有个问题是,CPU不会保证我们对栈的操作不超界
也就是说,CPU只知道栈顶在何处(由[SS:SP]指示),而不知道我们安排的栈空间有多大。这点就好像 CPU 只知道当前要执行的指令在何处(由CS:IP指示),而不知道要执行的指令有多少从这两点上我们可以看出CPU的工作机理,它只考虑当前的情况:当前的顶在何处、当前要执行的指令是哪一条
我们在编程的时候要自己操心栈顶超界的问题,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界;执行出栈操作的时候也要注意,以防栈空的时候继续出栈而导致的超界
相关文章:
速通汇编(六)认识栈,SS、SP寄存器,push和pop指令的作用
一,栈 (一)栈的特点 栈是一种具有特殊访问方式的存储空间,特殊在于,进出这块存储空间的数据,“先进后出,后进先出” 由于栈的这个“先进后出”的特点,我们可以利用其来很好的操作内…...
【Python机器学习】NLP信息提取——值得提取的信息
目录 提取GPS信息 提取日期 如下一些关键的定量信息值得“手写”正则表达式: GPS位置;日期;价格;数字。 和上述可以通过正则表达式轻松捕获的信息相比,其他一些重要的自然语言信息需要更复杂的模式: 问…...
代理IP批理检测工具,支持socks5,socks4,http和https代理批量检测是否可用
代理IP批理检测工具,支持socks5,socks4,http和https代理批量检测是否可用 工具使用c编写: 支持ipv4及ipv6代理服务器。 支持http https socks4及socks5代理的批量检测。 支持所有windows版本运行! 导入方式支持手工选择文件及拖放文件。 导入格式支持三…...
AI视觉算法盒是什么?如何智能化升级网络摄像机,守护全方位安全
在智能化浪潮席卷全球的今天,以其创新技术引领行业变革,推出的集高效、智能、灵活于一体的AI视觉算法盒。这款革命性的产品,旨在通过智能化升级传统网络摄像机,为各行各业提供前所未有的安全监控与智能分析能力,让安全…...
【Vue】VueRouter路由
系列文章目录 第七章 VueRouter路由 文章目录 系列文章目录第一节:VueRouter基础一、安装:二、基本使用:1. 创建路由代码:Single Page Application:SPA2. 使用路由3. 展示路由: 二、嵌套路由三、路由传参1…...
idea多模块启动
文章目录 idea多模块启动2018版本的idea2019版本的idea idea多模块启动 2018版本的idea 1.首先看一下view> Tool Windows下有没有Run Dashboard 如果有,点击一下底部的窗口就会出现 如果不存在,执行下一步 2.查看自己项目的工作空间位置 点击 File&…...
23:SPI二:W25Q64存储器模块的使用
W25Q64存储器模块的使用 1、W25Q64的简介2、模块内部结构2.1:引脚结构2.2:内部存储结构2.3:此模块的注意事项 3、程序模拟SPI读写W25Q644、片上外设SPI读写W25Q64 1、W25Q64的简介 其中最主要的特点就是掉电不丢失。 由上图所示:…...
论文解读《COMMA: Co-articulated Multi-Modal Learning》
系列文章目录 文章目录 系列文章目录论文细节理解1. 研究背景2. 论文贡献3. 方法框架4. 研究思路5. 实验6. 限制结论 论文细节理解 这段话中,the vision branch is uni-directionally influenced by the text branch only 什么意思?具体举例一下 以下是…...
10款电脑加密软件超好用推荐|2024年常用电脑加密软件排行榜
随着数据隐私和信息安全意识的增强,电脑加密软件已成为日常工作和个人生活中不可或缺的工具之一。无论是保护公司机密文件,还是保障个人数据的安全,合适的加密软件都能提供强有力的保护。本文将推荐2024年超好用的10款电脑加密软件࿰…...
用户态缓存:环形缓冲区(Ring Buffer)
目录 环形缓冲区(Ring Buffer)简介 为什么选择环形缓冲区? 代码解析 1. 头文件与类型定义 1.1 头文件保护符 1.2 包含必要的标准库 1.3 类型定义 2. 环形缓冲区结构体 2.1 结构体成员解释 3. 辅助宏与内联函数 3.1 min 宏 3.2 is…...
Harmony应用 ArkTs AES 加密方法之GCM对称加密
加解密介绍 在数据存储或传输场景中,可以使用加解密操作用于保证数据的机密性,防止敏感数据泄露。 使用加解密操作中,典型的场景有: 使用对称密钥的加解密操作。 使用非对称密钥的加解密操作。 使用RSA(PKCS1_OAEP…...
热成像在战场上的具体作用!!!
1. 探测和跟踪敌人 原理:人体和许多类型的军事设备都会发热,热成像技术通过探测这些红外辐射,能够在远距离探测和跟踪敌人的位置。 应用场景:这一功能在夜间或有覆盖物(如草丛、树林)的情况下尤为有效&am…...
2024年09月20日《每日一练》
1、 根据我国“十三五”规划纲要,()不属于新一代信息技术产业创新发展的重点。 A 人工智能 B 移动智能终端 C 先进传感器 D 4G D P13 此题考察的是新一代信息技术,必须掌握,高频考点 国在“十三五“规划纲要中&#x…...
使用 SSCB 保护现代高压直流系统的优势
在各种应用中,系统效率和功率密度不断提高,这导致了更高的直流系统电压。然而,传统的电路保护解决方案不足以在保持高可靠性和安全性的同时有效保护这些高压配电系统。 固态断路器 (SSCB) 和电熔断器具有众多优点&…...
Linux基础命令——文件系统的日常管理
目录 一.如何查看当前工作目录?(你现在所处的位置路径) 二.命令touch的用途是什么?还有别的方法新建文件吗? (1)创建空文件 (2)如果已经存在这个文件,就会更新创建时间。 (3…...
uniapp使用高德地图设置marker标记点,后续根据接口数据改变某个marker标记点,动态更新
最近写的一个功能属实把我难倒了,刚开始我请求一次数据获取所有标记点,然后设置到地图上,然后后面根据socket传来的数据对这些标记点实时更新,改变标记点的图片或者文字, 1:第一个想法是直接全量替换,事实证明这样不行,会很卡顿,有明显闪烁感,如果标记点比较少,就十几个可以用…...
坦白了,因为这个我直接爱上了 FreeBuds 6i
上个月,华为发布的 FreeBuds 6i 联名了泡泡玛特真的超级惊艳,不少宝子被这款耳机的颜值所吸引,而它的实力更是不容小觑的。FreeBuds 6i 是一款性能强大的降噪耳机,它一直在强调平均降噪深度,但是应该很多人对这个概念很…...
006.MySQL_查询数据
课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :…...
【C#生态园】从图像到视觉:Emgu.CV、AForge.NET、OpenCvSharp 全面解析
C#图像处理库大比拼:功能对比、安装配置、API概览 前言 图像处理和计算机视觉在现代软件开发中扮演着重要角色,而C#作为一种流行的编程语言,拥有许多优秀的图像处理库。本文将介绍几个用于C#的图像处理和计算机视觉库,包括Image…...
1、无线通信的发展概况
无线通信是指双方至少一方使用无线方式进行信息的交换与传输,包括移动体(行人、车辆、船舶以及飞机)和移动体之间的通信,也包括移动体与固定点(固定点的移动电台或有线通信)之间的通信。 随着无线通信的范围…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...





