Skip to content

Add ARM32 assembly variant — 44% smaller#5

Merged
widgetii merged 1 commit intomasterfrom
asm-variant
Apr 3, 2026
Merged

Add ARM32 assembly variant — 44% smaller#5
widgetii merged 1 commit intomasterfrom
asm-variant

Conversation

@widgetii
Copy link
Copy Markdown
Member

@widgetii widgetii commented Apr 3, 2026

Summary

Hand-written ARM32 assembly rewrite of uget that is functionally identical but significantly smaller.

Variant Size (hisiv510) bin2sh script
uget (C) 4680 bytes 14532 bytes
uget-asm (ARM32) 2632 bytes 7965 bytes

How it works

  • Uses raw Linux syscalls (SVC #0) instead of libc wrappers for: write, close, fork, execve, wait4, fchmod, unlink, socket, connect, sendto, recvfrom
  • Custom _start entry point — no CRT startup (.init/.fini, __uClibc_main, frame registration)
  • All string operations inlined (strcmp, strstr, memset, memcpy)
  • Only 2 PLT imports remain: gethostbyname (DNS) and mkstemp (temp file)

Per-toolchain sizes

Toolchain C ASM Savings
hisiv300 uClibc 4688 2632 43%
hisiv500 uClibc 4680 2632 43%
hisiv510 uClibc 4680 2632 43%
hisiv600 glibc 4908 2588 47%
himix100 uClibc 4996 4676 6%
himix200 glibc 5204 4784 8%

himix toolchains show less savings due to linker segment page-alignment padding (~2KB of zeroes between text and data segments), not from larger code.

Test plan

  • 24/24 qemu-arm tests pass locally (4 tests × 6 toolchains)
  • 48 CI tests pass (8 tests × 6 toolchains: 4 for uget + 4 for uget-asm)

🤖 Generated with Claude Code

Hand-written ARM32 assembly rewrite that is functionally identical to
the C version but significantly smaller by:
- Using raw Linux syscalls instead of libc wrappers (write, close,
  fork, execve, wait4, fchmod, unlink, socket, connect, sendto, recvfrom)
- Eliminating CRT startup (no .init/.fini, no __uClibc_main)
- Inlining string operations (strcmp, strstr, memset, memcpy)
- Only 2 PLT imports remain: gethostbyname and mkstemp

Size comparison (stripped, hisiv510 toolchain):
  C version:   4680 bytes, bin2sh script: 14532 bytes
  ASM version: 2632 bytes, bin2sh script:  7965 bytes

Tested on all 6 toolchains via qemu-arm (48 tests: 8 per toolchain).

Also updates:
- Makefile: adds uget-asm target
- CI: builds and tests both variants, includes both in release artifacts
- README: documents both variants

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@widgetii widgetii merged commit 8865d75 into master Apr 3, 2026
7 checks passed
@widgetii widgetii deleted the asm-variant branch April 3, 2026 17:40
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.

1 participant