我正在用我的主机(linux x86)和目标机器(arm)上运行的c ++编写一个小应用程序。
我遇到的问题是在主机上我的二进制文件大小约为700kb,但在目标机器上它大约是7mb。
我正在为两个平台使用相同的编译开关。我的第一个问题是,arget机器上的一个库静态链接但我检查了两个二进制文件objdump
并且都使用相同的动态链接库。
所以任何人都可以告诉我如何弄清楚为什么尺寸会有这么大的差异?
答案 0 :(得分:2)
虽然不同的计算机体系结构理论上 ARM和x86可能会有所不同,但它们仍然设计在同一个宇宙中,内存和带宽不会浪费,导致CPU设计人员尽可能地保持可执行代码的紧密性。
因此,我将按概率的顺序研究以下可能性:
符号剥离:如果两个二进制文件中的一个已从其符号中剥离,那么它将显着缩小,尤其是在使用调试信息进行编译时。您可能想尝试剥离两个二进制文件,看看会发生什么。
静态链接:我偶尔会遇到嵌入式目标的构建系统,它们更喜欢使用共享库进行静态链接。检查每个二进制文件的库依赖关系可能会检测到这一点。
其他启用的代码:较大的二进制代码可能启用了其他代码,例如构建系统找到了一个额外的可选库,或者因为目标平台需要特定的句柄。
尽管如此,10的因素可能太多了,除非较小的二进制文件缺少很多功能,或者较大的二进制文件静态链接在某个可选库中。
不同的编译器配置:您不仅应该查看您提供的编译器选项,还应该查看编译器为每个目标使用的默认值。例如,如果编译器在一个体系结构中具有明显更高的内联或循环展开限制,则生成的可执行文件可能会明显地显示出来。
答案 1 :(得分:1)
首先,没有理由期望为不同体系结构编译的相同代码在大小上彼此之间具有任何类型的关系。您可以轻松地让A大于B然后更改一行代码,然后B大于A.
第二个你正在谈论的“二进制文件”是我在猜elf,这是一些二进制文件,有些是很多开销。架构可以在架构和其他类似的东西之间变化。
如果要为两个体系结构/平台编译相同的代码,或者使用不同的编译器或相同体系结构的编译选项,那么没有理由期望文件大小彼此之间存在任何关系。
答案 2 :(得分:0)
不同的架构可以采用完全不同的方式来处理同一件事。例如,在CISC(例如x86)架构上加载立即值通常是一条指令,而在RISC(例如ppc,arm)上,它通常不止一条指令,所需的实际数量取决于该值。例如,如果指令集仅允许16位立即值,则最多可能需要7条指令来加载64位值(加载16位并在负载之间切换)。因此代码本质上是不同的。
答案 3 :(得分:0)
到目前为止未提及但与ARM / x86比较相关的一个原因是浮点仿真。今天所有的x86芯片都支持本机FP(即使是通过SSE支持SIMD FP,x86-64也是如此),但ARM CPU通常缺少FP单元。这反过来意味着即使是简单的FP添加也必须转换为指数和尾数的长整数运算序列。