Home > database >  How to compile a Hello World assembly on Windows?
How to compile a Hello World assembly on Windows?

Time:10-21

Having such a simple assembly Win 32 program:

.386
.model flat, stdcall
option casemap :none

EXTERN printf :PROC ; declare printf

.data
    HelloWorld db "Hello Wolrd!:-)", 0

.code
start:
  sub esp, 4
  push offset HelloWorld
  call printf
  add esp, 4
  ret
end start

I can successfully compile it by just:

ml.exe /c HelloWorld.asm

BUT have a problem linking it. When I use:

link HelloWorld.obj libcmt.lib

I'm getting an error:

unresolved external symbol _main called in _mainCRTStartup

What have I change/correct to to successfully link the program to run it?

P.S.

Please don't tell me to use just nasm. I'd like to use ml & link from my MSVC.

CodePudding user response:

With some minor tweaks this now builds correctly.

.386    
.model flat, c
option casemap :none

includelib libcmt.lib
includelib legacy_stdio_definitions.lib

EXTERN printf :PROC ; declare printf

.data
    HelloWorld db "Hello World!:-)", 0

.code
main PROC
  push offset HelloWorld
  call printf
  add esp, 4
  ret
main ENDP
END

The main edits are

  • .model flat, c sets the calling conventions for procedures to C.
    If you decide to keep .model flat, stdcall it'll require these changes.

Replace

EXTERN printf :PROC

main PROC 

with

printf PROTO NEAR C,:DWORD

main PROC NEAR C    
  • Included libcmt.lib and legacy_stdio_definitions.lib which statically links the native C-Runtime startup into your code.

  • Changed entry point from start to main. There's an entry point (_mainCRTStartup) within the C-Runtime library (CRT) libcmt.lib, which does some initialization tasks, and then hands off control to the entry point for your application main. You can change the default entry point, but usually you want the convenience of the initialization the CRT entry point does for you automatically.

  • Removed the first sub esp,4 so the remaining one push is balanced by the add esp,4, so ESP is pointing at the return address when ret runs.

To build, open a Windows command prompt and run:

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars32.bat"

to set the MSVC Environment initialized for: 'x86'

Next, run these MASM commands

ml.exe /c /coff HelloWorld.asm

link.exe /SUBSYSTEM:console HelloWorld.obj

The program displays

Hello World!:-)

CodePudding user response:

Your error message says that it can't find the exported symbol (i.e. function) "_main". I expect renaming your start function to _main would get it to compile.

  • Related