1

I have this:

$ make build
read.o: In function `_start':
read.asm:(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:3: recipe for target 'build' failed
make: *** [build] Error 1

From this asm:

global main

section   .text
main:   mov       rax, 1                  ; system call for write
          mov       rdi, 1                  ; file handle 1 is stdout
          mov       rsi, message            ; address of string to output
          mov       rdx, 13                 ; number of bytes
          syscall                           ; invoke operating system to do the write
          mov       rax, 60                 ; system call for exit
          xor       rdi, rdi                ; exit code 0
          syscall                           ; invoke operating system to exit

section   .data
message:  db        "Hello, World", 10      ; note the newline at the end

I am running it with this:

$ nasm -felf64 read.asm -o read.o && gcc read.o -o store && ./store

How do I change the word main to something other than main or _start, such as begin or myentrypoint? I would like to customize it. Can it even be customized?

Lance
  • 75,200
  • 93
  • 289
  • 503
  • Your asm defines a `main`, not a `_start`, so this `gcc read.o` is the right command to link it with CRT start files that call `main`. Did your intended [mcve] use `_start:` instead of `main:`, for you to build into a static executable with `gcc -static -nostdlib read.o`? Or simply `ld read.o -o store`. I have an `asm-link` wrapper script that assembles + links a single file into an executable, included in my answer on [Assembling 32-bit binaries on a 64-bit system (GNU toolchain)](https://stackoverflow.com/q/36861903) – Peter Cordes May 01 '20 at 03:03

1 Answers1

3

Note that main is not the entrypoint. The entrypoint is _start provided by crt0.o which eventually calls main. You cannot change that. However, you can provide your own startup code that calls some other function than main.

Note that the entrypoint itself can be set to whatever symbol you like with the -e option to ld. Refer to the manual for details. Note however that if you change this, the C runtime code will no longer work correctly. Use only with your own runtime code.

One option to change main to something else is setting main to be an alias for some other symbol, e.g. with

.set main, mymain

in some assembly file. Alternatively, simply provide a dummy main function that jumps to your actual main function:

        global  main
main:   jmp     mymain
fuz
  • 88,405
  • 25
  • 200
  • 352
  • So what should the final command sequence and assembly look like? – Lance Apr 30 '20 at 22:31
  • @LancePollard I don't know because I am not sure what exactly you want. You talk about `main` in one place, “entrypoint” in the other and then provide an error message I cannot reproduce. If you can narrow it down to an exact description of what you want, then I can produce such a command sequence for you. – fuz Apr 30 '20 at 22:44
  • 1
    Note that `.set main, mymain` is GAS syntax, not NASM. I'm not sure if NASM supports generating weak aliases for symbols. – Peter Cordes May 01 '20 at 02:54
  • @PeterCordes Indeed, there doesn't seem to be any support for this. The trampoline approach will work however. – fuz May 02 '20 at 12:16