本文介绍了带有汇编程序的未解析外部符号C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在汇编器中创建函数以在C中使用它.我的问题是我无法编译我的代码.我正在使用Visual Studio2012.我在构建定制化过程中添加了错误提示,所以我不知道哪里出了问题.C:

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;

组装:

.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

推荐答案

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

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.

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

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

有关Microsoft称为装饰名称"的详细信息,请参见此处

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

解决方案:

  • 规范且可移植的方法是在主文件中声明函数"extern C":
    extern "C" int szukaj_max(int a, int b, int c);
  • 以编译器和链接器期望的方式命名该函数.您可能可以手动将名称拼凑在一起,或者只是查看链接器错误:在您的情况下,名称为?szukaj_max@@YAHHHH@Z(不带下划线).这是不可移植的,因为其他编译器具有不同的约定. (但是,MASM汇编器也可能不是完全可移植的.)
  • 或者,如果您实际上是使用C进行编程,请将主文件名的扩展名更改为".c",以便编译器假定所有声明的函数都是C函数(这是Ange的正确解决方案).那应该又是可移植的.
  • 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.

这篇关于带有汇编程序的未解析外部符号C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 00:06