你好,我试图编译这段代码,以显示最大的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
1条答案
按热度按时间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。为了教育和学习,我个人推荐第二种选择,但两者都应该解决你的问题。