带有Assembler的未解析的外部符号C ++

时间:2014-11-30 16:13:18

标签: c++ assembly mixed

我试图在汇编程序中使用它来在C中使用它。我的问题是我无法编译我的代码。我正在使用Visual Studio 2012.我已经在构建custiomization中添加了masm,所以我不知道什么是错的。 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; 

大会:

.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  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

3 个答案:

答案 0 :(得分:3)

包含函数调用的主文件的编译器假定它是C ++文件,例如因为文件名以“.cpp”结尾。因此,编译器将声明int szukaj_max (int a, int b, int c);解释为声明C ++函数。但是,汇编程序文件定义了C函数。

主要区别在于名称修改:为C ++函数生成的符号名称包含有关参数的信息,主要是为了便于链接器重载解析。因此,甚至没有查找简单符号_szukaj_max。 (我最初对出现在错误消息中的__cdecl感到困惑,但它定义了ABI问题,如参数传递顺序,堆栈清理职责等,而不是名称错误。)

有关“装饰名称”的更多信息,请参阅here.

解决方案:

  • 规范和便携的方式是在主文件中声明“extern C”函数:
    extern "C" int szukaj_max(int a, int b, int c);
  • 按照编译器和链接器期望的方式命名函数。您可以手动将名称拼凑在一起,或者只是查看链接器错误:您的案例中的名称是?szukaj_max@@YAHHHH@Z(没有前导下划线)。这是不可移植的,因为其他编译器具有不同的约定。 (但是MASM汇编程序也可能不是完全可移植的。)
  • 或者,如果您实际上是用C编程,请将主文件名的扩展名更改为“.c”,以便编译器假定所有声明的函数都是C函数(这是Ange的正确解决方案)。这应该是便携式的。

答案 1 :(得分:2)

您必须将文件命名为“ .c”而不是“ .cpp”我遇到了同样的问题,并且通过这样做解决了这个问题。

答案 2 :(得分:2)

我相信某些解决方案可能不完整,所以我只是添加自己的流程,希望对任何人都有用。

安装程序是x64 Windows 10上带有.cpp文件扩展名的Visual Studio 2015(针对x64编译)。 我试图在Visual Studio MFC应用程序中运行this int2d_x64.asm from al-khaser

我发现this article by LALLOUS' LABthis answer by Mike Danes on msdn从根本上是有帮助的,简而言之:

  1. 将.asm文件添加到您的项目中(右键单击项目名称>添加项目>现有项目> int2d_x64.asm)
  2. 为您的项目添加.asm文件编译支持(右键单击项目名称>构建依赖关系>构建自定义>选中masm,然后按OK)
  3. 将.asm文件项类型定义为文件的Microsoft宏汇编程序(在我的情况下为int2d_x64.asm)。 (右键单击解决方案资源管理器中的.asm文件>属性>常规>从“项目类型”下拉菜单中,选择“ Microsoft宏汇编器”)
  4. 将函数本身定义为extern "C" void __int2d();(对于OP,则为@Peter-Reinstate Monica建议:extern "C" int szukaj_max(int a, int b, int c);