【问题标题】:How to change the start/main entrypoint of x86-64 assembly with NASM?如何使用 NASM 更改 x86-64 程序集的开始/主入口点?
【发布时间】:2020-04-30 22:17:09
【问题描述】:

我有这个:

$ 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

来自这个汇编:

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 以外的其他名称,例如beginmyentrypoint?我想定制它。还能定制吗?

【问题讨论】:

  • 您的 asm 定义了 main,而不是 _start,因此此 gcc read.o 是将其与调用 main 的 CRT 启动文件链接的正确命令。您打算使用minimal reproducible example 使用_start: 而不是main:,以便您使用gcc -static -nostdlib read.o 构建静态可执行文件吗?或者干脆ld read.o -o store。我有一个 asm-link 包装脚本,它将单个文件组合+链接到一个可执行文件中,包含在我对 Assembling 32-bit binaries on a 64-bit system (GNU toolchain) 的回答中

标签: linux gcc assembly nasm


【解决方案1】:

请注意,main 不是入口点。入口点是_start,由crt0.o 提供,最终调用main。你无法改变这一点。但是,您可以提供自己的启动代码来调用 main 以外的其他函数。

请注意,可以使用-e 选项将入口点本身设置为您喜欢的任何符号ld。详情请参阅手册。但是请注意,如果您更改此设置,C 运行时代码将不再正常工作。仅与您自己的运行时代码一起使用。

main 更改为其他值的一个选项是将main 设置为其他符号的别名,例如与

.set main, mymain

在一些汇编文件中。或者,只需提供一个虚拟的 main 函数来跳转到您的实际主函数:

        global  main
main:   jmp     mymain

【讨论】:

  • 那么最终的命令序列和程序集应该是什么样子的呢?
  • @LancePollard 我不知道,因为我不确定您到底想要什么。您在一个地方谈论main,在另一个地方谈论“入口点”,然后提供一条我无法重现的错误消息。如果你能把它缩小到你想要的确切描述,那么我可以为你生成这样一个命令序列。
  • 请注意,.set main, mymain 是 GAS 语法,而不是 NASM。我不确定 NASM 是否支持为符号生成弱别名。
  • @PeterCordes 实际上,似乎没有任何支持。然而,蹦床方法将起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 2015-09-20
  • 2014-01-02
  • 2012-03-11
  • 1970-01-01
相关资源
最近更新 更多