【详细分析C/C++程序运行过程】狂肝120小时,带你速览CSAPP

简介: 【详细分析C/C++程序运行过程】狂肝120小时,带你速览CSAPP

预备知识


  1. 当过程P调用Q,会把返回值压入栈,指明当Q返回时要到Q的哪个地址继续执行;
  2. Q的返回地址作为P的栈帧的一部分,因为他存放的是与P相关的状态;
  3. 调用Q后,Q在此基础上继续扩展自己的栈帧;
  4. 很多过程调用不需要栈帧,只用寄存器足够;
  5. ret就是从栈中弹出之前的那返回地址,然后把pc设为那个返回地址;
  6. 局部变量放在内存中的情况:寄存器不足;局部变量使用地址运算符&,必须为他产生一个地址;某些局部变量是数组或结构,必须能够通过数组或结构被引用访问到;
  7. 大多栈帧都是定长的,有时也要变长的fram;
  8. 通过寄存器过程P最多可传6个整数值(6个指针或者整数);
  9. 如果需要更多参数,P可以在调用Q之前在自己的栈帧存储好这些参数;
  10. 在objdump中产生的反汇编callq 和 retq ,q是64位的意思;
  11. return返回值默认返回rax的值;


函数调用数据传送示例



1668325285979.jpg

1668325303906.jpg


解析


  1. 参数7位于栈顶;
  2. 通过栈传递参数时,所有数据大小都向8的倍数对齐;
  3. 参数到位后,就可以开call了;
  4. P调用Q时,P的代码首先把参数复制到合适寄存器;
  5. P的代码可访问Q返回在rax中的返回值;
  6. 存6个的参数在栈中,我们把第7个参数放在rsp+8中,第八个参数在rsp+16;
  7. 举例把第七个char a4放到%rsp+8,第八个char* a4放到%rsp+16定义为*a4p ;
  8. *a4p+=a4-----------翻译成:先把a4的指针放到rax,movq 16(rsp),rax;
  9. 然后获得a4的值movl 8(rsp),edx放到edx;
  10. 然后计算 addb dl,(rax);用这个取值的符号计算;
  11. 当时栈的分配,因为a4其实就是一个字节的char,他会放到申请的八个字节的栈帧的最后一个字节上;


栈上的局部存储

1668325340449.jpg


看图


第二个例子:

传参数是倒着处理,先给他多的进栈。

不多的那6个进寄存器

1668325351234.jpg

1668325361330.jpg



x86-64实际内存的分配


实际分配图像


x86-64( 又称x64,即英文词64-bit extended,64位拓展的简写)是x86架构的64位拓展,向后兼容于16位及32位的x86架构。

1668325381345.jpg

1668325392442.jpg

1668325400643.jpg


注意:我们可以估计64位机器的地址大小:

通过观察 1024与1000非常接近,同时

2^10 大约等于 10^3


264**-----------**(210)6**乘以16--------------**1018乘以16


内存的限制


现在64位机器只用47位地址-------也就是差不多256TB的地址

1668325422428.jpg


这就是为什么会出现这个地址:

0x 0000 7FFF FFFF FFFF-------最高地址


栈-存放 局部变量

1668325439052.jpg


栈:大小一般限制在8MB

如果去访问一个超过8Megabyte的指针,程序会报Segmentation fault

1668325450969.jpg



文本段-存放exe二进制代码的区域


存放可执行程序的区域—文本段

read-only


executable machine instruction


数据段-存放全局变量,静态变量,字符串常量


声明的全局变量

1668325490840.jpg



堆-存放malloc,new,calloc申请的变量


动态变化

回想高地址不断增长


动态链接

printf函数…

1668325520477.jpg


相关文章
|
2月前
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
53 2
|
3月前
|
C++
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
44 0
|
11天前
|
Ubuntu Linux Shell
C++ 之 perf+火焰图分析与调试
【11月更文挑战第6天】在遇到一些内存异常的时候,经常这部分的代码是很难去进行分析的,最近了解到Perf这个神器,这里也展开介绍一下如何使用Perf以及如何去画火焰图。
|
1月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
104 21
|
1月前
|
存储 算法 搜索推荐
对二叉堆的简单分析,c和c++的简单实现
这篇文章提供了对二叉堆数据结构的简单分析,并展示了如何在C和C++中实现最小堆,包括初始化、插入元素、删除最小元素和打印堆的函数,以及一个示例程序来演示这些操作。
35 19
|
1月前
|
Ubuntu Linux Shell
C++ 之 perf+火焰图分析与调试
【10月更文挑战第8天】在遇到一些内存异常的时候,经常这部分的代码是很难去进行分析的,最近了解到Perf这个神器,这里也展开介绍一下如何使用Perf以及如何去画火焰图。
|
2月前
|
C++
【C++基础】程序流程结构详解
这篇文章详细介绍了C++中程序流程的三种基本结构:顺序结构、选择结构和循环结构,包括if语句、三目运算符、switch语句、while循环、do…while循环、for循环以及跳转语句break、continue和goto的使用和示例。
46 2
|
2月前
|
Ubuntu Linux Shell
C++ 之 perf+火焰图分析与调试
简介 在遇到一些内存异常的时候,经常这部分的代码是很难去进行分析的,最近了解到Perf这个神器,这里也展开介绍一下如何使用Perf以及如何去画火焰图。 1. Perf 基础 1.1 Perf 简介 perf是Linux下的一款性能分析工具,能够进行函数级与指令级的热点查找。利用perf剖析程序性能时,需要指定当前测试的性能时间。性能事件是指在处理器或操作系统中发生的,可能影响到程序性能的硬件事件或软件事件 1.2 Perf的安装 ubuntu 18.04: sudo apt install linux-tools-common linux-tools-4.15.0-106-gen
|
3月前
|
C语言 C++
vscode——如何在vscode中运行C/C++
vscode——如何在vscode中运行C/C++
54 1
|
3月前
|
PHP C++ Python
右手坐标系,空间点绕轴旋转公式&程序(Python和C++程序)
右手坐标系,空间点绕轴旋转公式&程序(Python和C++程序)
64 0