The issue!
I have started learning assembly language and am facing some difficulty compiling my program.
option casemap:none
.data
fmtStr byte 'Hello, world!', 10, 0
.code
externdef printf:proc
main proc
sub rsp, 56
lea rcx, fmtStr
call printf
add rsp, 56
ret
main endp
end
I have successfully compiled my assembly file to object file using the following command.
ml64 /c main.asm
The problem arises when I try to compile the resulting main.obj
using the following command.
link main.obj /subsystem:console /entry:main /out:main.exe
The printf symbol was missing. So
I did some research and found that I need to link kernel32.lib
, legacy_stdio_definitions.lib
and msvcrt.lib
to get this to work. So I linked those files as well but then got the following error.
LINK : fatal error LNK1104: cannot open file 'legacy_stdio_wide_specifiers.lib'
So I included that file as well and ran the following command.
link main.obj /subsystem:console /entry:main /out:main.exe "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\kernel32.Lib" "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64\legacy_stdio_definitions.lib" "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64\legacy_stdio_wide_specifiers.lib" "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64\msvcrt.lib"
Now I am getting the following errors and my current theory is that I need to link more files but can't figure out which ones.
Microsoft (R) Incremental Linker Version 14.29.30148.0
Copyright (C) Microsoft Corporation. All rights reserved.
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __acrt_iob_func referenced in function _vwprintf_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vfwprintf referenced in function _vfwprintf_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vfwprintf_s referenced in function _vfwprintf_s_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vfwprintf_p referenced in function _vfwprintf_p_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vfwscanf referenced in function _vfwscanf_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vswprintf referenced in function _vsnwprintf_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vswprintf_s referenced in function _vswprintf_s_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vsnwprintf_s referenced in function _vsnwprintf_s_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vswprintf_p referenced in function _vswprintf_p_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vswscanf referenced in function _vswscanf_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vfprintf referenced in function _vfprintf_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vfprintf_s referenced in function _vfprintf_s_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vfprintf_p referenced in function _vfprintf_p_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vfscanf referenced in function _vfscanf_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vsprintf referenced in function _vsnprintf_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vsprintf_s referenced in function _vsprintf_s_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vsnprintf_s referenced in function _vsnprintf_s_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vsprintf_p referenced in function _vsprintf_p_l
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : error LNK2019: unresolved external symbol __stdio_common_vsscanf referenced in function _vsscanf_l
main.exe : fatal error LNK1120: 19 unresolved externals
At this point I ditched link.exe
and use gcc
to compile my code and it successfully compiled!
gcc main.obj -o main.exe
My questions
What can I do to link my object files using
link.exe
.Trying to figure out a solution I came across the following compilers and linkers, some of them I was a little familiar with, and some of them were a new discovery to me.
ml64
link
gcc
ld
cl
Some of them are microsoft compilers and linkers some are gnu compilers and linkers. What are the differences between these compilers and linkers and when should I use which ones? (I use a windows amd machine if that's needed)
The assembly code that I have provided here is the one that I copied from a book with some changes. In that book the author was linking an assembly compiled
.obj
file and aC
compiled.obj
and was calling the function inC
defined inassembly
to writeHello, World!
in the console. I made some changes here to make this a standaloneassembly
program but still don't understand the program properly, e.g., what is the use ofsub
andadd
instructions. So a brief explanation of the program will be appreciated.I noticed that there is an
entry
flag available to us inlink
. My assumption for now is that is specifies where the program/instructions begin. So, if I replaced all themain
keywords in the assembly code with let's saystart
and used/entry:start
as one of the flags, will the program compile and work as intended? (assuming that I managed to compile the program usinglink
in the first place)