我的确切问题是我试图从 3 个文件中获取链接的最终 exe:
c
装载机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,我都失败了。 有什么帮助或我缺少的东西吗?补充一下,这也是来自我用来进入汇编的一本书。
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.o中变为
_asm_main
,C++ 函数名称 asm_main 在 driver.o中变为
_asm_main...
(TODO)。