3

I have the following 'hello world' NASM assembly code

bits 64
default rel

segment .data
    msg db "Hello world!", 0

segment .text
global main

extern puts

main:
    sub     rsp, 40

    lea     rcx, [msg]
    call    puts

    xor     rax, rax
    add     rsp, 40
    ret

and I can build the code with the following commands

nasm -f win64 -gcv8 -o hello.obj hello.asm
link hello.obj /subsystem:console /entry:main /defaultlib:msvcrt.lib /defaultlib:ucrt.lib /defaultlib:Kernel32.lib /nologo /incremental:no /opt:noref /debug /pdb:hello.pdb /out:hello.exe

Everything works but I would prefer to link with the CRT statically. I'm trying the following link step instead, using what I think are the correct libraries.

link hello.obj /subsystem:console /entry:main /defaultlib:libcmt.lib /defaultlib:libucrt.lib /defaultlib:Kernel32.lib /nologo /incremental:no /opt:noref /debug /pdb:hello.pdb /out:hello.exe

Although the link succeeds, the program produces no output when run. There's also a noticable pause when it runs, I assume it's crashing.

What am I doing wrong? What do I need to do differently to statically link with the C runtime?

Thanks

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
john
  • 85,011
  • 4
  • 57
  • 81
  • 1
    Don't use `/entry:main`. You need to use the CRT's entry point. The linker should use the correct entry point by default. – Ross Ridge Nov 23 '20 at 20:49
  • @RossRidge Thanks, that solved it. So by using `/entry:main` I was skipping some CRT initialization code? – john Nov 23 '20 at 21:14
  • Yup. The DLL CRT has it's own entry point that gets called when the DLL gets loaded, but the static CRT needs to use the executable's entry pont. – Ross Ridge Nov 23 '20 at 21:32

0 Answers0