将 Assembly 链接到 C 时出现链接错误 [对 `asm_main()' 的未定义引用]

问题描述 投票:0回答:1

我的确切问题是我试图从 3 个文件中获取链接的最终 exe:

  • 主要
    c
    装载机
  • 主要
    asm
    文件
  • 包含函数的附件 asm 文件。

我设法将它们全部成功转换为后续的目标文件,但是在链接时, 我收到 对“asm_main()”的未定义引用错误。

我的

C
文件很简单,如下所示:

#include "cdecl.h"

int PRE_CDECL asm_main( void ) POST_CDECL;
int main()
{
    int ret_status;
    ret_status = asm_main();
    return ret_status ;
}

它指向主

asm
文件,其中包含以下部分:

segment .text
        global  _asm_main
_asm_main:
        enter   0,0               ; setup routine
        pusha

        mov     eax, prompt1      ; print out prompt
        call    print_string

        call    read_int          ; read integer
        mov     [input1], eax     ; store into input1

        mov     eax, prompt2      ; print out prompt
        call    print_string

        call    read_int          ; read integer
        mov     [input2], eax     ; store into input2

        mov     eax, [input1]     ; eax = dword at input1
        add     eax, [input2]     ; eax += dword at input2
        mov     ebx, eax          ; ebx = eax
        dump_regs 1               ; dump out register values
        dump_mem 2, outmsg1, 1    ; dump out memory
;
; next print out result message as series of steps
;
        mov     eax, outmsg1
        call    print_string      ; print out first message
        mov     eax, [input1]     
        call    print_int         ; print out input1
        mov     eax, outmsg2
        call    print_string      ; print out second message
        mov     eax, [input2]
        call    print_int         ; print out input2
        mov     eax, outmsg3
        call    print_string      ; print out third message
        mov     eax, ebx
        call    print_int         ; print out sum (ebx)
        call    print_nl          ; print new-line

        popa
        mov     eax, 0            ; return back to C
        leave                     
        ret

asm_io 文件位于此处:https://github.com/nateware/cpp/blob/master/ assembly/asm_io.asm

使用

djgpp mingw(prebuillt 12.2.0)
进行编译,
NASM(2.16.01)
也用于 asm。 我使用过的命令包括:

i586-pc-msdosdjgpp-g++.exe -c driver.c
nasm -f coff first.asm
nasm -f coff asm_io.asm

对于我使用的最终链接:

i586-pc-msdosdjgpp-g++.exe -o first driver.o first.o asm_io.o

无论我做了什么来尝试获得最终的exe,我都失败了。 有什么帮助或我缺少的东西吗?补充一下,这也是来自我用来进入汇编的一本书。

c assembly gcc linker-errors djgpp
1个回答
0
投票

TL;DR 使用

i586-pc-msdosdjgpp-gcc.exe
代替
i586-pc-msdosdjgpp-g++.exe
来编译driver.c

或者,要修复

undefined reference to 'asm_main()'
错误,请在主 C++ 文件 (
driver.c
) 中使用 extern "C" 声明它:

#ifdef __cplusplus
extern "C"
#endif
int PRE_CDECL asm_main( void ) POST_CDECL;

更长一点的解释:

  • 如果您使用 i586-pc-msdosdjgpp-g++.exe 编译
    driver.c
    ,那么它将把 driver.c 视为 C++ 源文件。作为替代方案,
    i586-pc-msdosdjgpp-gcc.exe
    将其视为 C 源文件。 C 和 C++ 是不同的语言,编译器遵循不同的规则,不存在 100% 向后兼容性。您遇到了这些差异之一。
  • 您的 driver.c 在 C 和 C++ 中都有效,因此两种编译都会成功并创建 driver.o
  • C 和 C++ 编译器进行了一些名称修改。 C 函数名称 asm_main
    driver.o
    中变为 _asm_main,C++ 函数名称 asm_main
    driver.o
    中变为 _asm_main... (TODO)。
© www.soinside.com 2019 - 2024. All rights reserved.