我参加了三星的采访。他们询问了很多关于程序内存布局的问题。我对此几乎一无所知。
我用谷歌搜索了“可执行程序的内存布局”。 “进程的内存布局”。
我很惊讶地发现这些主题的信息不多。大多数结果都是论坛查询。我只是想知道为什么?
这些是我找到的几个链接:
我想从一本正确的书而不是一些网络链接中学到这一点。(兰迪海德也是一本书,但还有一本书)。在哪本书中我能找到清楚的&关于这个主题的更多信息?
我也很奇怪,为什么操作系统的书不能在他们的书中涵盖这一点?我读了第6版的摊位。它只讨论了过程控制块。
整个布局创建是linker
的任务对吗?我在哪里可以阅读有关此过程的更多信息我希望从磁盘上的程序 COMPLETE 信息到处理器上的执行。
修改
最初,即使阅读了下面给出的答案,我也不清楚。最近,我在看完这些文章之后看到了这些文章,我明白了。
帮助我理解的资源:
- www.tenouk.com/Bufferoverflowc/Bufferoverflow1b.html
- 5部分PE文件格式教程:http://win32assembly.online.fr/tutorials.html
- 优秀文章:http://www.linuxforums.org/articles/understanding-elf-using-readelf-and-objdump_125.html
- PE Explorer:http://www.heaventools.com/
醇>
是的,“可执行程序的布局(PE / ELF)”!=“进程的内存布局”)。在第3个链接中找到自己。 :)
在清除了我的概念之后,我的问题让我看起来很蠢。 :)
答案 0 :(得分:7)
如何加载内容非常依赖于操作系统和使用的二进制格式,细节可能会变得很糟糕。有关二进制文件如何布局的标准,但它实际上取决于操作系统如何布置进程的内存。这可能是文档很难找到的原因。
回答你的问题:
可执行代码由编译器和链接器创建,但它是将操作系统放入操作系统所需的二进制格式的链接器。在Linux上,这种格式通常为ELF,在Windows和较旧的Unix上为COFF,在Mac OS X上为Mach-O。不过,这不是一个固定的清单。一些操作系统可以并且确实支持多种二进制格式。链接器需要知道输出格式以创建可执行文件。
进程的内存布局与二进制格式非常相似,因为很多二进制格式被设计为mmap'd
,因此加载器的任务更容易。
虽然这不是相当。二进制格式的某些部分(如静态数据)不直接存储在二进制文件中。相反,二进制文件只包含这些部分的大小。当进程加载到内存中时,加载器知道分配适当的内存量,但二进制文件不需要包含大的空部分。
此外,进程的内存布局包括stack和heap的一些空间,其中进程的调用帧和动态分配的内存进入。这些通常位于大地址空间的两端。
这实际上只是揭示了二进制文件如何加载的表面,并没有涉及动态库的任何内容。有关动态链接和加载工作的详细处理,请阅读How to Write Shared Libraries。
答案 1 :(得分:2)
以下是从文件(* nix)执行程序的一种方法。
如果堆和堆栈发生冲突,通常会导致内存不足的情况,这就是堆栈通常放在高内存中的原因。
在没有内存管理单元的系统中,请求分页通常不可用,但通常使用相同的内存布局。
答案 2 :(得分:1)