【问题标题】:Relocation error when compiling NASM code in 64-bit mode在 64 位模式下编译 NASM 代码时出现重定位错误
【发布时间】:2018-12-26 16:24:45
【问题描述】:

我编写了一个简单的汇编代码,我试图在 64 位模式下编译。代码如下:

extern printf

section .rodata
readinfo db `%d\n`, 0

section .text
global main
main:
mov rbp, rsp ; for correct debugging

mov rax, 5
push rax
push readinfo
call printf
add rsp, 8

xor rax, rax
mov rsp, rbp
ret

以下是我对 nasm 和 gcc 的说明(正如我在其他帖子中所读到的,gcc 会自动将目标文件与默认的 c 库链接):

nasm -f elf64 -o test.o test.asm -D UNIX
gcc -o test test.o

但是,我收到以下重定位错误:

/usr/bin/x86_64-linux-gnu-ld: test.o: 重定位 R_X86_64_32S 反对 制作 PIE 对象时不能使用 `.rodata';重新编译 -fPIC

/usr/bin/x86_64-linux-gnu-ld:最终链接失败:不可表示 输出部分

collect2: 错误:ld 返回 1 个退出状态

当我使用“-no-pic”选项编译以禁用与位置无关的代码时,它编译时没有错误,但在执行后我得到一个没有输出的段错误。 当我以 32 位重新编译代码(用 32 位替换 64 位寄存器)时,我没有收到任何错误。命令是:

nasm -f elf32 -o test.o test.asm -D UNIX
gcc -o test test.o -m32

我的问题是:为什么我不能在 64 位模式下用 PIC 编译代码?

PS: 这不是 Can't link a shared library from an x86-64 object from assembly because of PIC 的重复,因为错误是不同的,并且在该帖子中找到的解决方案与我的问题无关。我已经编辑了要指定的错误输出。

【问题讨论】:

标签: linux gcc assembly nasm x86-64


【解决方案1】:

错误是我使用了错误的调用约定。在架构 x86_64 中,前两个参数分别在 rdi 和 rsi 中传递,而不使用堆栈。另外,我需要在通话中添加“wrt ..plt”。以下代码有效:

extern printf

section .rodata
readinfo db `%d\n`, 0

section .text
global main
main:
mov rbp, rsp ; for correct debugging

mov rsi, 5
mov rdi, readinfo
xor rax, rax
call printf wrt ..plt

xor rax, rax
mov rsp, rbp
ret

nasm 和 gcc 的命令没有改变。

【讨论】:

猜你喜欢
  • 2016-11-15
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
  • 2021-07-28
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多