一、深入学习c++先要练好的内功
掌握进程虚拟地址空间区域的划分
课程讲的内容建立在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++先要练好的内功的更多相关文章
- 你应当如何学习C++以及编程(细节是必要的,但不是重要的,把时间用在集中精力去解决问题,而不是学习新技术,那样练不成高手。在实践中提高才是最重要的。最最重要的内功还是长期学习所磨练出来的自学能力)good
最近在学习Qt但由于没有C++的基础,感觉学的很吃力.看到pongba的这篇文章感觉不错就弄过来了, 原文地址:http://blog.csdn.net/qter_wd007/article/deta ...
- 《疯狂Java讲义》(一) ---- 关于学习Java的反思
"听到Spring很火,就立马买来一本Spring的书来读,最后结果往往是失败,因为这种学习没有积累,没有根基,学习过程中困难重重,每天都被一些相同.类似的问题所困扰,起初热情十足,经常上论 ...
- 10个相见恨晚的 Java 在线练手项目
10个有意思的Java练手项目: 1.Java 开发简单的计算器 难度为一般,适合具有 Java 基础和 Swing 组件编程知识的用户学习 2.制作一个自己的 Java 编辑器 难度中等,适合 Ja ...
- BFC与优雅降级 渐进增强——学习笔记
BFC(块级格式化上下文) BFC(Block formatting context) 直译为"块级格式化上下文". 元素的显示模式 我们前面讲过 元素的显示模式 display. ...
- 学习笔记之Python人机交互小项目一:名字管理系统
2020是一个不平凡的一年,但即使挫折不断,我们每学期的课程实训也没有受到影响,仍旧如期实施.与往年不同的是,今年的实训老师是学校邀请的公司在职人员来给我们实训.今年实训的内容是Python语言,下面 ...
- Go 学习路线(2022)
原文链接: Go 学习路线(2022) Go 语言的发展越来越好了,很多大厂使用 Go 作为主要开发语言,也有很多人开始学习 Go,准备转 Go 开发. 那么,怎么学呢? 我发现,在互联网时代,学习的 ...
- 1121冬至!!!巩固HTML基础第一堂
今天只是把以前的知识巩固了一下.温故而知新,说的一点没错: 又新明白了一种居中对齐方法: 水平居中:align left(左侧对齐),center(居中对齐) 垂直居中:ralign top(上对齐) ...
- 《程序设计教学法--以Java程序设计为例》
<程序设计教学法--以Java程序设计为例> 当老师上的第一门课就是<Java程序设计>,工作以来,断断续续上了近十次课了吧.十几年来,教材.课程内容.教学方法.教学手段不断改 ...
- lucene.net 3.0.3、结合盘古分词进行搜索的小例子(转)
lucene.net 3.0.3.结合盘古分词进行搜索的小例子(分页功能) 添加:2013-12-25 更新:2013-12-26 新增分页功能. 更新:2013-12-27 新增按分类查询功能, ...
随机推荐
- Excel之“提取指定符号(中括号)中的字符”
提取A1中[]内的字符函数:=MID(A1,SEARCH("[",A1)+1,SEARCH("]",A1)-SEARCH("[",A1)-1 ...
- Linux基础学习 | gcc、g++的安装和使用
安装gcc 1.apt-get命令是debain Linux发新版的APT软件包管理工具. dabian.ubuntu.deepin等Linux系统通过以下命令: 安装gcc:Shell输入sudo ...
- 实用的 CSS — 贝塞尔曲线(cubic-bezier)
欢迎移步我的博客阅读:<实用的 CSS - 贝塞尔曲线(cubic-bezier)> 前言 在了解 cubic-bezier 之前,你需要对 CSS3 中的动画效果有所认识,它是 anim ...
- 体验javascript之美6:如果你觉得什么都会了或者不知道js学什么了看这里-面向对象编程
概述 当大家已经把js的语言基础理解了,然后能够写出一些简单的例子了,这个时候基本上达到了一年工作经验的水平,而自己能够独立的写一些小功能,完成一些小效果,或者临摹修改一些比较复杂的插件的时候差不多就 ...
- CSS系列——浏览器默认样式
了解HTML标签在各浏览器当中的默认样式,可以让我们了解,为什么会要写Reset.css,Reset.css当中要怎么写样式最合理.试着思考下面的问题: 为什么会有默认样式? 每个浏览器的默认样式有什 ...
- 设计模式之简单工厂SimpleFactory的实现(配置文件)
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSetti ...
- CCF201903-2二十四点
思路描述:最开始的思路是拿一个栈来存储数据和符号,在动手实践的过程中发现行不通,单个数字的char和int转换可以,但是加起来的数据两位数字就很难处理了. 然后就去看了看别人的思路,给了我一个很好的启 ...
- IDEA个人常用快捷键
Ctrl+Z:撤销 Ctrl+Shift+Z:重做 Ctrl+X:剪贴 Ctrl+C:复制 Ctrl+V:粘贴 Ctrl+Y:删除当前行 Ctrl+D:复制当前行 Alt+向左箭头:返回上次光标位置 ...
- 「实践篇」解决微前端 single-spa 项目中 Vue 和 React 路由跳转问题
前言 本文介绍的是在做微前端 single-spa 项目过程中,遇到的 Vue 子应用和 React 子应用互相跳转路由时遇到的问题. 项目情况:single-spa 项目,基座用的是 React,目 ...
- Vue整合Quill富文本编辑器
Quill介绍 Quill是一款开源的富文本编辑器,基于可扩展的架构设计,提供丰富的 API 进行定制.截止2021年1月,在github上面已有28.8k的star. Quill项目地址:https ...