Linux程序的内存

news2024/10/7 9:21:42

                要研究程序的运行环境,首先要弄明白程序与内存的关系。程序与内存的关系,好比鱼和水一般密不可分。内存是承载程序运行的介质,也是程序进行各种运算和表达的场所。了解程序如何使用内存,对程序本身的理解,以及后续章节的探讨非常有利。

程序的内存布局                             

                现代的应用程序都运行在一个内存空间里,在32位的系统里,这个内存空间拥有4GB的寻址能力。Linux默认情况下将高地址的1GB空间分配给内核,剩下的3GB的内存分配给应用进程,称为用户空间。在用户空间里,也有很多地址区间有特殊的地位,一般来讲,应用程序使用的内存空间里有如下"默认"的区域。

        1、栈:栈用于维护函数调用的上下文,离开了栈函数调用就无法实现。栈通常在用户空间的最高地址处分配,通常有数兆字节的大小。

        2、堆:堆是用来容纳应用程序动态分配的内存区域,当程序使用malloc或new分配内存时,得到的内存来自堆里。堆通常存在于栈的下方(低地址方向),在某些时候,堆也可能没有固定统一的存储区域。堆一般比栈大很多,可以有几十至数百兆字节的容量。

        3、可执行文件映像:这里存储着可执行文件在内存里的影像。由装载器在装载时将可执行文件的内存读取或映射到这里。

        4、保留区:保留区并不是一个单一的内存区域,而是对内存中受到保护而禁止访问的内存区域的总称,例如,大多数操作系统里,极小的地址通常都是不允许访问的,如NULL,通常C语言将无效指针赋值为0也是出于这个考虑,因为0地址上正常情况下不可能有有效的可访问数据。图1是Linux下一个进程里典型的内存布局。

图1

                 在图1中,有一个没有介绍的区域:"动态链接库映射区",这个区域用于映射装载的动态链接库。在Linux下,如果可执行文件依赖其他共享库,那么系统就会为它在适当的地址分配相应的空间,并将共享库载入到该空间。

                在图中箭头表明了几个大小可变的区的尺寸增长方向,在这里可以清晰看出栈向低地址增长,堆向高地址增长。当栈或堆现有的大小不够用时,它将按照图的增长方向扩大自身的尺寸,直到预留的空间被用完为止。

栈和调用惯例

                栈是现代计算机程序里最为重要的概念之一,几乎每个程序都使用了栈,没有栈就没有函数,没有局部变量,也就没有我们如今能够看见的所有的计算机语言。

                在经典的计算机科学中,栈被定义为一个特殊的容器,用户可以将数据压入栈中(入栈),也可以将已经压入栈中的数据弹出(出栈),但栈这个容器必须遵循一条规则:先入栈的数据后出栈。

                在计算机系统中,栈则是一个具有以上属性的动态区域。程序可以将数据压入栈中,也可以将数据从栈顶弹出。压栈操作使得栈增大,而弹出操作使栈减小。

                在经典的操作系统里,栈总是向下增长的。栈顶由称为esp的寄存器进行定位。压栈的操作使得栈顶的地址减小,弹出的操作使得栈顶的地址增大。

                这里的栈底的地址是0xbfffffff,而esp寄存器表明了栈顶,地址为0xbffffff4。在栈上压入数据会导致esp减小,弹出数据使得esp增大。相反,直接减小esp的值也等效于在栈上开辟空间,直接增大esp的值等效于在栈上回收空间。如图2所示-程序栈实例。

图2

                栈在程序运行中具有举足轻重的地位。最重要的是,栈保存了一个函数调用所需要的维护信息,这常常被称为堆栈帧或活动记录。堆栈帧一般包括如下几个方面内容:

                1、函数的返回地址和参数。

                2、临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量。

                3、保存的上下文:包括在函数调用前后需要保持不变的寄存器。

                一个函数的活动记录用ebp和esp这两个寄存器规定范围。esp寄存器始终指向栈的顶部,同时也就指向了当前函数的活动记录的顶部。而相对的,ebp寄存器指向了函数活动记录的一个固定位置,ebp寄存器又称为帧指针。一个很常见的活动记录如图3所示。

       图3 活动记录 

                在参数之后的数据(包括参数) 既是当前函数的活动记录,ebp固定在图中所示的位置,不随这个函数的执行而变化,相反地,esp始终指向栈顶,因此随着函数的执行,esp会不断变化。固定不变的ebp可以用来定位函数活动记录中的各个数据。在ebp之前首先是这个函数的返回地址,它的地址是ebp-4,再往前是压入栈中的参数,它们的地址分别是ebp-8,ebp-12等,视参数数量和大小而定。ebp所直接指向的数据是调用该函数前ebp的值,这样在函数返回的时候,ebp可以通过读取这个值恢复到调用钱的值。之所以函数的活动记录会形成这样的结构,是因为函数调用本身如此书写的:一个函数总是这样调用的:

        1、把所有或一部分参数压入栈中,如果有其他参数没有入栈,那么使用某些特定的寄存器传递。

        2、把当前指令的下一条指令的地址压入栈中。

        3、跳转到函数体执行。

                其中第2步和第3步由指令call一起执行。跳转到函数体之后即开始执行函数,一个函数体的"标准"开头是这样的:

        1、push ebp:把ebp压入栈中(称为old ebp)。

        2、move ebp,esp:ebp=esp(这时ebp指向了栈顶,而此时栈顶就是old ebp)。

        3、【可选】sub esp,XXX:在栈上分配XXX字节的临时空间。

        4、【可选】push XXX:如有必要,保存名为XXX寄存器(可重复多个)。

                把ebp压入栈中,是为了在函数返回的时候便于恢复以前的ebp的值。而之所以可能要保存一些寄存器,在于编译器可能要求某些寄存器在调用前后保持不变,那么函数就可以在调用开始时将这些寄存器的值压入栈中,在介绍后再取出。不难想象,在函数返回时,所进行的"标准"结尾与"标准"开头正好相反:

        1、【可选】pop XXX:如有必要,恢复保存过的寄存器(可重复多个)。

        2、move esp,ebp:恢复ESP同时回收局部变量空间。

        3、pop ebp:从栈中恢复保存的ebp的值。

        4、从栈中取得返回地址,并跳转到该位置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/417990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【CSS-Part3 样式显示模式、背景设置、三大特性 】

CSS-Part3 样式显示模式、背景设置、三大特性一 CSS元素显示模式:1.1块元素:1.2行内元素:1.3行内块元素:(同时具有行内元素和块元素的特点)元素显示模式总结:1.4元素显示模式转换:一种模式的元素需要另一模…

从Navicat 和 DBeaver中导出数据不要文本识别符号 “”

今天需要从MySQL和ClickHouse数据库中导出CSV数据文件,打开CSV数据文件后发现字段的数据带着""这种不需要的符号,研究了一下终于成功导出了不要文本识别符号“”的CSV文件 一、演示从DBeaver导出ClickHouse数据库的表文件 第一步&#xff0c…

SSH、OpenSSH、SSL、OpenSSL及CA

OpenSSL1. SSH、OpenSSH、SSL、OpenSSL关系及区别2. SSH介绍2.1 概念2.2 SSH的主要功能2.3 示例讲解2.4 ssh和sshd的区别3. OpenSSH介绍3.1 概念3.2 OpenSSH程序简介3.3 OpenSSH 包含的组件1. ssh2. scp3. sftp4. sshd5. ssh-keygen6. ssh-copy-id7. ssh-agent8. ssh-add9. ssh…

刘二大人《Pytorch深度学习实践》第九讲多分类问题

文章目录多分类问题损失函数课上代码transforms的使用方法view()函数dim维度的理解为什么要使用item()多分类问题 把原来只有一个输出,加到10个 每个输出对应一个数字,这样可以得到每个数字对应的概率值,这里每个输出做…

Netty实战与调优

Netty实战与调优 聊天室业务介绍 代码参考 /*** 用户管理接口*/ public interface UserService {/*** 登录* param username 用户名* param password 密码* return 登录成功返回 true, 否则返回 false*/boolean login(String username, String password); }/*** 会话管理接口…

如何快速上手Vue框架?

编译软件:IntelliJ IDEA 2019.2.4 x64 运行环境:Google浏览器 Vue框架版本:Vue.js v2.7.14 目录一. 框架是什么?二. 怎么写一个Vue程序(以IDEA举例)?三. 什么是声明式渲染?3.1 声明式3.2 渲染四…

docker安装oracle_11g -- 命还长时,自己搞的小玩具!!!

前言: 如果不是嫌命长, 建议不这么玩, 因为装到最后你会很崩溃, 感觉毫无意义, 就是个玩具, 哎~~~就是玩!!! 参考文档 1.https://blog.51cto.com/u_12946336/5722259 2.https://www.muzhuangnet.com/show/118178.html 3.https://blog.csdn.net/qq_42957435/article/details/1…

spring security+jwt实现认证和授权

最近正在研究前后端分离的开发模式&#xff0c;做做小项目练练手&#xff0c;正好用到了spring security的认证和授权&#xff0c;就总结一波。 首先&#xff0c;引入相关的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId&g…

支付系统设计:收银台设计一

文章目录前言1. 收银台前端页面1. 1 收银台的业务场景1. 2 同应用不同支付场景下的收银台2. 商户平台配置管理2.1 配置流程2.2 支付工具列表配置2.3 支付配置2.3 支付银行配置3. 系统处理流程3.1 下单流程3.1 拉起收银台流程总结前言 收银台即用户日常付款前选择支付方式的页面…

革新设计,小巧强大,水库保卫无忧!

水库安全运行事关广大人民群众生命财产安全&#xff0c;为规范水库管理&#xff0c;落实水库预报、预警、预演、预案措施&#xff0c;提升水库信息化管理水平&#xff0c;保障水库安全运行。水库大坝是重要的国民基础设施&#xff0c;承担着防洪抗旱&#xff0c;节流发电的重要…

新规拉开中国生成式AI“百团大战”序幕?

AI将走向何方&#xff1f; ChatGPT在全球范围掀起的AI热潮正在引发越来越多的讨论&#xff0c;AI该如何管理&#xff1f;AI该如何发展&#xff1f;一系列问题都成为人们热议的焦点。此前&#xff0c;马斯克等海外名人就在网络上呼吁OpenAI暂停ChatGPT的模型训练和迭代&#xf…

SGAT丨单基因分析工具SingleGeneAnalysisTool

Single Gene Analysis Tool 简介&#xff1a;SGAT是一个免费开源的单基因分析工具&#xff0c;基于Linux系统实现自动化批量处理&#xff0c;能够快速准确的完成单基因和表型的关联分析&#xff0c;只需要输入基因型和表型原始数据&#xff0c;即可计算出显著关联的SNP位点&…

学习大数据需要什么语言基础

Python易学&#xff0c;人人都可以掌握&#xff0c;如果零基础入门数据开发行业的小伙伴&#xff0c;可以从Python语言入手。 Python语言简单易懂&#xff0c;适合零基础入门&#xff0c;在编程语言排名上升最快&#xff0c;能完成数据挖掘、机器学习、实时计算在内的各种大数…

测试名词介绍

测试名词介绍一&#xff1a;敏捷测试1. 定义&#xff1a;2. 敏捷测试的核心&#xff1a;3. 敏捷测试的8大原则和传统测试的区别二&#xff1a;测试名词介绍瀑布模型回归测试Alpha测试Beta测试性能测试白盒测试黑盒测试灰盒测试三&#xff1a;测试流程单元测试 (unit test)集成测…

Java RSA加解密算法学习

一、前言 1.1 问题思考 为什么需要加密 / 解密&#xff1f;信息泄露可能造成什么影响&#xff1f; 二、 基础回顾 2.1 加密技术 加密技术是最常用的安全保密手段&#xff0c;利用技术手段把重要的数据变为乱码&#xff08;加密&#xff09;传送&#xff0c;到达目的地后再…

nginx的前端部署方式

1. 什么是nginx Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器。 由俄罗斯的程序设计师Igor Sysoev所开发&#xff0c;官方测试nginx能够支支撑5万并发链接&#xff0c; 并且cpu、内存等资源消耗却非常低&#xff0…

javascript 数组详解

1.数组是可变的 数组内元素可以是不同的类型&#xff1a; 字符串一旦创建就不可变&#xff0c;但数组是可变的&#xff0c;且操作起来十分随意&#xff0c;例如&#xff1a; 直接修改数组长度&#xff0c;若新赋予长度小于原数组长度&#xff0c;会直接舍弃多余元素: 若新赋予…

【AI绘画】Midjourney和Stable Diffusion教程

之前我向大家介绍了这两个AI绘画网站&#xff1a; Stable Diffusion介绍&#xff1a; https://mp.csdn.net/mp_blog/creation/editor/130059509 Midjourney介绍: https://mp.csdn.net/mp_blog/creation/editor/130003233 前言 这里是新星计划本周最后一篇&#xff0c;主要…

python 连接oracle

前提&#xff0c;navicate成功连接oracle 1、下载cx_oracle,根据python版本下载whl&#xff0c;或者通过 ​pip install cx_Oracle -i http://pypi.douban.com/simple/ 下载地址&#xff1a; cx-Oracle PyPIhttps://pypi.org/project/cx-Oracle/#files2、navicate下instant…

​Auction Design in the Auto-bidding World系列一:面向异质目标函数广告主的拍卖机制设计...

导读&#xff1a; 传统拍卖机制不存在了&#xff01;出价产品智能化成为行业发展趋势&#xff0c;自动出价&#xff08;Auto-bidding&#xff09;已成为互联网广告主营销的主流&#xff0c;经典效用最大化模型&#xff08;Utility Maximizer&#xff09;的假设已经不再能良好地…