flat assembler
Message board for the users of flat assembler.

Index > Heap > Optimization of C code

Author
Thread Post new topic Reply to topic
strelok_ciberi



Joined: 14 Mar 2011
Posts: 3
strelok_ciberi
I've noticed that a simple "Hello World" in C means near 20 Ko on the disk (on windows). Could someone tell me if there is a way to reduce this size, without any system interruptions because of windows' constraints... (i tried -O3 options in gcc but it doesnt change the size)
Post 14 Mar 2011, 18:42
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4240
Location: 2018
edfed
code in assembler.
Post 14 Mar 2011, 19:32
View user's profile Send private message Visit poster's website Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler
-ON, where N is a number, is for speed. -Os is for size.

It's 20kB for the libraries and other stuff to which it is linked. The actual size of the code is about as minuscule as you'd expect. To see the exact code, pass the -S option and it will translate the C to AT&T asm and give you that, rather than finishing the compilation.
Post 14 Mar 2011, 19:36
View user's profile Send private message Reply with quote
Coty



Joined: 17 May 2010
Posts: 546
Location: ␀
Coty
edfed wrote:
code in assembler.

This Very Happy

Tyler wrote:
It's 20kB for the libraries and other stuff to which it is linked. The actual size of the code is about as minuscule as you'd expect.

In the end, it is a 20kb binary with slow and bloated library. No matter if your code is only 23 bytes, the computer is not going to go faster because the part you wrote is only 23bytes.
Post 14 Mar 2011, 21:19
View user's profile Send private message Send e-mail Visit poster's website AIM Address Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Depends on which C compiler (on which OS) and what libraries you use, and how you link them (statically / dynamically). Things like "printf" require extra code, which has to be either in dynamically linked library, or inside your executable. You need to learn what to (not) use if "size matters" to you, and how to tell compiler whether to use dynamic or link static library into final executable.

Here's example of minimal (equivalent to what you'd write in ASM) win32 hello world, using only system API and no statically linked library code:
Code:
#include <windows.h>

const char string[] = "Hell 'o World";

int main(int argc, char **argv)
{
 DWORD written;
      WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), string, sizeof(string)-1, &written, 0);
      return 0;
}    


Compile with MS Visual C/C++:
Code:
cl test.c /link /nodefaultlib /entry:main /subsystem:console /merge:.rdata=.text kernel32.lib    


Resulting executable has 1KB, the minimal possible size of proper valid executable. Compiled with optimization enabled, contents of executable are (in this case!) pretty much exactly the same thing you'd write in assembly:
Code:
00401000 > . D92F817C       DD kernel32.GetStdHandle
00401004 > . 270E817C       DD kernel32.WriteFile
00401008     00000000       DD 00000000
0040100C   . 48 65 6C 6C 20>ASCII "Hell 'o World",0
0040101A     00             DB 00
0040101B     00             DB 00
0040101C     00             DB 00
0040101D     00             DB 00
0040101E     00             DB 00
0040101F     00             DB 00
00401020 >/$ 51             PUSH ECX
00401021  |. 6A 00          PUSH 0                                   ; /pOverlapped = NULL
00401023  |. 8D4424 04      LEA EAX,[ESP+4]                          ; |
00401027  |. 50             PUSH EAX                                 ; |pBytesWritten
00401028  |. 6A 0D          PUSH 0D                                  ; |nBytesToWrite = D (13.)
0040102A  |. 68 0C104000    PUSH 0040100C                            ; |Buffer = a.0040100C
0040102F  |. 6A F5          PUSH -0B                                 ; |/DevType = STD_OUTPUT_HANDLE
00401031  |. FF15 00104000  CALL [<&KERNEL32.GetStdHandle>]          ; |\GetStdHandle
00401037  |. 50             PUSH EAX                                 ; |hFile
00401038  |. FF15 04104000  CALL [<&KERNEL32.WriteFile>]             ; \WriteFile
0040103E  |. 33C0           XOR EAX,EAX
00401040  |. 59             POP ECX
00401041  \. C3             RETN
00401042     CC             INT3
00401043     CC             INT3
00401044   . 6C100000       DD 0000106C                              ;  Struct 'IMAGE_IMPORT_DESCRIPTOR'
00401048   . 00000000       DD 00000000
0040104C   . 00000000       DD 00000000
00401050   . 94100000       DD 00001094
00401054   . 00100000       DD 00001000
00401058   . 00000000       DD 00000000                              ;  Struct 'IMAGE_IMPORT_DESCRIPTOR'
0040105C   . 00000000       DD 00000000
00401060   . 00000000       DD 00000000
00401064   . 00000000       DD 00000000
00401068   . 00000000       DD 00000000
0040106C   . 84100000       DD 00001084                              ;  Import lookup table for 'KERNEL32.dll'
00401070   . 78100000       DD 00001078
00401074   . 00000000       DD 00000000
00401078   . 8D04           DW 048D
0040107A   . 57 72 69 74 65>ASCII "WriteFile",0
00401084   . 3B02           DW 023B
00401086   . 47 65 74 53 74>ASCII "GetStdHandle",0
00401093   . 00             DB 00
00401094   . 4B 45 52 4E 45>ASCII "KERNEL32.dll",0
    


Something similar should be possible on every normal platform with every normal compiler.
Post 14 Mar 2011, 22:02
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
For a smaller Win32 LIBC, check out WCRT.

But really, unless you're doing 64kb intros, don't worry about it. 20kb is very, very, very little... and once you go beyond "Hello, world" and write a decent-sized program, the percentage of size taken by libc in your application is going to get smaller and smaller.
Post 19 Mar 2011, 11:28
View user's profile Send private message Visit poster's website Reply with quote
strelok_ciberi



Joined: 14 Mar 2011
Posts: 3
strelok_ciberi
How should I compile this Hello World file with gcc please ?
Actually, my problematic is to find a way to call a windows' API without loading a full library in memory. Of course 20Ko is very little, but it's not the point. The point is that i wrote a 1ko-source, and the result is 20Ko... 20 times too much :p And I'm convinced that it's not necessary.
Also, it would be nice if someone give me a Hello World source file in asm without including any library.
Post 19 Mar 2011, 19:12
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler
You can't print without including a library, no matter what language it's coded in.
Post 19 Mar 2011, 22:55
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler
Have you tried compiling without debug symbols? I don't know how big of an effect it will have, but try it, if you haven't already.
Post 19 Mar 2011, 23:24
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Hmm, seems that GCC always has to link at least libgcc... I am no GCC guru, but is this is so, that kinda sucks in comparison to MSVC.
Post 20 Mar 2011, 00:53
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
strelok_ciberi



Joined: 14 Mar 2011
Posts: 3
strelok_ciberi
So i have to use msvc... Or to make my own compiler x)
Post 20 Mar 2011, 12:08
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
vid wrote:
Hmm, seems that GCC always has to link at least libgcc... I am no GCC guru, but is this is so, that kinda sucks in comparison to MSVC.
Visual C++, especially never versions, also depend on VC-specific imports for certain stuff - if you don't want to link against libc, you'll have to define those yourself.

strelok_ciberi wrote:
Actually, my problematic is to find a way to call a windows' API without loading a full library in memory. Of course 20Ko is very little, but it's not the point. The point is that i wrote a 1ko-source, and the result is 20Ko... 20 times too much :p And I'm convinced that it's not necessary.
Depends on how you look at things. If you do normal C/C++ programming, and you're doing more than "Hello World", you'll likely be using a lot of libc functions. If you use those functions, it's not wasted space.

Again, take a look at Jibz' WCRT, it's a minimal libc that tries to do as much as possible through direct API calls. This might sometimes mean slower code than a "normal" libc, and not as full range of C++ support, but also less overhead.

_________________
Image - carpe noctem
Post 20 Mar 2011, 13:20
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Quote:
Visual C++, especially never versions, also depend on VC-specific imports for certain stuff - if you don't want to link against libc, you'll have to define those yourself.

What "certain stuff" do you mean? Something that's needed for pure C and can't be disabled? (like __main appears to be in mingw-gcc)
Post 20 Mar 2011, 16:46
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
The only two I can remember off top of my head for pure C would be for stack probing and flot->int conversions - both can be disabled via compiler switches, but will result in slightly different runtime behavior; whether this affects you depends on your software.

For C++, there's all sorts of exception handling stuff, stack unwinding, whatnot. Unlike the rest of libc, the sources for those aren't included with VC++, only the binary .obj files.
Post 20 Mar 2011, 17:32
View user's profile Send private message Visit poster's website Reply with quote
wht36



Joined: 18 Sep 2005
Posts: 106
wht36
Use -s -Os switch with gcc will bring it down to 7kb if using printf.

#include <stdio.h>

main()
{
printf("hello, world\n");
}
Post 23 Sep 2011, 08:07
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.