如何使用汇编制作小型二进制文件?

2024-01-02

我正在为我的一些项目编写一些汇编代码,我看到了一些有趣的东西。链接时二进制文件的大小非常大。所以我测试了又测试,即使使用尽可能少的代码行,输出的 Elf 二进制文件也很大。例如:

.section .text
.global _start
_start:
    movl $1,%eax
    movl $0,%ebx
    int $0x80

汇编和链接上面的代码后,结果二进制文件是超过4kb! 有趣的是,大部分二进制文件都用零填充。
我尝试了很多方法来找出失败的原因。
有人可以向我解释一下这里有什么问题吗?

我简单地组装并链接该文件:

as -o <OBJ_NAME> <SOURCE NAME>
ld -o <ELF_NAME> <OBJ_NAME>

推荐任何形式的资源以供进一步阅读都会很好。

正如你可能猜到的,我使用 64 位 GNU/Linux

thanks.


这与对齐有关。看readelf -eW <ELF_NAME>。有趣的是

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000401000 001000 00000c 00  AX  0   0  1

请注意Off柱子。这是文件中的偏移量,.text部分开头为0x1000,即 4K。

如果你看同样的图片程序头。用零填充的空间位于 ELF 标头末尾和 0x1000 之间。

为什么是这样?

首先,因为 ELF 标准规定

可加载进程段的 p_vaddr 和 p_offset 必须具有一致的值(以页面大小为模)。

(see man elf)。你的系统(我的系统)上的页面大小是 4K。这就是您在中看到的值p_align.

其次,链接器分配给“文本”段开头的虚拟地址 - 与.text此处的部分,因为这就是该部分包含的全部内容 - 是0x0000000000401000。因此,文件中“文本”段偏移量的十六进制表示必须以000。但是 0 已经被包含 ELF 标头(文件的最开头)的只读段占用。第二个选择是0x1000.

为什么链接器选择 0x401000 作为文本部分的虚拟地址?我不知道。我认为,如果稍微调整链接器脚本,您将能够得到更小的结果可执行文件。


正如彼得和其他人指出的那样,可以使用以下命令禁用页面大小对齐-n链接器选项:

'-n'
'--nmagic'
    Turn off page alignment of sections, and disable linking against
    shared libraries[…]

这样我就得到

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 1] .text             PROGBITS        0000000000400078 000078 00000c 00  AX  0   0  1

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x000078 0x0000000000400078 0x0000000000400078 0x00000c 0x00000c R E 0x1

可执行文件的大小降至 664 字节(之后为 344 字节)stripping).


通过 GNU ld,您可以使用链接描述文件精细控制链接器输出文件的布局。ld.bfd(通常也称为只是ld) 如果用户未指定链接描述文件,则解释默认链接描述文件。它可以通过以下方式获得ld --verbose。然后您可以编辑它并提供您的版本而不是默认版本-T <your-script>.

我删除了第一个出现的

. = ALIGN(CONSTANT (MAXPAGESIZE));

(before .text)并得到 720(当stripped)字节。这与使用的结果不同-n选项。你仍然得到 2 个可加载的段,以及它们的p_align还是0x1000.

存在效率影响p_align < MAX_PAGE_SIZE我不完全明白。 (由于地址计算更困难,页面加载速度不会那么快?我认为应该有更好的解释。)如果您了解更多有关此内容或解释的地方,请随意编辑答案。

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

如何使用汇编制作小型二进制文件? 的相关文章

随机推荐