Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Saturday, May 30, 2020 4:39 PM
I am programming in assembly x64 and the 2 lines that cause the errors are:
extern ExitProcess
extern printf
The command that compiles the asm is:
nasm -f win64 -o hello_world.obj hello_world.asm
I'm using Visual Studio 2017 to link the .obj file and the command is:
link hello_world.obj /subsystem:console /entry:main /out:hello_world_basic.exe
The output of the command is:
hello_world.obj : error LNK2001: unresolved external symbol ExitProcess
hello_world.obj : error LNK2001: unresolved external symbol printf
hello_world_basic.exe : fatal error LNK1120: 2 unresolved externals
All replies (11)
Saturday, May 30, 2020 7:15 PM
Try
* extern _printf*
Saturday, May 30, 2020 8:03 PM
I tried that just now and nasm says: symbol 'printf' undefined.
Saturday, May 30, 2020 8:09 PM
Try using _printf instead of printf (in all of the places).
Saturday, May 30, 2020 9:30 PM
The error still appeared but for _printf.
Saturday, May 30, 2020 9:36 PM
Maybe try linking with legacy_stdio_definitions.lib
Saturday, May 30, 2020 10:15 PM
How do I do link with legacy_stdio_definitions.lib?
Saturday, May 30, 2020 11:28 PM
Specify the library as an input to the linker in the command line parameters.
Saturday, May 30, 2020 11:42 PM
All of it works now but this error pops up:
legacy_stdio_definitions.lib(legacy_stdio_definitions.obj) : fatal error LNK1112: module machine type 'x86' conflicts with target machine type 'x64'
Sunday, May 31, 2020 12:13 AM
You need to set up your command line build environment so that the 64 bit versions of libraries are found
Sunday, May 31, 2020 1:24 AM
When I open x64 Native Tools, navigate to the correct directory, and run:
link hello_world.obj /subsystem:console /entry:main legacy_stdio_definitions.lib /out:hello_world_basic.exe
The same error as I had at the start pops up.
Sunday, May 31, 2020 2:26 AM
I don't. These are the steps that I follow to get this to work.
1) Run the x64 Native Tools Command Prompt VS 2019.
2) Run the following commands:
These are change to the working directory (this is where the .asm file is). Add nasm.exe to the path so I can call it without the full path. Run nasm and then finally run the linker. I ran the executable at the end for good measure.
Now, two points of note here. First I linked with kernel32.lib and msvcrt.lib. Kernel32 is needed as a base for even console applications and msvcrt.lib to link to the basic CRT. This is to get the stdio initialisation to occur before I call printf.
Second because I am linking against the CRT, main is being called from the CRT entry point, hence I don't set the /entry option for the linker.
Now this is important because for the simple example I was using:
global main
extern printf
section .data
msg db "Hello World!", 13, 10, 0
section .text
main:
sub rsp, 8
sub rsp, 32
mov rcx, qword msg
call printf
add rsp, 32
xor eax, eax
add rsp, 8
ret
There is no additional initialisation of stdio, and in this case printf will not work unless you let the CRT initialise itself. So I use main and link against msvcrt.lib to let the linker bring in the CRT and initialise stdio. If you are doing the extra work to initialise the CRT then you can ignore this, but I would suggest you use a name other than main for the main function.
This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.