For 32-bit ELF object files you may try to use Smaller C's linker, smlrl.
Code:
int add(int a, int b) { return a + b; }
int one = 1;
int two = 2;
void _start(void) { add(one, two); }
Compiling:
Code:
$ smlrcc -c -o bin.o bin.c
$ smlrl -flat32 -origin 0x80000 -o bin.bin bin.o
Disassembly:
Code:
$ ndisasm -b32 -o0x80000 bin.bin
00080000 E916000000 jmp dword 0x8001b
00080005 CC int3
00080006 CC int3
00080007 CC int3
00080008 CC int3
00080009 CC int3
0008000A CC int3
0008000B CC int3
0008000C CC int3
0008000D CC int3
0008000E CC int3
0008000F CC int3
00080010 55 push ebp
00080011 89E5 mov ebp,esp
00080013 8B4508 mov eax,[ebp+0x8]
00080016 03450C add eax,[ebp+0xc]
00080019 C9 leave
0008001A C3 ret
0008001B 55 push ebp
0008001C 89E5 mov ebp,esp
0008001E FF3538000800 push dword [dword 0x80038]
00080024 FF3534000800 push dword [dword 0x80034]
0008002A E8E1FFFFFF call dword 0x80010
0008002F 83ECF8 sub esp,byte -0x8
00080032 C9 leave
00080033 C3 ret
00080034 0100 add [eax],eax
00080036 0000 add [eax],al
00080038 0200 add al,[eax]
0008003A 0000 add [eax],al
You don't have to use the entire compiler for this, just the linker. However, note that ELF object files produced by other compilers may not be fully supported.