| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> 所有编程语言中的栈操作,底层原理都在这里 -> 正文阅读 |
|
[嵌入式]所有编程语言中的栈操作,底层原理都在这里 |
文章目录在任何一门编译型语言中, 栈操作都是非常重要的。 利用栈的后进先出特性,可以很方便的解决一些棘手的问题,以至于 对于一些解释型的脚本语言,比如: 因此,理解了栈操作的基本原理,对于学习、理解高级语言是非常有帮助的。 这篇文章,我们继续从最底层的指令码入手,通过一个子程序调用(即:函数调用),来学习栈空间是如何操作的,也就是下面这张图: 示例虽然是汇编代码,但是指令码一共不超过
示例代码说明代码的功能是:
主程序在调用子程序的时候,就涉及到返回地址的入栈、出栈操作。 子程序在计算字符串长度的时候,为了保护一些使用到的寄存器不被破坏,也涉及到入栈和出栈操作。 我们的主要目标就是来研究以上这 具体的代码说明如下: 执行主程序以下演示的截图,是通过 在调试的过程中,主要关心的就是栈空间中的数据,以及几个寄存器的值:
初始状态在执行第一条指令之前,首先看一下所有寄存器中的值: 此时,我们还没有为数据段寄存器 只有 再来看一下指令码: 两个绿框内的指令,就是用来设置数据段寄存器 这部分内容在上一篇文章中都已经详细描述过了,这里就不重复了。 执行代码前 5 句
这 执行完这 从以上这张图中可以看到编译器为程序安排了下面这几个地址:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kp0eMjyl-1627604791666)(http://iottown.sewain100.cn/iot727_stack_5.png)] 虽然数据段值定义了 我们把此时内存空间的整体布局画一下: 准备调用子程序我们都知道,在调用函数的之后,需要把调用指令后面的那条指令的地址,压入到栈中。 只有这样,被调用函数在执行结束之后,才能继续返回到正确的指令处继续执行。
在执行 1. call 的指令码和汇编代码
注意: 之前文章说过, 当 这也是相对地址的概念!在以后介绍到重定位的时候,再继续聊这个话题。 2. 栈空间的数据此时,栈顶寄存器 这 因为栈里数据是否有意义,是依赖于 调用子程序子程序的功能是计算字符串的长度,那么主程序一定要告诉子程序:字符串的开始地址在哪里。 在代码的开头,我们放置了 主程序把第一个字符的地址 0,通过寄存器 子程序在执行时,就从 现在我们开始执行 从上面的描述中可以知道: 由于这里 我们来看一下执行 1. 寄存器的值[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L81xjhKK-1627604791671)(http://iottown.sewain100.cn/iot727_stack_8.png)] 从图中看出
从图中还可以看到,指令寄存器 2. 栈空间的数据可以看到:最后 2 个字节是 此时,指令寄存器 子程序保护使用到的寄存器我们知道: 在子程序中,为了计算字符串的长度,代码中用到了 但是我们不知道这 2 个寄存器是否在主程序中也被使用了。 如果我们冒然直接使用它们,改变了它们的值,那么在子程序执行结束后,返回到主程序时,主程序如果也用了这 2 个寄存器,那就有麻烦了。 因此,在子程序的开始处,需要把 当子程序返回的时候,再从栈中恢复它们的值,这样就不会对主程序构成潜在的威胁了。 1. push bx在入栈之前, 还记得上篇文章中入栈的操作吗:
此时,栈顶寄存器
此刻,栈中有意义的数据就有 2. push cx在入栈之前, 执行入栈的 栈空间的数据情况: 3. 计算字符串的长度字符串是放在数据段中的。数据段的段地址 字符串的首地址,主程序在执行 因此,子程序只要从
在循环获取每一个字符的时候,可以用 读取的每个字符,放在 我们来看一下检查第一个字符 ‘a’ 的情况: 此时:
这个过程一直循环 此刻,寄存器 4. 把字符串长度告诉主程序字符串的长度计算出来了,我们要把这个值告诉主程序,一般都是通过通用寄存器 所以,执行指令 mov ax, bx 把 5. pop cx子程序在返回之前,需要把栈中保存的 另外,由于栈的后进先出特性,需要把栈顶数据先弹出到 在执行出栈之前:
栈中的数据情况如下: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C5TzSqg1-1627604791682)(http://iottown.sewain100.cn/iot727_stack_19.png)]
此时,栈中的数据情况: 6. pop bx执行过程是一样的:
此时,栈中的数据情况: 7. 返回指令 ret
此时,栈中的数据情况是: 这时,栈顶寄存器 不管怎样,此时:
所以,当 推荐阅读 【1】C语言指针-从底层原理到花式技巧,用图文和代码帮你讲解透彻 |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/27 9:48:19- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |