Question

I wrote two equivalent programs in C and x86 assembly:

.386
.model small
INCLUDELIB MSVCRT
EXTRN _printf:NEAR
.data
msg db "Hello World", 10, 0
.code
main PROC
    push ebp
    mov ebp, esp
    lea eax, msg
    push eax
    call _printf
    add esp, 4
    mov esp, ebp
    pop ebp
    ret 0
main ENDP
END

#include <stdio.h>
int main()
{
    printf("Hello World\n");
    return 0;
}

I compiled the assembly one with: ml hello.asm /link /ENTRY:main /SUBSYSTEM:CONSOLE

And the C one with: cl /O1 /MD hello.c

The /O1 switch is supposed to minimize space and the /MD switch links with MSVCRT.LIB rather than LIBCMT (which is the same thing in my assembly program).

However, when I examine the actual executables the C one is actually twice the size of the assembly one:

2014-02-08  10:48 AM             3,072 hello.exe
2014-02-08  10:53 AM             6,144 hello_c.exe

Doing a DUMPBIN /DISASM on both shows that the assembly one only generates the exact instructions I specified whereas the C one generates several hundred times more...

Does anyone have an explanation as to why an optimizing compiler that was asked to minimize space still produces worse results than an assembly program?

Was it helpful?

Solution

I believe its because of the extra boilerplate code added by the C runtime. It has to setup for atexit, command line arguments, etc. If you're really curious, disassemble them with the free demo version of IDA Pro (https://www.hex-rays.com/products/ida/support/download_demo.shtml)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top