assembly 程序集语言中未定义的对main的引用

3gtaxfhh  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(157)

你好,我试图编译这段代码,以显示最大的2个给定值的汇编,但显然不能使它。
错误为

/usr/bin/ld:
   /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o:
   in function `_start': (.text+0x20):
   undefined reference to `main'
collect2: error: ld returned 1 exit status

(Line为便于阅读而添加的分隔符。)
密码是

bits 64
global my_average
section .text

start:
 push rbp
 mov rbp, rsp

        xor rax, rax
        add rax, rdi
        add rbx, rsi
        cmp rax , rbx
        jge .end

.end:
 mov rax, rbx

mov rsp, rbp
pop rbp
ret
6qftjkof

6qftjkof1#

一开始我以为这是this的复制品,但原来的问题似乎是关于32位的。虽然它与答案无关,但我认为值得更新答案。
ld链接期间(通常由gcc在内部调用)二进制文件的入口点指向_start符号。这意味着当程序运行时,它从这个点开始执行。尽管如此,C程序的默认起始点通常是main函数。2这是由于C程序经常与各种库链接。其中一个比较有名的是libc,但也有libgcc。其中一些库需要在程序启动时执行一些初始化。这通常通过使_start在调用main之前调用这些初始化例程来实现。gcc为该任务使用的_start符号在crt中定义(CRT代表C运行时)。下面是gcc源代码中_start的链接,特别是i386版本(64位版本我找不到,但它在那里的某个地方)。由于_start符号已经定义,程序员只需要定义main
现在你不是在写C,而是在写汇编。你很可能不需要任何你在写C时通常需要的库。你希望_start只调用你的程序代码,而不是在后台初始化任何东西。但是GCC默认情况下是这样做的,通过将选项传递给链接器ld。你实际上有两种解决方案:

  • 使用-nostdlib运行GCC,如建议的here。这使得GCC不使用默认库,因此不执行初始化,也不使用CRT。链接选项在here中描述。
  • 直接使用ld,并详细了解here建议的链接过程。这比较困难,但可以让你更好地理解你实际在做什么。在我个人看来,这更适合汇编,除非你的代码只有一部分是汇编,其余部分是C。

为了教育和学习,我个人推荐第二种选择,但两者都应该解决你的问题。

相关问题