一、深入学习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 新增按分类查询功能, ...
随机推荐
- 基于Python3实现的各类数据库连接和连接池
基于Python3的各类数据库连接和连接池, 支持数据库有: Mysql(MariaDB), Oracle, PostgreSQL(GreenPlum), Vertica, Redis, MongoD ...
- flash的TotalFrames显示undefined
通过js来操作flash的时候,获取到总帧数的是属性.TotalFrames,而不是属性TotalFrames().在asp.net中,js放在最后可以在一定程度上避免当前flash没有加载完,导致获 ...
- Tomcat警告之“资源添加到Web应用程序[]的缓存中,因为在清除过期缓存条目后可用空间仍不足 - 请考虑增加缓存的最大空间”
原因 缓存不够,可以将其缓存调大 解决办法: 在 /conf/context.xml 的 前添加以下内容: <Resources cachingAllowed="true" ...
- 定时任务__@Xxl-JOB的使用
概述xxl-job框架 首先我们要知道什么是XXL-JOB? 官方简介:XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并接入多家公司 ...
- 【AD】Altium Designer 原理图的绘制
原理图设置基础 原理图的设置 设置原理图图纸大小 在原理图的绘制过程中,各个元件的大小是不能调整的. 如果原理图纸张放不下,需要对图纸进行设置:设计->文档选项,右键->选项-> ...
- 【Android开发】【第三方SDK】 安卓版分词功能
功能介绍: 获取剪切板内容,进行分词: 点击分解后的词,填入输入框: 点击叉号将地址拼接起来返回主界面 用途: 增加用户的体验效果,可以直接在微信上复制地址,然后通过此功能确认地址. 附上git地址 ...
- Vue入坑日记: day - 01
前言 最近做了一些小项目,小组里写前端的确实有点拉胯,于是自己动手写前端,因为大一学过web前端基础,所以对HTML,CSS还有印象,就直接对JS下手了,学了两天把JS大致搞明白了,顺便对JQuery ...
- JS正则表达式学习记录
JS:正则表达式学习记录 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...
- JavaScript学习总结4-规范
昨天学习了JS的严格检查模式,今天做一点补充 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 & ...
- npm 报错This is probably not a problem with npm. There is likely additional logging output above.
报错This is probably not a problem with npm. There is likely additional logging output above. 安装了一个插件后 ...