【发布时间】:2023-03-08 09:43:01
【问题描述】:
我在汇编器上复制了示例程序并使用 gcc 编译它,但得到以下输出:
gcc hello.s -o hello1
/usr/bin/ld: /tmp/ccPs5dcq.o: 重定位 R_X86_64_32 对 `.data' 在制作 PIE 对象时不能使用;使用 -fPIE 重新编译
/usr/bin/ld:最终链接失败:输出部分无法表示
collect2:错误:ld 返回 1 个退出状态
代码:
.data
hello_str:
.string "Hello, world!\n"
.set hello_str_length, . - hello_str - 1
.text
.globl main
.type main, @function
main:
movl $4, %eax
movl $1, %ebx
movl $hello_str, %ecx
movl $hello_str_length, %edx
int $0x80
movl $1, %eax
movl $0, %ebx
int $0x80
.size main, . - main
我做错了什么?
附:我绝对是汇编程序的初学者,只是试图解析示例
【问题讨论】:
-
尝试用
-fno-pie编译。让我看看我能不能找到一个好的副本。 -
@fuz 谢谢,它有效,这是什么意思?
-
指令
movl $hello_str, %ecx在链接时需要知道hello_str的地址。在创建 PIE(位置无关)可执行文件时情况并非如此,因此链接器会对您大喊大叫。可以以与位置无关的方式编写相同的代码,但是在 32 位代码中,这要困难得多,因此最好暂时忽略这一点。另外,鉴于您编写的是 32 位代码,您需要与-m32进行汇编和链接,否则会出现奇怪的问题。 -
@fuz:注意
R_X86_64_32重定位:问题是不支持 64 位模式下的 32 位 绝对修正。使用-m32,动态链接器可以修复一个 32 位绝对值以保存整个地址空间中的任何指针,因此它是受支持的。错误消息与32-bit absolute addresses no longer allowed in x86-64 Linux? 重复,但真正的修复是-m32(即使不需要,-no-pie也可能是个好主意)。 -
如果您编译为 64 位代码,What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code? 也适用。