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

汇编global与extern使用问题:Bootloader跨文件调用输出异常

问题原因及解决方案

核心错误点

  1. 错误使用64位目标文件格式编译16位代码
    你用nasm -f elf64编译16位Bootloader代码,生成的是64位ELF目标文件,其中的指令编码是针对64位模式的。而Bootloader运行在16位实模式下,CPU无法正确解析这些64位指令,比如call printc会被编译成64位调用指令,执行时直接出错。

  2. 链接时未指定16位模式
    默认ld链接elf64文件会生成64位可执行程序,即使指定了-Ttext=0x7c00,也不会生成16位兼容的代码段,导致实模式下无法正常运行。

  3. 多文件链接时引导扇区填充计算错误
    原代码中的times 510 - ($-$$) db 0里,$$是单个目标文件的起始地址,而非整个程序的起始地址,链接后会导致填充长度错误,引导签名0xaa55无法落在正确的位置(第511、512字节),影响BIOS引导。


修复步骤

1. 改用32位ELF格式编译

使用elf32格式编译,配合后续链接时的16位模式指定,生成兼容16位实模式的目标文件:

nasm -f elf32 start.asm -o start.o
nasm -f elf32 print.asm -o print.o

2. 使用链接脚本控制程序布局

创建boot.ld链接脚本,明确指定程序起始地址、16位代码段布局,以及引导扇区的填充和签名:

ENTRY(_start);
SECTIONS
{
    . = 0x7c00;
    .text : AT(0x7c00)
    {
        *(.text);
        /* 填充到510字节,插入引导签名 */
        . = ALIGN(1);
        FILL(0);
        . = 0x7c00 + 510;
        SHORT(0xaa55);
    }
}

3. 链接生成可执行文件

用ld指定32位ELF模式并加载链接脚本:

ld -m elf_i386 -T boot.ld start.o print.o -o printer.elf

4. 转换为原始二进制文件

objcopy -O binary printer.elf printer.bin

5. 运行测试

qemu-system-x86_64 -drive format=raw,file=printer.bin

为什么%include能正常工作?

使用%include时,所有代码会被合并到单个源文件中,如果你之前是用nasm -f bin直接编译成16位原始二进制文件,生成的代码完全符合实模式要求,不存在目标文件格式不兼容和链接布局的问题,因此可以正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 07:57:09