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

NASM编写调用printf的汇编代码编译失败,加-fPIE仍报错求助

NASM调用printf编译错误修复

问题背景

编写了调用printf的NASM汇编代码,编译时遇到标签警告和PIE重定位错误,添加-fPIE选项无效,直接用ld链接出现段错误。

原汇编代码

section .text
global main
extern printf
main:
  endbr64
  push rbp
  
  mov rdi, [array + 1 * 4]
  mov rsi, specifer
  mov rax, 0
  call printf

  pop rbp
  mov rax, 0
  ret
section .data
  array db 1,2,3,4,5,6,7,8,9,1
  arrlen equ $ - array
  specifer db '%d',0xa,0
  speclen equ $ - specifer

编译命令

nasm -f elf64 arrays.asm
gcc arrays.o

错误信息

arrays.asm:6: warning: label alone on a line without a colon might be in error [-w+orphan-labels]
/usr/bin/ld: arrays.o: relocation R_X86_64_32S against `.data' can not be used when making a PIE object; recompile with -fPIE
collect2: error: ld returned 1 exit status

工具版本

  • NASM: 2.14.02
  • GCC: 9.4.0
  • ld: 2.34

错误原因与修复方案

1. 标签警告修复

错误提示的endbr64是CET(控制流强制技术)指令,部分旧版NASM可能无法正确识别该指令,导致误判为无冒号的标签。

  • 直接删除endbr64行即可消除警告(如果不需要CET功能);
  • 若需保留该指令,可用字节码替代:db 0xf3, 0x0f, 0x1e, 0xfa。

2. PIE重定位错误修复

64位Linux下GCC默认生成PIE(位置独立可执行文件),这类程序要求访问数据段时必须使用RIP相对寻址,原代码使用的绝对寻址会触发重定位错误。同时原代码存在数据宽度错误:

  • array是单字节数组(db),原代码mov rdi, [array + 1*4]会读取8字节数据,导致内存越界,需用movzx零扩展单字节到64位寄存器;
  • 访问数据符号前需加rel前缀,生成RIP相对地址。

修正后的汇编代码

section .text
global main
extern printf
main:
  push rbp
  
  ; 取array偏移4的单字节元素,零扩展到rdi(printf第一个参数)
  movzx rdi, byte [rel array + 4]
  ; 加载格式字符串的RIP相对地址到rsi(printf第二个参数)
  mov rsi, rel specifer
  mov rax, 0
  call printf

  pop rbp
  mov rax, 0
  ret
section .data
  array db 1,2,3,4,5,6,7,8,9,1
  arrlen equ $ - array
  specifer db '%d',0xa,0
  speclen equ $ - specifer

正确编译命令

直接使用原命令即可,无需额外添加-fPIE:

nasm -f elf64 arrays.asm
gcc arrays.o -o arrays

若需明确指定PIE编译,可添加-fPIE选项:

nasm -f elf64 arrays.asm
gcc -fPIE arrays.o -o arrays

关于ld链接段错误的说明

ld不会自动链接C标准库和启动代码(如crt0.o),而printf依赖C标准库,因此必须用GCC完成链接,它会自动处理这些依赖项。


内容的提问来源于stack exchange,提问作者raging-loon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:12:49