You are not logged in.

#1 2020-11-25 14:13:50

esonn
Member
From: Austria
Registered: 2015-10-01
Posts: 61

[Solved] x86 assembly: executable size now 10x larger than 2 years ago

For a university course, I like to compare code-sizes of functionally similar programs if written and compiled using gcc/clang versus writing it in assembly. Now I just re-evaluated how to further shrink the executable code size and I couldn't trust my eyes when the very same assembly code I assembled/linked 2 years ago now has grown >10x in size!

$ make
as -32 -o helloworld-asm-2020.o helloworld-asm-2020.s
ld -melf_i386 -o helloworld-asm-2020 helloworld-asm-2020.o

$ ls -l
-rwxr-xr-x 1 xxx users   708 Jul 18 2018 helloworld-asm-2018*
-rwxr-xr-x 1 xxx users  8704 Nov 25 15:00 helloworld-asm-2020*
-rwxr-xr-x 1 xxx users  4724 Nov 25 15:00 helloworld-asm-2020-n*
-rwxr-xr-x 1 xxx users  4228 Nov 25 15:00 helloworld-asm-2020-n-sstripped*
-rw-r--r-- 1 xxx users   498 Nov 25 14:44 helloworld-asm-2020.s

The same hello world program, compiled using GNU as and GNU ld (always using 32-bit assembly + linking) was 708 bytes then, and has grown to 8.5K now. Even when telling the linker to turn off page alignment (ld -n), it still has almost 4.2K. stripping/sstripping doesn't pay off either.

readelf tells me that the start of section headers is much later in the code (byte 468 vs 8464), but I have no idea why. It's running on the same arch system as in 2018, the Makefile is the same and I'm not linking against any libraries (especially not libc). Any idea how this can happen?

Edit: Wording.

Last edited by esonn (2020-12-01 13:11:08)


Anyone who quotes me in their sig is an idiot. -- Rusty Russell

Offline

#2 2020-12-01 13:10:22

esonn
Member
From: Austria
Registered: 2015-10-01
Posts: 61

Re: [Solved] x86 assembly: executable size now 10x larger than 2 years ago

Update:
I fiddled around with virtually every linker option, none of which significantly shrinked the executable. However, I noticed that GNU binutils includes two different linkers, namely ld.gold and ld.bfd. When using ld.gold instead of ld.bfd (to which /usr/bin/ld is symlinked to by default), the executable size becomes as small as expected:
   

    $ cat Makefile 
    TARGET=helloworld
    all:
    	as -32 -o ${TARGET}-asm.o ${TARGET}-asm.s
    	ld.bfd -melf_i386 -o ${TARGET}-asm-bfd ${TARGET}-asm.o
    	ld.gold -melf_i386 -o ${TARGET}-asm-gold ${TARGET}-asm.o
    	rm ${TARGET}-asm.o
    
    $ make -q
    $ ls -l
    total 68
    -rw-r--r-- 1 eso eso   200 Dec  1 13:57 Makefile
    -rwxrwxr-x 1 eso eso  8700 Dec  1 13:57 helloworld-asm-bfd
    -rwxrwxr-x 1 eso eso   732 Dec  1 13:57 helloworld-asm-gold
    -rw-r--r-- 1 eso eso   498 Dec  1 13:44 helloworld-asm.s

Maybe I just used ld.gold two years ago without being aware of it. gold apparently can't build anything else than ELF, but why would I want to compile anything else? :-) Anyway, marking as solved.


Anyone who quotes me in their sig is an idiot. -- Rusty Russell

Offline

Board footer

Powered by FluxBB