title: Calling a standard-library-function in MASM
body: <p>I want to get started in MASM in a mixed C++/Assembly way.
  I am currently trying to call a standard-library-function (e.g. printf) from a PROC in assembly, that I then call in C++.</p>
  
  <p>I have the code working after I declared printf's signature in my cpp-file. But I do not understand why I have to do this and if I can avoid that.</p>
  
  <p>My cpp-file:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  extern "C" {
      extern int __stdcall foo(int, int);
  }
  
  extern int __stdcall printf(const char*, ...); // When I remove this line I get Linker-Error "LNK2019: unresolved external symbol"
  
  int main()
  {
      foo(5, 5);
  }
  </code></pre>
  
  <p>My asm-file:</p>
  
  <pre><code>.model flat, stdcall
  
  EXTERN printf :PROC ; declare printf
  
  .data
  
  tstStr db "Mult: %i",0Ah,"Add: %i",0 ; 0Ah is the backslash - escapes are not supported
  
  .code
  
  foo PROC x:DWORD, y:DWORD
  
  mov eax, x
  mov ebx, y
  add eax, ebx
  push eax
  mov eax, x
  mul ebx
  push eax
  push OFFSET tstStr
  call printf
  ret
  
  foo ENDP
  
  END
  </code></pre>
  
  <p><strong>Some Updates</strong></p>
  
  <p>In response to the comments I tried to rework the code to be eligible for the cdecl calling-convention. Unfortunatly this did not solve the problem (the code runs fine with the <code>extern</code> declaration, but throws an error without).</p>
  
  <p>But by trial and error i found out, that the <code>extern</code> seems to force external linkage, even though the keyword should not be needed, because external linkage should be the <a href="https://en.cppreference.com/w/cpp/language/storage_duration#Linkage" rel="nofollow noreferrer">default</a> for function declarations.</p>
  
  <p>I can omit the declaration by using the function in my cpp-code (i.e. if a add a <code>printf("\0");</code> somewhere in the source file the linker is fine with it and everythings works correctly.</p>
  
  <p>The new (but not really better) cpp-file:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  extern "C" {
      extern int __cdecl foo(int, int);
  }
  extern int __cdecl printf(const char*, ...); // omiting the extern results in a linker error
  
  int main()
  {
      //printf("\0"); // this would replace the declaration
      foo(5, 5);
      return 0;
  }
  </code></pre>
  
  <p>The asm-file:</p>
  
  <pre><code>.model flat, c
  
  EXTERN printf :PROC
  
  .data
  
  tstStr db "Mult: %i",0Ah,"Add: %i",0Ah,0 ; 0Ah is the backslash - escapes are not supported
  
  .code
  
  foo PROC
  
  push ebp
  mov ebp, esp
  mov eax, [ebp+8]
  mov ebx, [ebp+12]
  add eax, ebx
  push eax
  mov eax, [ebp+8]
  mul ebx
  push eax
  push OFFSET tstStr
  call printf
  add esp, 12
  pop ebp
  ret
  
  foo ENDP
  
  END
  </code></pre>