如何做一个程序看起来在记忆?
-
21-09-2019 - |
题
怎么是一个程序(例如C或C++)安排在计算机存储器?我知道一些关于分段,变量等,但基本上我没有扎实的了解的 整个 结构。
由于存结构可能有所不同,让我们假设一个C++控制台应用程序。
一些指点我的后具体而言:
- 大纲的一个功能,以及它是如何称呼?
- 每个功能都有一堆框架,什么是含有,它是如何安排在的记忆?
- 功能的参数和返回值
- 全球和地方的变量?
- const静态变量?
- 线的地方储存..
链接tutorial-像材料,这是值得欢迎的,但是请没有参考式的材料假设知识库的汇编等。
解决方案
这可能是你在找什么:
http://en.wikipedia.org/wiki/Portable_Executable
PE文件的格式是二进制文件结构的windows的二进制文件(.exe.dll等)。基本上,他们是映射入存储器那样。更多的详细描述这里有一个解释你怎么可以自己看看二元表示的装载dll在存储器:
http://msdn.microsoft.com/en-us/magazine/cc301805.aspx
编辑:
现在我明白了,你想了解如何来源码所涉及的二进制代码在PE文件。这是一个巨大的领域。
首先,你必须了解基本关于计算机的架构,它将涉及学习的一般基础的大会的代码。任何简介"机构"的大学课程中将做的事。文献包括,例如"约翰L.轩尼诗和David A.帕特森。机构:一定量的方法"或"安德鲁Tanenbaum、有结构的计算机组织"。
在阅读这个,你应该明白是什么一堆及其差堆。什么叠的指针和基础的指针是什么,返回的地址是多少寄存器的存在等。
一旦你理解这一点,这是相对容易把拼在一起:
C++对象包含码和数据,即件的变量。一个类
class SimpleClass {
int m_nInteger;
double m_fDouble;
double SomeFunction() { return m_nInteger + m_fDouble; }
}
将4+8consecutives字节的记忆。会发生什么当你要做的:
SimpleClass c1;
c1.m_nInteger = 1;
c1.m_fDouble = 5.0;
c1.SomeFunction();
第一,对象c1是建立在堆,即堆的指针esp是下降了12个字节,以腾出空间。然后常数"1"写入存地址esp-12和恒定的"5.0"写入esp-8.
然后我们叫一个功能,意味着两件事情。
计算机负载的部分的二进制PE文件进入存储器包含功能SomeFunction().SomeFunction将只在存储器的一次,无论如何许多的实例SimpleClass你创造的。
计算机具执行功能SomeFunction().这意味着几件事情:
- 叫功能还意味着通过所有参数,经常这样做是对的堆。SomeFunction有一个(!) 参数,这个指针,即指上的存储器地址栈在哪里我们刚才写的价值观"1"和"5.0"
- 保存当前程序的状态,即,当前的指令,地址是地址,这将是执行,如果SomeFunction返回。叫一种功能手段推动返回的地址在堆,并设置指令的指令(注册eip)地址的功能SomeFunction.
- 内部的功能SomeFunction,老栈保存通过储存的古老的基本指针(ebp)上堆(推ebp)和制作指针的新的基本指针(视ebp,esp)。
- 实际的二进制代码SomeFunction执行这将致电机指令转换m_nInteger到一个双人,并将它添加到m_fDouble.m_nInteger和m_fDouble上发现的堆,在ebp-x字节。
- 结果外存储在一个登记册和功能返回。这意味着堆被丢弃这意味着堆的指针是重新设置为基本指针。基针重新设置(下一个值上堆),然后指令的指令集到的回信地址(再下一个值在stack)。现在我们回到原来的状态,但在某些寄存器潜伏的结果SomeFunction().
我建议,你建立自己这样一个简单的例子和步骤,通过拆卸。在调试建立的码将易于理解和Visual Studio显示的变量名称在拆卸图。看看有什么寄存器esp,ebp和eip做,在这里在你的记忆分配对象,那里的代码等。
其他提示
什么一个巨大的问题!
首先,你想要了解 虚拟存储器.没有,什么都没有意义。总之,C/C++指针不是物理存储的地址。指针,都是虚拟的地址。有一个特殊的CPU特征(MMU,存储管理单元),透明的地图,他们的物理存储器。只的操作系统是允许配置MMU。
这提供了安全(有没有C/C++指针的价值就可能使这一点成为另一个进程的地址的虚拟空间,除非这一进程中有意分享存储器与您)和让OS做一些很神奇的东西,我们现在理所当然的(如透明地交换的一些进程的存储磁盘,然后透明地载回来时,该进程试图使用它)。
一个进程的地址空间(的一个。k.a.虚拟地址的空间。k.a.址的存储器)包含:
一个巨大的区域的存储器,保留用于Windows的内核,这个过程不允许接触;
区域虚拟存储器的"映射的",即没有什么是载有,有没有物理存储器分配到这些地址,且该过程会崩溃,如果它试图访问他们;
零部件的各个模块(EXE和DLL文件)已载入(每个包含这些机代码、字符串常量和其他数据);和
什么其它存储的过程中已分配系统。
现在通常一个进程,让所C Runtime Library或Win32图书馆做的大多数超低级别的存管理,其中包括设立:
一堆(每个线程),那里的局部变量和功能的参数和返回值储存;和
一堆,那里存储器的分配是如果过程中的电话
malloc
或者不会new X
.
欲了解更多关于堆叠的结构,阅读有关 呼吁公约.欲了解更多有关如何堆结构性的,阅读有关 malloc实现.在大堆真是一堆、后第一个出的数据结构,包含参数、地方变量,以及偶尔的临时结果,而不多。由于很容易为一个程序写入直接过去结束堆(公共C/C++的错误之后,这个网站是命名)时,系统图书馆通常是确保有一个未映射页邻堆。这使得该进程崩溃时,立即这样一个错误发生,使它更容易debug(和过程中被杀害之前可以做任何更多的伤害).
这堆是不是真的一堆数据结构的意义。这是一个数据结构保持由CRT或Win32库,需要页,内存来自操作系统和包裹他们当处理请求的小碎片的记忆通过 malloc
和朋友。(注意,操作系统不进行微观管理;一个进程,可很大程度上管理其地址的空间,但是,它希望,如果它不喜欢的方式CRT并。)
一个过程还可以要求页直接从操作系统,使用一个API喜欢 VirtualAlloc
或 MapViewOfFile
.
还有更多,但我们最好停下来!
为了解堆框架的结构可以参考 http://en.wikipedia.org/wiki/Call_stack
它给你的有关信息结构的呼叠,如何当地人,globals,返回的地址是存储在电话堆
它可能不是最准确的信息,但是MS按提供一些样本章节的书 内部Microsoft Windows2000年,第三版, ,包含的信息有关的进程和他们的创作以及图像的一些重要的数据结构。
我也偶然发现了 这PDF 总结上述的一些信息在一个漂亮的图表。
但是,所有提供的信息是更多的操作系统的观点并不多详细的有关应用程序方面。
实际上-你不会走远在这个问题,至少有一点点的知识汇编器。我会下载并享受大按钮逆转(教程)的网站,例如OpenRCE.org.