我创建了一个包含以下行的文件:
int main() { return 0; }
编译后,我惊讶地发现这个简单程序的二进制文件是 8328 字节!这里发生了什么,二进制文件在这 8328 个字节中做了什么?当然,这个程序可以用几行汇编来表达。
注意:我用以下行编译了这个:
g++ main.cpp
我的 g++ 版本是g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
我创建了一个包含以下行的文件:
int main() { return 0; }
编译后,我惊讶地发现这个简单程序的二进制文件是 8328 字节!这里发生了什么,二进制文件在这 8328 个字节中做了什么?当然,这个程序可以用几行汇编来表达。
注意:我用以下行编译了这个:
g++ main.cpp
我的 g++ 版本是g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
该二进制文件中有很多内容:
file
在其上运行)strip
工具将为您删除(或链接gcc -s
)ldd
和strings
工具)argc
和argv
然后调用的启动代码main
main
将' 的返回值返回给操作系统的关闭代码。对于喜剧效果,请尝试静态链接该程序,其中您的二进制文件将包含通常动态链接到 DLL 的函数。(但是,此选项将简化部署)
对生成的文件进行二进制转储并检查出来!
它主要是空的空间。二进制文件中的数据被组织成页面(通常大小为 4096 或 8192 字节)。这样就可以有效地对页面进行内存映射。通常,第一页包含有关如何加载二进制文件的说明 - 代码位于文件中的此位置并被映射到此位置,对于数据等也是如此。第二页可能是您的代码,第三页将包含符号和调试信息。每个页面可能大部分是空的。
不要打扰。
试着做一个不那么琐碎的程序,你会发现大小并没有那么不同,直到你的代码开始变成数百千字节。
简而言之:标准库的一部分构成了 OS 模块之间的“基础结构”和管理程序启动和终止的 C++ 语义(所有初始化和销毁全局变量、标准输入和输出等)
另外:将 C++ 符号映射到内存地址的所有内容(如果您不需要删除它 - 尝试-O3
-s
并消除-g
选项),以便调试器可以在整个执行过程中显示正确的源代码引用。
另外:由于内存的布局方式,二进制文件通常由固定大小的块组成。您的程序甚至可能更短,但必须至少存在一个代码段、一个数据段初始化器和一个共享段(用于常量值)。