简体   繁体   中英

How to compile a Hello World assembly on Windows?

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?

PS

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

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!:-)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM