You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GCC编译x86_64汇编时mov指令为何导致动态段大小设置失败?

解决PIE模式下x86_64汇编的R_X86_64_32S重定位错误

问题原因

你遇到的R_X86_64_32S重定位错误,核心原因是PIE(位置独立可执行文件)强制要求所有内存地址引用必须是位置无关的:

  • 直接写mov rdi, f时,汇编器会生成32位绝对地址的重定位(R_X86_64_32S),但PIE程序的加载基址是随机的,32位偏移无法覆盖64位地址空间,且动态链接器不允许这种绝对地址引用。
  • 移除该行后没有绝对地址引用,所以编译流程能正常完成。

解决方案

要在PIE模式下正确获取标签f的地址,必须使用RIP相对寻址,用lea指令替代mov:

mov rdi, f  # 错误:生成32位绝对重定位
lea rdi, [f]  # 正确:生成RIP相对的位置无关重定位

替换后的完整代码如下:

.intel_syntax noprefix 
.globl main 
.section .rodata 
.text
f:                 # Exits thread
    mov rdi, 0
    mov rax, 60
    syscall

main: 
    call create_thread_stack
    pop rsi                    # --
    sub rsi, 8                 # | Put function pointer onto
    lea rdi, [f]               # | new stack(修正此处)
    push rdi                   # --
    pop qword ptr [rsi]        # Put function pointer onto new stack
    mov rdi, -2147479808       # Flags
    mov rax, 56                # Sys_clone
    syscall
    ret

create_thread_stack:    # Mmaps stack for cloned process
    mov rdi, 0
    mov rsi, 4194304    # Size of stack
    mov rdx, 3          
    mov r10, 290
    mov r9, 0
    mov r8, -1
    mov rax, 9          # Sys_mmap
    syscall
    add rax, 4194304
    push rax            # Return base pointer of new stack
    ret

额外说明

  • 你尝试的mov rdi, [f]是读取f地址处的内存内容,而非f的地址本身,不符合需求;
  • mov rdi, offset f在Intel语法中仍会生成绝对地址重定位,无法满足PIE的位置无关要求;
  • 编译时需确保同时传递-fPIE和-pie参数给GCC(gcc -fPIE -pie your_code.s -o output),前者告诉汇编器生成PIE兼容的目标文件,后者告诉链接器生成PIE可执行文件。

内容的提问来源于stack exchange,提问作者FlappyToucan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:37:21