Skip to content

Add smaller ASM version and Makefile clean target#1

Merged
tchajed merged 2 commits intotchajed:mainfrom
acd407:main
Mar 8, 2026
Merged

Add smaller ASM version and Makefile clean target#1
tchajed merged 2 commits intotchajed:mainfrom
acd407:main

Conversation

@acd407
Copy link
Copy Markdown
Contributor

@acd407 acd407 commented Mar 8, 2026

By adjusting the compilation and linking parameters, tiny_asm_opt can be as small as tiny.

$ LC_ALL=C ls -la tiny tiny_asm_opt
-rwxr-xr-x 1 acd407 acd407 127 Mar  8 15:10 tiny
-rwxr-xr-x 1 acd407 acd407 127 Mar  8 15:10 tiny_asm_opt

This is the commands:

clang -s -Wl,--build-id=none -z noseparate-code -nostartfiles -nostdlib -static tiny.s -o tiny_asm_opt
objcopy --strip-section-headers tiny_asm_opt tiny_asm_opt
  • -s: Strips all symbol tables (.symtab and .strtab).
  • -Wl,--build-id=none: Directs the linker (ld) to omit the .note.gnu.build-id section, which normally contains a build hash.
  • -z noseparate-code: A linker option that disables the "separate code" feature. This prevents enforcement of separate, non-writable segments for code and data. Critically, it allows the ELF header, program headers, and code to reside in the same loadable segment, enabling extreme size reduction.
  • objcopy: A GNU Binutils tool for copying and transforming object files.
  • --strip-section-headers: Removes the Section Header Table and all associated section name strings.

Resulting ELF Structure

The final binary (tiny_asm_opt) consists of:

  • ELF Header: Defines file type, entry point (0x400078), and program header table location.
  • Program Header Table: Contains two LOAD segments:
    1. A minimal segment (likely for alignment/placeholder).
    2. The key segment: A read-only, executable PT_LOAD segment that starts at file offset 0 but declares a size of 0x4000 bytes. Since the actual file is only 0x7F bytes, the loader maps the entire file (including its own headers) to virtual address 0x400000 and zero-fills the remainder. This segment contains the entry point code.
  • Code: The 7-byte machine code at file offset 0x78.

Key Optimization

By declaring a segment much larger than the file, the ELF avoids trailing zero-padding for alignment. Combining the ELF header, program headers, and code into a single executable segment—and then stripping non-essential section headers—achieves the minimal possible size while remaining a valid, executable ELF file.

acd407 added 2 commits March 8, 2026 15:17
Use the compilation and linking parameters of clang to generate a binary
as small as tiny.
@tchajed
Copy link
Copy Markdown
Owner

tchajed commented Mar 8, 2026

Thanks, this is cool!

@tchajed tchajed merged commit b7ab000 into tchajed:main Mar 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants