4
        .386
        .model flat, c
        .stack 100h
printf  PROTO arg1:Ptr Byte

        .data
msg1    byte "Hello World!", 0Ah, 0

        .code
main    proc
        INVOKE printf, ADDR msg1
        ret

main    endp
        end main

Hi, I am getting the below errors:

I searched around and found someone said that it can be fixed by linking the microsoft runtime library

Can anyone teach me how can I exactly fix it?

Thanks

Severity    Code    Description Project File    Line    Suppression State
Error   LNK2019 unresolved external symbol _printf referenced in function _main testing C:\Users\Kin\Desktop\assembly\testing\testing\Source.obj    1   
Error   LNK1120 1 unresolved externals  testing C:\Users\Kin\Desktop\assembly\testing\Debug\testing.exe 1   
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
kireinasora
  • 323
  • 1
  • 3
  • 10
  • Although this other answer was written with VS 2015 in mind, it more than likely applies to VS 2017: http://stackoverflow.com/questions/33721059/call-c-standard-library-function-from-asm-in-visual-studio . There are a couple of answers with possible solutions. – Michael Petch May 20 '17 at 20:01
  • Hi Michael, I have read the post and tried the three mentioned methods, but not working on 2017version, I can't even change to 2013 v120, using the second and third method, I can compile successfully, but literally nothing happened when I opened the exes file~ – kireinasora May 20 '17 at 20:08
  • I'm curious. If you take the code as is (*no alterations whatsoever*) and compile it what is the result when run? That code is in this answer: http://stackoverflow.com/a/33725587/3857942 . I'm just asking because I have yet to toss VS 2017 on a system yet. – Michael Petch May 20 '17 at 20:17
  • Hi, when I copy the code using includelib libcmt.lib, libvcruntime.lib, libucrt.lib, legacy_stdio_definitions.lib, and compile, it shows errors that "LNK1120 1 unresolved externals Win32Project1" "LNK2019 unresolved external symbol _WinMain@16 referenced in function "int __cdecl __scrt_common_main_seh(void)" (?__scrt_common_main_seh@@YAHXZ) Win32Project1" – kireinasora May 21 '17 at 03:16
  • when I add wcrt.lib in the additional dependency, and compile without anychange of the code, it shows errors "1 unresolved symbol", "unresolved external symbol _WinMain@16referenced in function _WinMainCRTStartup" – kireinasora May 21 '17 at 03:21
  • When I add wcrt.lib in the additional dependency, and compile with change of the last line of the code "end" to "end main", it compile successfully, however, no any windows pops up. – kireinasora May 21 '17 at 03:23

2 Answers2

6

I don't have VS 2017 installed to try this. Important: Make sure you create a Console Application and not a Windows Application. Once you create this project make sure MASM is added to the build customizations. Add an .ASM file to your project.

Take your code and insert the following lines at the top:

includelib libcmt.lib
includelib libvcruntime.lib
includelib libucrt.lib
includelib legacy_stdio_definitions.lib

An explanation as to why these lines are needed in Visual Studio later than 2013 can be found in this Stackoverflow Answer.

You want the C runtime to be the entry point to your console application (which in turn will call your main). Because of this you MUST remove main from the last line that says end main. When you do end main it bypasses the C runtime startup startup. Failure to properly initialize the C runtime will likely lead to the program crashing when you make calls like printf. It should simply be end and not end main.

The final code you should test is:

includelib libcmt.lib
includelib libvcruntime.lib
includelib libucrt.lib
includelib legacy_stdio_definitions.lib

        .386
        .model flat, c
        .stack 100h
printf  PROTO arg1:Ptr Byte

        .data
msg1    byte "Hello World!", 0Ah, 0

        .code
main    proc
        INVOKE printf, ADDR msg1
        ret

main    endp
        end
Community
  • 1
  • 1
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
0

Since Visual Studio 2015, printf is now "inlined" into C code. The assembly code to get around this would be complicated. I ended up including a small C source file in the project with a unused call to printf to get around this problem. I don't recall if the generated printf code is parameter count dependent. I just use the same or more parameters in the dummy C source code call to printf than what I use in the assembly code.

rcgldr
  • 27,407
  • 3
  • 36
  • 61