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

为何GNU ld处理NASM与GAS等效汇编生成的.o文件输出不同?

解答

这种差异的核心原因是NASM和GAS生成的目标文件中,.text段的默认对齐属性不同,ld在链接时会严格遵循段的对齐要求来安排代码位置,最终导致入口地址和文件大小出现差异。

具体分析

  1. 段对齐属性差异
    虽然用strip --strip-section-headers剥离段头后两个.o文件内容一致,但原始目标文件的段头信息中,.text段的对齐要求不同:

    • GAS生成的.text段默认对齐值为16字节
    • NASM生成的.text段默认对齐值为8字节(不同版本可能略有差异)
  2. ld的链接行为
    非PIE模式下,ELF可执行文件的LOAD段起始地址固定为0x400000,LOAD段开头包含64字节的ELF头+56字节的程序头表(共120字节,即0x78):

    • 对于NASM的.o文件,.text段要求8字节对齐,0x78是8的倍数,因此ld直接将代码放在该位置,LOAD段总大小为120+12=132字节(代码共12字节),入口地址为0x400078。
    • 对于GAS的.o文件,.text段要求16字节对齐,0x78不是16的倍数,ld会在程序头表后填充8字节空数据,将代码起始位置调整到0x80(128字节,16的倍数),LOAD段总大小变为128+12=140字节,入口地址为0x400080。
  3. 验证方法
    执行readelf -S tiny-nasm.o和readelf -S tiny-gas.o,对比.text段的Align字段,即可看到两者的对齐值差异。

  4. 统一输出的方法
    手动指定.text段的对齐值,消除汇编器默认设置差异:

    • NASM代码中添加ALIGN 16,或编译时使用nasm -f elf64 -align 16 tiny-nasm.asm
    • GAS代码中添加.align 8

这样ld链接时会使用相同的对齐要求,生成的二进制文件大小和入口地址将完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 22:14:55