速通汇编(六)认识栈,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、无线通信的发展概况
无线通信是指双方至少一方使用无线方式进行信息的交换与传输,包括移动体(行人、车辆、船舶以及飞机)和移动体之间的通信,也包括移动体与固定点(固定点的移动电台或有线通信)之间的通信。 随着无线通信的范围…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...