掌握进程虚拟地址空间区域的划分

课程讲的内容建立在x86 32位的Linux系统下。

任何的编程语言会产生两种东西:指令和数据。磁盘上的可执行文件在启动时都会加载到内存当中,但是不会加载到物理内存中,是放在进程的虚拟地址空间中。

在4g内存中,有3g内存是用户空间,1g内存是内核空间。用户空间分为代码段.text,只读数据段.rodata,数据段.data(存放初始化后的数据),.bss(存放未初始化的数据,操作系统会默认赋值为0),堆,加载共享库,栈,最后是命令行参数和环境变量。内核空间分为三块。

每个进程的用户空间是私有的,但是内核空间是共享的,就有这样一个问题:进程之间的通信方式有哪些?匿名管道通信=》在将通信的内容放在内核空间中。

面试中常问的问题:指令在运行的时候放在内存的哪个区域?代码段.text

从指令角度掌握函数调用堆栈的详细过程

两个问题:

#include<iostream>
using namespace std; /*
问题1:main函数调用sum,sum执行完后,怎么知道回到哪个函数
问题2:sum执行完,回到main函数之后怎么知道从哪一行继续执行
*/ int sum(int a, int b) {
int temp = 0;
temp = a + b;
return temp;
} int main() {
int a = 10;
int b = 20; int ret = sum(10, 20);
cout << "ret:" << ret << endl;
return 1;
}

代码在内存中是怎么存在的。在代码运行时会在内存中生成相应的栈帧,保存代码所需的内存。esp为栈顶地址,ebp为栈底地址(为高位地址)。

从main函数开始,代码在内存保存数据,首先是两个赋值语句,被放在栈底的上面,汇编代码为 mov dword ptr[ebp-4], 0Ah。运行到ret的时候,首先将数据存在栈中,然后调用函数,函数会首先push到栈顶,函数的两个参数被从右到左push到栈顶,同时esp会向上移动指向栈顶。然后将函数所在的地址压入栈内,再将ebp压入栈中,为sum函数开辟新的栈帧。

栈帧内的元素默认为0xCCCCCCCC。依旧是按照函数内的指令在内存中存数据。遇到}后会将上方的内存进行出栈,ebp指向原来main函数的地址,esp回到栈顶,实参上面的内容全都不要了。这个时候如果访问到esp上面的地址会报错,但是esp上面的地址中的数据仍然是之前的数据没有删除。

举个例子:

int* func(){
int data=10;
return &data;
}//这个内存是不安全的,保存在栈顶开辟的内存中,虽然函数调用之后不会马上消失,但是如果调用新函数这个内存中的数据就会随着新函数改变 int* p=func();//如果后面调用新函数,这个操作就会失效
cout<<*p<<endl;

从编译器角度理解c++代码的编译和链接原理

首先明确的是c++代码在生成为可执行文件的过程中要经过编译和链接两个过程。

  • 一、编译过程

    • 预编译
    • 编译
    • 汇编

    编译过程结束后会生成一个二进制可重定位的目标文件(*.obj)

    .obj文件的格式组成是什么? 是由elf文件头和上节中讲到的.data .bss等段组成。

    此时在该文件中还没有分配虚拟地址,但是在指令中地址被设置为000000。同时在该文件中声明的代码被放置在UND段表示没有定义。

  • 二、链接过程(将编译完成所有.obj文件和静态库文件链接成可执行文件)

    • 将所有.obj文件段合并,符号表合并,进行符号解析 (对.data .bss等各个段进行合并)
    • 符号的重定位 符号解析成功以后=》给所有符号分配虚拟地址

    生成可执行文件。执行的时候在cpu对虚拟地址进行映射,映射到物理地址中

    符号解析:对所有符号的引用,都要找到该符号定义的地方。就是找到定义UND段的地方。

    .exe/.out文件的格式组成是什么?:与.obj文件相比,多了一个program header。该header段中有两个load=》告诉系统运行这两个程序的时候把哪些内容加载到内存当中。

extern int gdata;//这句话是声明,告诉编译器去别的文件中找gdata的定义。

上图是程序在磁盘中的存在形式和执行的过程。

一、深入学习c++先要练好的内功的更多相关文章

  1. 你应当如何学习C++以及编程(细节是必要的,但不是重要的,把时间用在集中精力去解决问题,而不是学习新技术,那样练不成高手。在实践中提高才是最重要的。最最重要的内功还是长期学习所磨练出来的自学能力)good

    最近在学习Qt但由于没有C++的基础,感觉学的很吃力.看到pongba的这篇文章感觉不错就弄过来了, 原文地址:http://blog.csdn.net/qter_wd007/article/deta ...

  2. 《疯狂Java讲义》(一) ---- 关于学习Java的反思

    "听到Spring很火,就立马买来一本Spring的书来读,最后结果往往是失败,因为这种学习没有积累,没有根基,学习过程中困难重重,每天都被一些相同.类似的问题所困扰,起初热情十足,经常上论 ...

  3. 10个相见恨晚的 Java 在线练手项目

    10个有意思的Java练手项目: 1.Java 开发简单的计算器 难度为一般,适合具有 Java 基础和 Swing 组件编程知识的用户学习 2.制作一个自己的 Java 编辑器 难度中等,适合 Ja ...

  4. BFC与优雅降级 渐进增强——学习笔记

    BFC(块级格式化上下文) BFC(Block formatting context) 直译为"块级格式化上下文". 元素的显示模式 我们前面讲过 元素的显示模式 display. ...

  5. 学习笔记之Python人机交互小项目一:名字管理系统

    2020是一个不平凡的一年,但即使挫折不断,我们每学期的课程实训也没有受到影响,仍旧如期实施.与往年不同的是,今年的实训老师是学校邀请的公司在职人员来给我们实训.今年实训的内容是Python语言,下面 ...

  6. Go 学习路线(2022)

    原文链接: Go 学习路线(2022) Go 语言的发展越来越好了,很多大厂使用 Go 作为主要开发语言,也有很多人开始学习 Go,准备转 Go 开发. 那么,怎么学呢? 我发现,在互联网时代,学习的 ...

  7. 1121冬至!!!巩固HTML基础第一堂

    今天只是把以前的知识巩固了一下.温故而知新,说的一点没错: 又新明白了一种居中对齐方法: 水平居中:align left(左侧对齐),center(居中对齐) 垂直居中:ralign top(上对齐) ...

  8. 《程序设计教学法--以Java程序设计为例》

    <程序设计教学法--以Java程序设计为例> 当老师上的第一门课就是<Java程序设计>,工作以来,断断续续上了近十次课了吧.十几年来,教材.课程内容.教学方法.教学手段不断改 ...

  9. lucene.net 3.0.3、结合盘古分词进行搜索的小例子(转)

    lucene.net 3.0.3.结合盘古分词进行搜索的小例子(分页功能)   添加:2013-12-25 更新:2013-12-26 新增分页功能. 更新:2013-12-27 新增按分类查询功能, ...

随机推荐

  1. 学习ELK日志平台(四)

    一:需求及基础: 场景: 1.开发人员不能登录线上服务器查看详细日志 2.各个系统都有日志,日志数据分散难以查找 3.日志数据量大,查询速度慢,或者数据不够实时 4.一个调用会涉及到多个系统,难以在这 ...

  2. Demo示例——Bundle打包和加载

    Unity游戏里面的场景.模型.图片等资源,是如何管理和加载的? 这就是本文要讲的资源管理方式--bundle打包和加载. 图片 Unity游戏资源管理有很多方式: (1)简单游戏比如demo,可以直 ...

  3. 创建TypeScript代码模板(NVS+Yarn+ESLint+Prettier+Husky)

    创建TypeScript代码模板(NVS+Yarn+ESLint+Prettier+Husky) Cui, Richard Chikun 本文笔者将带你在Github代码仓库创建TypeScript代 ...

  4. Chrome 53 Beta一些有意思的改动

    原文链接: http://blog.chromium.org/2016...译者:Icarus邮箱:xdlrt0111@163.com 如果没有特殊说明的话,以下都是应用在Android,Chrome ...

  5. APICloud重磅支持Atom编辑器,并建立开发工具核心库

    APICloud技术再次升级,不仅支持Atom编辑器开发工具,并推出核心开发工具库,使开发者进行App开发更便捷高效. APICloud支持Atom编辑器开发工具 APICloud始终坚持多开发工具支 ...

  6. Web缓存总结

    web缓存作用 减少网络带宽消耗降低服务器压力减少网络延迟,加快页面打开速度 Web缓存的类型 数据库数据缓存:为了提供查询的性能,会将查询后的数据放到内存中进行缓存,下次查询时,直接从内存缓存直接返 ...

  7. ES6-11学习笔记--Map

    Map:一种新的数据结构 常用方法 遍历 应用场景 WeakMap   常用方法: let map = new Map() let obj = { name: '张三' } map.set(obj, ...

  8. Citus 分布式 PostgreSQL 集群 - SQL Reference(SQL支持和变通方案)

    由于 Citus 通过扩展 PostgreSQL 提供分布式功能,因此它与 PostgreSQL 结构兼容.这意味着用户可以使用丰富且可扩展的 PostgreSQL 生态系统附带的工具和功能来处理使用 ...

  9. 设计模式之简单工厂SimpleFactory的实现

    internal interface Chart { void Display(); } internal class LineChart : Chart { public LineChart() { ...

  10. Exchange统计邮箱数量

    以Exchange管理员身份登录,打开PowerShell控制台. 1.查询Exchange组织邮箱数量 键入以下命令. Get-Mailbox | Measure-Objcet 2.查询某数据库邮箱 ...