Как изменить начальную / основную точку входа сборки x86-64 с помощью NASM? - PullRequest
0 голосов
/ 01 мая 2020

У меня есть это:

$ 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

Из этого 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

Я запускаю его с этим:

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

Как мне изменить слово main к чему-то другому, чем main или _start, например begin или myentrypoint? Я хотел бы настроить его. Можно ли его даже настроить?

1 Ответ

2 голосов
/ 01 мая 2020

Обратите внимание, что main не является точкой входа. Точка входа - _start, предоставленная crt0.o, которая в конечном итоге вызывает main. Вы не можете это изменить. Однако вы можете предоставить свой собственный код запуска, который вызывает другую функцию, отличную от main.

. Обратите внимание, что для самой точки входа можно задать любой символ, который вам нравится, с параметром -e равным ld. За подробностями обращайтесь к руководству. Однако обратите внимание, что если вы измените это, код времени выполнения C больше не будет работать правильно. Используйте только с вашим собственным кодом времени выполнения.

Один из вариантов изменить main на что-то другое - установить main в качестве псевдонима для другого символа, например, с

.set main, mymain

в какой-то сборочный файл. В качестве альтернативы просто предоставьте фиктивную функцию main, которая переходит к вашей действительной основной функции:

        global  main
main:   jmp     mymain
...