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

为何ld将代码加载到0x1000而非0x0?如何让代码从0x0开始?

汇编代码在二进制文件中从0x1000起始的原因及解决方法

问题背景

我拥有以下文件:

boot.s

.section code_section
code:
    jmp code

.section boot_magic_section
boot_magic:
    .word 0xaa55

linker_script.ld

SECTIONS {
    beginning : {
        boot.o(code_section)
        . += 510;
        boot.o(boot_magic_section)
    } = 0
    .bss : {
        *(COMMON)
    }
    rest : {
        *(.note.gnu.property)
    }
}

执行编译链接命令:

as -o boot.o boot.s
ld -T linker_script.ld -o boot.bin boot.o && objdump -D boot.bin

反汇编结果显示code段位于虚拟地址0x0;但执行hexdump boot.bin -x时,发现代码实际在文件的0x1000偏移位置开始。

请问为何代码会从0x1000而非0x0开始?如何让汇编代码从0x0起始?


原因分析

你用ld直接输出的boot.bin本质是ELF格式的可执行文件,不是纯二进制镜像:

  • objdump -D解析的是ELF文件的虚拟内存地址(VMA),链接脚本里你把beginning段的VMA设为0,所以反汇编显示代码在0x0。
  • hexdump查看的是文件的实际字节偏移,ELF文件的段默认会按4KB(0x1000)的页大小对齐,所以代码段被放到了文件中0x1000的偏移位置,这是ELF文件格式的默认对齐规则导致的。

解决方法

要生成代码从0x0起始的纯二进制镜像,需要用objcopy将ELF文件转换为纯二进制格式,步骤如下:

  1. 先用ld生成ELF格式的中间文件:

    ld -T linker_script.ld -o boot.elf boot.o
    
  2. 使用objcopy提取纯二进制内容:

    objcopy -O binary boot.elf boot.bin
    

此时再执行hexdump boot.bin -x,就能看到代码从文件的0x0偏移位置开始,最后511-512字节是0xaa55,完全符合MBR的格式要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 06:40:46