Ami*_*r H 5 assembly linker elf ld binutils
我正在为我的某个项目编写一些汇编代码,我看到了一些有趣的东西。链接时二进制文件的大小是如此之大。所以我进行了测试和测试,即使使用尽可能少的代码行,输出 Elf 二进制文件也是如此之大。例如:
.section .text
.global _start
_start:
movl $1,%eax
movl $0,%ebx
int $0x80
Run Code Online (Sandbox Code Playgroud)
组装和链接以上代码后,结果二进制文件超过 4kb!有趣的是,大多数二进制文件都填充了零。
我尝试了很多事情来找出没有成功的原因。
有人可以向我解释这里有什么问题吗?
我只是组装和链接文件:
.section .text
.global _start
_start:
movl $1,%eax
movl $0,%ebx
int $0x80
Run Code Online (Sandbox Code Playgroud)
推荐任何形式的资源以供进一步阅读会很好。
你可能猜到了,我使用 64 位 GNU/Linux
谢谢。
这与对齐有关。见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
Run Code Online (Sandbox Code Playgroud)
注意Off列。这是文件中的偏移量,该.text部分以 开头0x1000,即 4K。
如果您查看程序标题,则图片相同。用零填充的空间位于 ELF 标头的末尾和 0x1000 之间。
为什么是这样?
首先,因为 ELF 标准规定
可加载进程段必须具有一致的 p_vaddr 和 p_offset 值,以页面大小为模。
(见man elf)。您系统(我的)上的页面大小是 4K。这是您在 中看到的值p_align。
其次,链接器分配给“text”段开头的虚拟地址——与.text此处的段相同,因为这是该段包含的全部内容——是0x0000000000401000. 因此,文件中“文本”段偏移量的十六进制表示必须以000. 但是 0 已经被包含 ELF 标头(文件的最开始)的只读段占用。第二个选择是0x1000。
为什么链接器选择 0x401000 作为文本段的虚拟地址?我不知道。我认为,如果您稍微调整链接器脚本,您将能够拥有更小的 resluting 可执行文件。
正如彼得和其他人指出的那样,可以使用-n链接器选项禁用页面大小对齐:
'-n'
'--nmagic'
Turn off page alignment of sections, and disable linking against
shared libraries[…]
Run Code Online (Sandbox Code Playgroud)
这样我得到
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
Run Code Online (Sandbox Code Playgroud)
并且可执行文件的大小降至 664 字节(stripping后为 344 )。
使用 GNU ld,您可以使用链接器脚本来精细控制链接器输出文件的布局。ld.bfd(通常也称为 just ld)如果用户没有指定一个默认链接描述文件。它可以通过 获得ld --verbose。然后您可以编辑它并提供您的版本而不是默认版本-T <your-script>。
我编辑了第一次出现
. = ALIGN(CONSTANT (MAXPAGESIZE));
Run Code Online (Sandbox Code Playgroud)
(之前.text)并获得 720(stripped时为 400 )字节。这与使用-n选项的结果不同。您仍然会获得 2 个可加载的段,它们p_align仍然是0x1000.
有p_align<MAX_PAGE_SIZE我不完全理解的效率影响。(由于更难的地址计算,页面不会加载得那么快?我认为应该有更好的解释。)如果您对此有更多了解或在哪里解释,请随意编辑答案。