为什么我的 hello world 二进制文件大部分为零?

2023-12-09

我已经编译了

#include <stdio.h>

int main() {
    printf("Hello world");
    return 0;
}

在 Mac 上,它的大小为 48k。但是,当我查看二进制文件时xxd大部分看起来像这样:

...
0000b990: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000b9a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000b9b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
...

为什么会这样呢?

otool告诉我:

 otool -L hello
hello:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.0.0)

很好,它再次动态链接到 libSystem,在那里它printf is.

那为什么全是零呢?


因为对齐。

XNU 强制映射二进制文件部分的每个段都与平台的页面大小对齐。在 x86_64 上,这是 0x1000 字节,在 arm64 上,这是 0x4000 字节(即使硬件支持 0x1000)。如果某些段的数据必须与某个偏移量对齐,那么就必须有某物在填补两者之间空白的文件中 - 通常为零。

现在,如果您的二进制文件是 48KB,那么它的段可能如下所示:

LC 00: LC_SEGMENT_64  Mem: 0x000000000-0x100000000  File: Not Mapped    ---/--- __PAGEZERO
LC 01: LC_SEGMENT_64  Mem: 0x100000000-0x100004000  File: 0x0-0x4000    r-x/r-x __TEXT
LC 02: LC_SEGMENT_64  Mem: 0x100004000-0x100008000  File: 0x4000-0x8000 rw-/rw- __DATA_CONST
LC 03: LC_SEGMENT_64  Mem: 0x100008000-0x10000c000  File: 0x8000-0xc000 rw-/rw- __DATA
LC 04: LC_SEGMENT_64  Mem: 0x10000c000-0x100010000  File: 0xc000-0xc110 r--/r-- __LINKEDIT

对于 0x4000 的对齐,这已经是最小布局。但如果你使用 Intel,你可以通过传递强制链接器使用 0x1000-Wl,-segalign,0x1000给编译器。这应该会生成一个只有 12KB 左右的二进制文件:

LC 00: LC_SEGMENT_64  Mem: 0x000000000-0x100000000  File: Not Mapped    ---/--- __PAGEZERO
LC 01: LC_SEGMENT_64  Mem: 0x100000000-0x100001000  File: 0x0-0x1000    r-x/r-x __TEXT
LC 02: LC_SEGMENT_64  Mem: 0x100001000-0x100002000  File: 0x1000-0x2000 rw-/rw- __DATA_CONST
LC 03: LC_SEGMENT_64  Mem: 0x100002000-0x100003000  File: 0x2000-0x3000 rw-/rw- __DATA
LC 04: LC_SEGMENT_64  Mem: 0x100003000-0x100004000  File: 0x3000-0x3110 r--/r-- __LINKEDIT

如果您想进一步优化二进制文件,则需要删除段。通过导入和链接,您真正可以摆脱的唯一一个是__DATA_CONST,您可以通过针对 macOS Mojave(或更早版本)使用-mmacosx-version-min=10.14。这将使您剩下 8KB 多一点的空间:

LC 00: LC_SEGMENT_64  Mem: 0x000000000-0x100000000  File: Not Mapped    ---/--- __PAGEZERO
LC 01: LC_SEGMENT_64  Mem: 0x100000000-0x100001000  File: 0x0-0x1000    r-x/r-x __TEXT
LC 02: LC_SEGMENT_64  Mem: 0x100001000-0x100002000  File: 0x1000-0x2000 rw-/rw- __DATA
LC 03: LC_SEGMENT_64  Mem: 0x100002000-0x100003000  File: 0x2000-0x20f0 r--/r-- __LINKEDIT

如果您追求尽可能最小的可执行文件,您可以进一步放弃__DATA甚至可能__LINKEDIT,但是您必须大幅更改代码以仅发出原始系统调用,而不使用动态链接器等。

对于任何现实世界的应用程序,我还想说这些零实际上并不重要。给定四个映射段,它们使用的空间永远不会超过 48KB。二进制越大,零所占的百分比就越小。

至于分布,答案很明显:xz.
压缩上述二进制文件会产生:

  • 48KB 二进制文件为 776 字节。
  • 12KB 二进制文件为 736 字节。
  • 8KB 二进制文件为 684 字节。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我的 hello world 二进制文件大部分为零? 的相关文章

  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • C中的malloc内存分配方案

    我在 C 中尝试使用 malloc 发现 malloc 在分配了一些内存后浪费了一些空间 下面是我用来测试 malloc 的一段代码 include
  • 在 LINQ 中按 Id 连接多表和分组

    我想按categoryId显示列表产品的名称组 这是我的代码 我想要我的视图显示结果 Desktop PC HP Red PC Dell Yellow PC Asus Red SmartPhone Lumia 720 Blue 我的组模型
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 为什么 Google 测试会出现段错误?

    我是 Google Test 的新手 正在尝试提供的示例 我的问题是 当我引入失败并设置GTEST BREAK ON FAILURE 1 或使用命令行选项 GTest 将出现段错误 我正在考虑这个例子 https code google c
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • 在 Visual Studio 2010 中从 Fortran 调用 C++ 函数

    我想从 Fortran 调用 C 函数 为此 我在 Visual Studio 2010 中创建了一个 FORTRAN 项目 之后 我将一个 Cpp 项目添加到该 FORTRAN 项目中 当我要构建程序时出现以下错误 Error 1 unr
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设
  • 在一个平台上,对于所有数据类型,所有数据指针的大小是否相同? [复制]

    这个问题在这里已经有答案了 Are char int long 甚至long long 大小相同 在给定平台上 不能保证它们的大小相同 尽管在我有使用经验的平台上它们通常是相同的 C 2011 在线草稿 http www open std
  • 具有交替类型的可变参数模板参数包

    我想知道是否可以使用参数包捕获交替参数模式 例如 template
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • DbContext 和 ObjectContext 有什么区别

    From MSDN 表示工作单元和存储库模式的组合 使您能够查询数据库并将更改分组在一起 然后将这些更改作为一个单元写回存储 DbContext在概念上类似于ObjectContext 我虽然DbContext只处理与数据库的连接以及针对数
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • 如何在 32 位或 64 位配置中以编程方式运行任何 CPU .NET 可执行文件?

    我有一个可在 32 位和 64 位处理器上运行的 C 应用程序 我试图枚举给定系统上所有进程的模块 当尝试从 64 位应用程序枚举 32 位进程模块时 这会出现问题 Windows 或 NET 禁止它 我认为如果我可以从应用程序内部重新启动
  • 如何在 Xaml 文本中添加电子邮件链接?

    我在 Windows Phone 8 应用程序中有一些大文本 我希望其中有电子邮件链接 例如 mailto 功能 这是代码的一部分
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • CMake 无法确定目标的链接器语言

    首先 我查看了this https stackoverflow com questions 11801186 cmake unable to determine linker language with c发帖并找不到解决我的问题的方法 我
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • C++ 函数重载类似转换

    我收到一个错误 指出两个重载具有相似的转换 我尝试了太多的事情 但没有任何帮助 这是那段代码 CString GetInput int numberOfInput BOOL clearBuffer FALSE UINT timeout IN
  • C++ 条件编译

    我有以下代码片段 ifdef DO LOG define log p record p else define log p endif void record char data 现在如果我打电话log hello world 在我的代码中

随机推荐

  • 淘汰赛可排序绑定顺序

    这是一个问题的后续 KnockoutJS 可按字段对 observableArray 进行排序并进行条件排序 我还有两件事正在努力实现 首先 当嵌套列表项被拖动到另一个列表时 父级为空 我想删除父级 我通过创建一个 afterMove 函数
  • 何时使用MyISAM和InnoDB? [复制]

    这个问题在这里已经有答案了 MyISAM 的设计理念是 您的数据库被查询的次数远远多于其被更新的次数 因此它执行非常快的读取操作 如果您的读写 插入 更新 比率低于 15 那么最好使用 MyISAM InnoDB 使用行级锁定 具有提交 回
  • 嵌套的 For-Each 会变平吗?

    有一个对象数组 其中每个对象都有一个对象集合 其中每个对象都有一个字符串属性 当我进行嵌套迭代时 TheArray TheCollection TheProperty 看起来我最终得到的不是字符串数组的数组 而是一维字符串数组 这是设计使然
  • 正则表达式匹配最后一个字符

    我有以下几行 data text javascript base64 Ly8gSGVyZdsdsd 5 data text javascript base64 Ly8gSGVyZdsdsd 2 data text javascript ba
  • Django / vBulletin 单点登录

    在同一域上为 Django 项目和 vBulletin 板进行单点登录 SSO 的最简单方法是什么 我有一个现有的 vBulletin 用户数据库 我研究过 Django 的远程用户后端和 vBulletin 的vBSSO但我还没有找到完整
  • java中带单引号的SQL查询

    我有一个想要在 java 中运行的查询 SELECT md5 CONCAT md5 clear password salt 它让我的应用程序连接并使用与我的论坛相同的用户名 密码 它的工作但是当salt包含字符 它给出一个错误 You ha
  • 在 Flutter 中更改主图像尺寸而不触及占位符图像大小

    我有一个关于 flutter 中的图像和预加载的小问题 如何在不改变占位符大小的情况下更改图像覆盖的适合值 Widget primaryVideoImg img return Flex direction Axis horizontal c
  • 确定作为 n 的函数执行递增变量计数的语句的频率

    好吧 我是分析算法的新手 非常感谢任何可以分享如何解决此问题的有用提示 我试图确定 count 作为 n 的函数增加了多少次 我已经在 ide 中运行它 对于值 1 7 输出为 1 3 6 10 15 21 28 我只是不确定如何将其写为
  • 如何保存python IDLE的自定义首选项?

    我在不同的位置有几台计算机 虽然我没有在 IDLE 中编码 但它始终在后台运行 用于小型测试 调试和研究任务 我在家里配置了 IDLE 自定义突出显示 按键设置等 将我的设置保存到外部文件中并将这些设置安装到我正在使用的任何计算机上会非常方
  • 如何访问脚本组件内的 ssis 包变量

    如何访问我在数据流 gt 脚本组件 gt 我的 C 脚本和 SSIS 包中使用的 C 代码中的变量 我已经尝试过 但也不起作用 IDTSVariables100 varCollection null this VariableDispens
  • 如何使用printf显示off_t、nlink_t、size_t等特殊类型?

    在我的程序中 我统计他们想要的文件并将数据发送过去 统计数据的字段struct都是特殊类型 struct stat dev t st dev ID of device containing file ino t st ino inode n
  • python,从(1,n)中随机选择#k个数字,不包括列表中的数字

    对于给定的 except list 3 5 8 n 30 k 5 我想在 1 到 30 之间选择 5 k 个随机数 但我不应该在排除列表中选择数字 假设 except list n 可能很大 当不需要排除时 很容易得到k个随机样本 rand
  • CSS 链接边框样式不适用于 a:visited

    问题在于链接边框样式 我可以在悬停时更改它 但边框 visited不起作用 这是我所拥有的示例 a link color 536DFE text decoration none border bottom dashed 1px transi
  • WCF WSDL + 可空属性

    我有一个 WCF 服务扁平化 WSDL 另一端的消费者告诉我 nillable true 属性正在将它们连接起来 我尝试在服务合同中设置 EmitDefaultValue false 但我没有注意到行为有任何变化 诚然 我以前从未深入研究过
  • 如何在 UICollectionViewCell 中设置 UILabel

    我有一个带有 UIViewController 的应用程序 其中包含 UICollectionView IBOutlet UICollectionView 中的单元格是 MyCustomCell 并使用此方法设置其 UILabel void
  • .NET 的 RSS 解析器 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 对于 NET 中的 RSS
  • 如何使用 Three.js 绘制平行线?

    我对矩阵变换的概念很陌生 我尝试在正交方向上偏移一条线 我想到的是 line translate offsetPixels new THREE Vector3 1 1 0 它沿着向量中定义的轴平移一条线 所以我的问题是如何定义向量中的轴以获
  • 在不同端点上实现多个协定的服务类的 WCF 配置

    我有一个MyService类实现IService1 and IService2接口 我想在两个不同的端点上公开这两个合约 例如 IService1暴露于 Service S1 IService2暴露于 Service S2 这样的配置会是什
  • 如何在vb.net中解码url

    此行表示服务器未声明 Dim DecodedString As String server UrlDecode context Request Form DeckName 我在顶部导入了 system web 似乎无法弄清楚为什么它不起作用
  • 为什么我的 hello world 二进制文件大部分为零?

    我已经编译了 include