I was trying to make a tiny hello world executable in Linux but the smallest I could get was a bit over 8k.
I have been following this article. In that article, the author is iteratively making smaller and smaller executables. At some point in it, it provides the following code for NASM:
; tiny.asm
BITS 32
GLOBAL _start
SECTION .text
_start:
mov eax, 1
mov ebx, 42
int 0x80
and this should be the commands to compile it:
nasm -f elf tiny.asm
gcc -Wall -s -nostdlib tiny.o
According to the author, the executable size at that point should be 372 bytes. However, for me it's more than 12KBytes. The only thing I did differently is adding the -m32 to gcc so it compiles as 32 bits.
I manged to get it down to a bit over 8KBytes by using ld
for linking instead of gcc
and then using strip
.
ld -m elf_i386 -s tiny.o
strip -s a.out
But it's still to large compered to the result in the article. Am I missing anything? I guess the article is quite old since it's compiling 32 bits by default. Could it be that newer Linux versions require bigger executables?
EDIT: code for my hello world program:
SECTION .data
msg: db "hello",10
msgLen: equ $ - msg ; the $ sign means the current byte address. That means the address where the next byte would go
SECTION .text
global _start ; "global" means that the symbol can be accessed in other modules. In order to refer to a global symbol from another module, you must use the "extern" keyboard
_start:
mov eax, 4 ; syscall: write
mov ebx, 1 ; stdout
mov ecx, msg
mov edx, msgLen
int 0x80 ; call!
mov eax, 1 ; syscal: exit
mov ebx, 0 ; return code
int 0x80