Reputation: 1934
This is my first trial running an assembly code for x64 in MASM:
_text SEGMENT
main PROC
mov ah,0
ret
main ENDP
_text ENDS
END
and I'm getting a linker error LNK2001: unresolved external symbol mainCRTStartup
. Why?
I have the entry point main
in Properties > Linker > Advanced > Entry Point
P.S.: the code assembles and executes as expected in x86.
Upvotes: 1
Views: 702
Reputation: 2259
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.
There are two methods to avoid LNK2001: unresolved external symbol mainCRTStartup.
Add libcmt.lib to the link command:
(C-Runtime initialization calls main)
ml64.exe test64.asm /link /DEBUG /subsystem:console /defaultlib:kernel32.lib /defaultlib:user32.lib /defaultlib:libcmt.lib
Specify the entry point main on the link command:
(Avoids C-Runtime initialization and calls main)
ml64.exe test64.asm /link /DEBUG /subsystem:console /defaultlib:kernel32.lib /defaultlib:user32.lib /entry:main
Here's some example MASM64 code to popup a window:
test64.asm
option casemap:none
externdef MessageBoxA : near
externdef ExitProcess : near
.data
szDlgTitle db "MASM 64-bit",0
szMsg db "HELLO",0
.code
main proc
; Reserve 28h bytes of shadow space.
sub rsp, 28h
xor r9d, r9d
lea r8, szDlgTitle
lea rdx, szMsg
xor rcx, rcx
call MessageBoxA
add rsp, 28h
; rax contains the ExitCode from MessageBoxA(...)
; When the primary thread's entry-point function main returns,
; it returns to the C/C++ Runtime startup code,
; which properly cleans up all the C Runtime resources used by the process.
;
; After the C Runtime resources have been freed,
; the C Runtime startup code explicitly calls ExitProcess,
; passing it the value returned from the entry-point function.
; This explains why simply returning from the primary thread's entry-point function terminates the entire process.
; Note that any other threads running in the process terminate along with the process.
ret
main endp
end
To build test64.exe, I use these batch commands:
makeit64.bat
@echo on
if not defined DevEnvDir (
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
)
ml64.exe test64.asm /link /subsystem:console /defaultlib:kernel32.lib /defaultlib:user32.lib /defaultlib:libcmt.lib
The output is
Upvotes: 2