Undefined reference to main in Assembly langage

Viewed 37

Hi im trying to compile this code in order to display the max of 2 given values in assembly but apparently can't seem to make it.

The error is

/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 breaks added for readability.)

And the code is

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 Answers

At first i thought this was a duplicate of this but the original question seems to be about 32-bits. While it is not relevant to the answer i think its worth to update the answer.


During linking with ld (which is usually called by gcc internally) the entry point into a binary is placed pointing to the _start symbol. This means that when the program is ran, it starts execution from this point. Despite that, the default starting point in a C program is usually a main function. This is due to the fact that C programs often link with various libraries. One of the better known ones is libc, but there is also libgcc. Some of these libraries require some initialization to be performed when the program is started. This is often implemented by making _start call these initialization routines before calling main. The _start symbol used by gcc for that task is defined in crt (CRT stands for C RunTime). Here is a link to _start in gcc source code, specifically the i386 version (64-bit version i could not find, but it is somewhere in there). Since the _start symbol is already defined, the programmer only has to define main.

Now you are not writing C, you are writing assembly. You most likely do not want any of the libraries you would normally want when writing C. You want _start to only call your program code, not initialize anything behind the scenes. But GCC does that by default, by passing options to the linker ld. You really have two solutions:

  • Run GCC with -nostdlib as suggested here. This makes it so that GCC does not use default libraries, so no initialization is performed and CRT is not used. The link option is described here.

  • Use ld directly, and learn in detail about the linking process as suggested here. This is more difficult, but gives you better understanding of what you are actually doing. In my personal opinion, this fits assembly much better, unless only part of your code is in assembly and the rest is in C.

I personally recommend the second option for the sake of education and learning, but both should fix your problem.

Related