如何减小NASM汇编生成的可执行文件体积?32位ELF Hello World优化问题
体积偏大的原因
你对汇编器的理解是正确的:NASM确实只是把汇编指令翻译成对应的二进制机器码,你生成的hello.o目标文件里的有效指令+数据总共才几十字节,体积偏大完全是链接生成ELF可执行文件时的默认规则导致的,从你提供的readelf输出可以看到两个核心原因:
- 页对齐浪费:ld默认将ELF的LOAD段按4KB(0x1000)对齐,你的代码段偏移被硬拉到了0x1000的位置,前面4KB的空间仅存储了ELF头和程序头,几乎全是空白。
- 多余运行时不需要的节:默认链接会保留符号表
.symtab、字符串表.strtab、节名表.shstrtab等用于调试、重定位的节,这些内容运行时完全用不到,额外占用了数百字节的空间。
减小体积的实操方法
1. 基础优化(无需改代码)
链接时添加--strip-all剔除所有符号和调试信息,加-n关闭页对齐规则,指令如下:
nasm -f elf32 hello.asm -o hello.o ld -m elf_i386 hello.o -o hello --strip-all -n
执行完这一步后,可执行文件体积会直接降到300字节以内。
2. 优化汇编代码进一步压缩
你当前拆分了.text和.data两个段,额外增加了段表开销,可以直接把字符串放到.text段(x86下可读权限的段都能正常访问字符串),同时用更短的指令替换长指令,修改后的代码如下:
; hello.asm section .text global _start _start: mov eax, 4 mov ebx, 1 mov ecx, msg mov edx, 11 ; "hello world"共11个字符,不需要多余长度 int 0x80 mov eax, 1 xor ebx, ebx ; 等价于mov ebx, 0,机器码短2字节 int 0x80 msg: db "hello world"
重新用上面的优化链接指令编译后,体积可以进一步降到150字节左右。
3. 极致压缩(进阶玩法)
如果追求极限体积,可以手动构造ELF文件结构,把ELF头、程序头、机器指令、字符串全部合并到连续的空间,不需要NASM和ld生成的冗余结构,最终可以做到不超过50字节的可执行Hello World。
内容的提问来源于stack exchange,提问作者ZeroSkill Gaming
相关产品推荐
相关产品推荐

