如何将混合(asm,C ++)源代码编译为32位程序?

时间:2019-04-03 23:26:00

标签: c++ assembly makefile cygwin

我在64位计算机上的Win7下使用 Cygwin 32位

以下程序

makefile:

runme:  main.cpp    asm.o
        g++ main.cpp    asm.o   -o  executable

asm.o:  asm.asm
        nasm    -f  elf     asm.asm     -o  asm.o 

asm.asm:

section .data
section .bss
section .text
    global GetValueFromASM

GetValueFromASM:
    mov eax, 9
    ret

main.cpp:

#include <iostream>

using namespace std;

extern "C" int GetValueFromASM();

int main()
{
    cout<<"GetValueFromASM() returned = "<<GetValueFromASM()<<endl;

    return 0;
} 

给我以下错误:

$ make
nasm    -f      elf             asm.asm         -o      asm.o
g++     main.cpp        asm.o   -o      executable
/tmp/cc3F1pPh.o:main.cpp:(.text+0x26): undefined reference to `GetValueFromASM'
collect2: error: ld returned 1 exit status
make: *** [makefile:2: runme] Error 1

我不明白为什么会产生此错误。

如何摆脱这个问题?

1 个答案:

答案 0 :(得分:2)

按照Windows / Cygwin的惯例,您必须在符号前面加上_

section .data
section .bss
section .text
    global _GetValueFromASM

_GetValueFromASM:
    mov eax, 9
    ret

其余代码应能正常工作。

一种替代方法是使用-fno-leading-underscore进行编译。但是,这可能会中断与其他(Cygwin系统)库的链接。如果您对其他平台的可移植性无所谓,我建议使用第一种方法。

从GNU在线文档引用:

  

-fleading-underscore

     

此选项及其对应的-fno-leading-underscore强制更改C符号在目标文件中的表示方式。一种用途是帮助链接旧的汇编代码。

     

警告:-fleading-underscore开关使GCC生成的代码与没有该开关的代码不二进制兼容。使用它来符合非默认应用程序二进制接口。并非所有目标都为此开关提供完整的支持。