Search code examples
c++assemblymixed

Unresolved external symbol C++ with Assembler


I am trying to make function in assembler to use it in C. My problem is that i can't compile my code. I am using Visual studio 2012. I've add masm in build custiomization so i dont have idea whats wrong. C:

#include <stdio.h> 
int szukaj_max (int a, int b, int c);

int main() 
{ 
int x, y, z, wynik; 
printf("\nProszępodaćtrzy liczby całkowite: "); 
scanf_s("%d %d %d", &x, &y, &z, 32);

wynik = szukaj_max(x, y, z); 
printf("\nSpośród podanych liczb %d, %d, %d, \ liczba %d jest największa\n", x,y,z, wynik);

return 0; 

Assembly:

.686 
.model flat 
public _szukaj_max 
.code 
_szukaj_max  PROC 
    push  ebp   ; zapisanie zawartości EBP na stosie 
    mov   ebp, esp  ; kopiowanie zawartości ESP do EBP 
    mov   eax, [ebp+8]  ; liczba x 
    cmp   eax, [ebp+12]  ; porownanie liczb x i y 
jge   x_wieksza  ; skok, gdy x >= y 
; przypadek x < y 
    mov   eax, [ebp+12]  ; liczba y 
    cmp   eax, [ebp+16]  ; porownanie liczb y i z 
jge   y_wieksza  ; skok, gdy y >= z 
; przypadek y < z 
; zatem z jest liczbąnajwiekszą
wpisz_z:  
    mov  eax, [ebp+16]  ; liczba z 
zakoncz: 
    pop   ebp 
    ret 
x_wieksza: 
    cmp   eax, [ebp+16]  ; porownanie x i z 
    jge   zakoncz   ; skok, gdy x >= z 
    jmp   wpisz_z 
y_wieksza: 
    mov   eax, [ebp+12]  ; liczba y 
    jmp   zakoncz 
_szukaj_max  ENDP

END 

Error:

 Error  2   error LNK2019: unresolved external symbol "int __cdecl szukaj_max(int,int,int)" (?    szukaj_max@@YAHHHH@Z) referenced in function _main    C:\Users\Kaczor\Desktop\Ako\4.1\4.1\Source.obj
 Error  3   error LNK1120: 1 unresolved externals   C:\Users\Kaczor\Desktop\Ako\4.1\4.1\Debug\4.1.exe   1

Solution

  • The compiler of the main file containing the function call assumes it is a C++ file, for example because the file name ends in ".cpp". Therefore, the compiler interpretes the declaration int szukaj_max (int a, int b, int c); as declaring a C++ function. However, your assembler file defines a C function.

    The main difference is in name mangling: The symbol names generated for C++ functions contain information about the parameters, mainly in order to facilitate overload resolution by the linker. Therefore the simple symbol _szukaj_max is not even looked for. (I was initially confused by __cdecl appearing in the error message, but that defines ABI issues like the order of parameter passing, stack cleanup responsibilities etc., not the name mangling.)

    For more information about "decorated names", as Microsoft calls it, see here.

    Solution:

    • The canonical and portable way is to declare the function "extern C" in your main file:
      extern "C" int szukaj_max(int a, int b, int c);
    • Name the function the way the compiler and linker expect it. You can probably cobble the name together manually, or you just look at the linker error: The name in your case is ?szukaj_max@@YAHHHH@Z (without leading underscore). This is not portable because other compilers have different conventions. (But then the MASM assembler may not be fully portable either.)
    • Or, if you are actually programming in C, change your main file name's extension to ".c" so that the compiler assumes all declared functions are C functions (that's Ange's correct solution). That should again be portable.