c - 为什么 ld 将我的 5 行无库 C 代码变成了 100MB 的二进制文件?
问题描述
我正在尝试按照本文档开发一些非常低级的 x86 代码。我编写了以下 C 程序:
void main()
{
char* video_memory = (char*) 0xb8000;
*video_memory = 'X';
}
我像这样编译和链接它:
gcc -m32 -fno-pie -c main.c -o main.o
ld -m elf_i386 -o main.bin -Ttext 513 --oformat binary main.o
main.bin
这会产生一个超过一百兆字节的二进制文件。我反汇编了那个二进制文件,它基本上是我的代码(大约十行),然后是一百兆的零,然后是某种页脚。
额外的字节都是不必要的,因为我曾经head
剪掉那些不是我的代码的,它仍然运行良好。
我正在使用 32 位标志,因为我的测试机器是一台旧的 32 位笔记本电脑,但您可以在 64 位中获得类似(但不那么极端)的行为。这个脚本:
gcc -fno-pie -c main.c -o main.o
ld -o main.bin -Ttext 513 --oformat binary main.o
产生main.bin
超过 4 MB 的 a。同样,模式是相同的:我的代码,4 兆零,然后是页脚。我的代码和零之间有一点噪音。这是反汇编的 4MB 文件:
0: f3 0f 1e fa endbr64
4: 55 push %ebp
5: 48 dec %eax
6: 89 e5 mov %esp,%ebp
8: 48 dec %eax
9: c7 45 f8 00 80 0b 00 movl $0xb8000,-0x8(%ebp)
10: 48 dec %eax
11: 8b 45 f8 mov -0x8(%ebp),%eax
14: c6 00 58 movb $0x58,(%eax)
17: 90 nop
18: 5d pop %ebp
19: c3 ret
...
aea: 00 00 add %al,(%eax)
aec: 00 14 00 add %dl,(%eax,%eax,1)
aef: 00 00 add %al,(%eax)
af1: 00 00 add %al,(%eax)
af3: 00 00 add %al,(%eax)
af5: 01 7a 52 add %edi,0x52(%edx)
af8: 00 01 add %al,(%ecx)
afa: 78 10 js 0xb0c
afc: 01 1b add %ebx,(%ebx)
afe: 0c 07 or $0x7,%al
b00: 08 90 01 00 00 1c or %dl,0x1c000001(%eax)
b06: 00 00 add %al,(%eax)
b08: 00 1c 00 add %bl,(%eax,%eax,1)
b0b: 00 00 add %al,(%eax)
b0d: f3 f4 repz hlt
b0f: ff (bad)
b10: ff 1a lcall *(%edx)
b12: 00 00 add %al,(%eax)
b14: 00 00 add %al,(%eax)
b16: 45 inc %ebp
b17: 0e push %cs
b18: 10 86 02 43 0d 06 adc %al,0x60d4302(%esi)
b1e: 51 push %ecx
b1f: 0c 07 or $0x7,%al
b21: 08 00 or %al,(%eax)
...
3ffaeb: 00 00 add %al,(%eax)
3ffaed: 04 00 add $0x0,%al
3ffaef: 00 00 add %al,(%eax)
3ffaf1: 10 00 adc %al,(%eax)
3ffaf3: 00 00 add %al,(%eax)
3ffaf5: 05 00 00 00 47 add $0x47000000,%eax
3ffafa: 4e dec %esi
3ffafb: 55 push %ebp
3ffafc: 00 02 add %al,(%edx)
3ffafe: 00 00 add %al,(%eax)
3ffb00: c0 04 00 00 rolb $0x0,(%eax,%eax,1)
3ffb04: 00 03 add %al,(%ebx)
3ffb06: 00 00 add %al,(%eax)
3ffb08: 00 00 add %al,(%eax)
3ffb0a: 00 00 add %al,(%eax)
...
巨大的二进制文件有效,但它很难看,我想了解发生了什么。
我正在 64 位机器上的 Ubuntu 20.20 上进行编译/链接。工具版本:
gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)
GNU ld (GNU Binutils for Ubuntu) 2.34
解决方案
推荐阅读
- javascript - 仅在 IE11 中出现未定义的 JS 错误
- php - 如何通过dbutil导入codeigniter导出的sql文件
- java - 如何在不影响其他节点的情况下为 DropShadow 设置动画?
- arrays - 排序数组中的时间复杂度
- mysql - mysql : 在存储过程中传递 sql 语句作为参数来执行它
- python - matplotlib 不显示图像
- laravel - Laravel 页面显示“此页面不起作用”而不是错误
- sorting - 在 Kotlin 中对集合进行排序和分组的简洁方法是什么?
- vhdl - 编译时出错:“非法顺序语句”
- identityserver4 - 为什么 Identity Server4 注销不起作用?(没有 MS 身份)