【问题标题】:Undefined references when linking assembly and C++ using g++使用 g++ 链接程序集和 C++ 时未定义的引用
【发布时间】:2012-01-25 11:26:02
【问题描述】:

为了考试,我必须在 Assembly 中编写一些类的成员函数。我已按照每条指令进行操作,但仍然无法正常工作。以下是相关文件。头部和main方法已经提供了,我只需要写构造函数和elab1方法即可。

类头

#include <iostream>
using namespace std;
struct st { int a; int vv1[4]; double vv2[4]; };
class cl 
{   double b; st s;
public:
    cl(int *p, double *d);
    void elab1(st ss);
    void stampa()
    {   int i; cout << b << ' ' << s.a << endl;
        for (i=0;i<4;i++) cout << s.vv1[i] << ' '; cout << '\t';
        for (i=0;i<4;i++) cout << s.vv2[i] << ' '; cout << endl;
        cout << endl;
    }
};

主要测试方法

// prova1.cpp
#include "cc.h" // class header
int main()
{
    st s = {1, 1,2,3,4, 1,2,3,4  };
    int v[4] = {10,11,12,13 };
    double d[4] = { 2, 3, 4, 5 };
    cl cc1(v, d);
    cc1.stampa();
    cc1.elab1(s);
    cc1.stampa();
}

这是我的大会

# es1.s
.text
.global __ZN2clC1EPiPe

__ZN2clC1EPiPe:

    pushl %ebp
    movl %esp, %ebp
    subl $4, %esp       

    pushl %eax
    pushl %ebx
    pushl %ecx
    pushl %edx
    pushl %esi

    cmpl $0, 12(%ebp)
    je fine
    cmpl $0, 16(%ebp)
    je fine

    movl 8(%ebp), %eax  
    movl 12(%ebp), %ebx
    movl 4(%ebx), %ecx
    movl %ecx, 12(%eax)

    fldz
    fstpl (%eax)

    movl $0, -4(%ebp)

ciclo:

    cmpl $4, -4(%ebp)
    je fine

    movl -4(%ebp), %esi     
    movl 12(%ebp), %ebx
    movl (%ebx, %esi, 4), %ecx
    subl %esi, %ecx     
    movl %ecx, 16(%eax, %esi, 4)

    movl 16(%ebp), %ebx
    pushl %eax
    movl %esi, %eax
    movl $3, %ecx
    imull %ecx
    movl %eax, %edx
    popl %eax

    movl 12(%ebp), %ecx

    fldl (%ebx, %edx, 4)
    fldl (%ecx, %esi, 4)
    faddp %st, %st(1)

    fstpl 32(%eax, %edx, 4)

    fldl (%ebx, %edx, 4)
    fldl (%eax)
    faddp %st, %st(1)

    fstpl (%eax)

    incl -4(%ebp)
    jmp ciclo

fine:

    popl %esi
    popl %edx
    popl %ecx
    popl %ebx
    popl %eax

    movl 8(%ebp), %eax

    leave
    ret

.global __ZN2cl5elab1E2st

__ZN2cl5elab1E2st: #TODO

我尝试使用提供给我们的命令行语句来编译和链接所有内容:

g++ -o es1 -fno-elide-constructors es1.s prova1.cpp

但它只给了我一堆undefined references:

/tmp/ccbwS0uN.o: In function `main':
prova1.cpp:(.text+0xee): undefined reference to `cl::cl(int*, double*)'
prova1.cpp:(.text+0x192): undefined reference to `cl::elab1(st)'
collect2: ld returned 1 exit status

您知道我该如何解决这个问题吗?我以为我可能以错误的方式翻译了函数名称,但我已经检查了好几次。

【问题讨论】:

  • 你确定名称中的两个下划线,而不仅仅是一个吗?
  • @PlasmaHH 我刚刚尝试删除一个下划线,问题仍然存在。
  • 你是如何创建错位名称的?
  • @JohanLundberg 遵循我书中写的翻译规则:C++ 类方法被这样处理:__ZN + 类名长度 + 类名 + C1 用于构造函数 + E + 参数列表,在我的情况下,一个 n 整数指针 (Pi) 和一个双指针 (Pe),但我不确定最后一个。编辑:最后一个应该是Pd,但这并不能解决问题。
  • c++filt 不会反转这些。我认为它应该如果正确的话。也许先尝试一个静态 void f() 函数?

标签: c++ assembly g++


【解决方案1】:

c++filt 应用于您的姓名修改并与错误消息中的签名进行比较。

当删除一个下划线并使用 c++filt 过滤时,我得到了您的错误名称 cl::cl(int*, long double*),它与您的错误消息/类声明中的任何内容都不匹配。

对于cl::cl(int*, double*),正确的名称应该是_ZN2clC1EPiPd

我建议您改进获取错误名称的方式(不管它是什么)。

【讨论】:

  • 是的,最后一个字母我错了,应该是Pd,我刚刚编辑了我的帖子。编辑:它现在正在工作,即使我的书使用两个下划线而不是一个。好吧,我会向我的老师提交一份错误报告。
  • @Narrakan:您的帖子仍然包含双下划线。
猜你喜欢
  • 2013-02-03
  • 1970-01-01
  • 1970-01-01
  • 2011-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多