load warning: cannot find entry symbol _start

Atinesh picture Atinesh · Jan 13, 2016 · Viewed 21.3k times · Source

I'm learning assembly programming. Below is the simple program that prints 'Hello, World!'. While the program runs perfectly, I'm getting the warning message while loading

ld: warning: cannot find entry symbol _start; defaulting to 0000000008048080

Here is the code :

section .data
    msg db 'Hello, world!', 0xa
    len equ $ - msg

section .text
    global main

main:

    mov ebx, 1
    mov ecx, msg
    mov edx, len
    mov eax, 4
    int 0x80

    mov eax, 1
    int 0x80

Can anybody explain the meaning of this warning. I'm using nasm with ubuntu 14.

Answer

Peter Cordes picture Peter Cordes · Jan 14, 2016

Use the label _start instead of main for the ELF entry point. main implies it's like the C main function, but this isn't even a function (e.g. you can't ret).


You don't say, but from the error messages and code I assume you're building your 32bit code with nasm -felf32 hello32.asm && ld -melf_i386 -o hello32 hello32.o

(If you're actually building 64bit code, you're lucky that it happens to work, but it'll break as soon as you do anything with esp instead of rsp.)

The error message is from ld, not from nasm. It says so right in the message. Tim's comment is correct: ld looks for a _start symbol in the files it links, but sets the entry point to the beginning of the text segment if it doesn't find one.

It doesn't matter what other global/external symbols you define. main has no relevance at all here, and could point anywhere you want. It's only useful for a disassembly output and stuff like that. Your code would work exactly the same if you took out the global main / main: lines, or changed them to any other name.


Labelling that as main is unwise because the ELF entry point is not a function. It's not main(), and doesn't receive argc and argv arguments, and can't ret because ESP is pointing at argc instead of a return address.

Only use main if you link with gcc / glibc's CRT startup code that looks for a main symbol and calls it after initializing libc. (So functions like printf work. Technically dynamic linker hooks let libc initialize itself before your _start if you linked it, but generally don't do that unless you understand exactly what you're doing). Related: Assembling 32-bit binaries on a 64-bit system (GNU toolchain)

e.g. gcc -m32 -o hello main.o if you do define a main:
instead of gcc -m32 -static -nostdlib -o hello start.o
(which is equivalent to your bare ld).