GNU GAS:标签没有相对引用

时间:2015-02-26 11:01:35

标签: assembly linker nasm boot gas

我正在编写一个用于学习目的的小引导程序。

这是boot.S

.code16
.text
    movw    $0xB800, %ax    /* 0xB000 is the text screen video memory */
    movw    %ax, %es       /* set it as the %es segment */

    movb    label, %al
    movb    %al, %es:0x0    /* screen[0] = 'A' */
    movb    $0x07, %es:0x1  /* white on black */
    jmp .

label:  
    .byte 'A

    .=510
    .byte 0x55
    .byte 0xAA

这是我用来将其编译为原始二进制文件的Makefile

hdd.img: boot.S
    as $< -o boot.o
    ld --oformat binary -Ttext 0x7c00 boot.o -o hdd.img

我遇到标签没有被相对引用的问题:当加载字节时,它使用绝对地址,比如0x7c14。

所以我不能在运行时重新定位这个bootsector(例如通过在内存中进一步复制它)。如果通过与当前指令的偏移量简单引用标签会更好。

是否可以这样做?

1 个答案:

答案 0 :(得分:1)

当然可以重新定位字符串。

首先,您的-Ttext 0x7C00是正确的。不要改变它。 在引导加载程序的开头,您应该将段寄存器归零(%ds%es%fs%gs%ss):

mov $0, %ax         // xor %ax, %ax would be more space efficient
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss

接下来,您应该设置一个堆栈。阅读:osdev wiki about stacks

现在问你的问题: 通常以%ds:%si的形式使用segmentation来处理字符串。重新定位引导加载程序时,只需正确更改%ds即可 假设你调用字符串label

mov $label, %si     // Always prefix a label address with a $

您可以使用lodsb指令从字符串中获取字符( LO a D S tring B yte,会自动为您增加%si

lodsb               // Character is stored in `%al` now

另一个建议是不要手动处理视频内存。使用BIOS Interrupt 0x10

祝你的bootloader好运!