GNU GAS:标签未被相对引用
GNU GAS: Label is not relatively referenced
我正在写一个小引导扇区用于学习目的。
这里是boot.S
.code16
.text
movw [=10=]xB800, %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 [=10=]x07, %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
我遇到标签没有相对引用的问题:加载字节'A'时,使用的是绝对地址,比如0x7c14)。
所以我不能在运行时重新定位这个引导扇区(例如通过在内存中进一步复制它)。如果通过当前指令的偏移量简单地引用标签会更好。
可以这样做吗?
当然可以重新定位字符串。
首先,你的-Ttext 0x7C00
是正确的。不要改变它。
在引导加载程序的开头,您应该将段寄存器(%ds
、%es
、%fs
、%gs
和 %ss
)归零:
mov [=10=], %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
指令从字符串中获取一个字符(LOaD String Byte,自动递增%si
给你:
lodsb // Character is stored in `%al` now
另一个建议是不要手动寻址显存。使用 BIOS Interrupt 0x10.
祝你的引导加载程序好运!
我正在写一个小引导扇区用于学习目的。
这里是boot.S
.code16
.text
movw [=10=]xB800, %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 [=10=]x07, %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
我遇到标签没有相对引用的问题:加载字节'A'时,使用的是绝对地址,比如0x7c14)。
所以我不能在运行时重新定位这个引导扇区(例如通过在内存中进一步复制它)。如果通过当前指令的偏移量简单地引用标签会更好。
可以这样做吗?
当然可以重新定位字符串。
首先,你的-Ttext 0x7C00
是正确的。不要改变它。
在引导加载程序的开头,您应该将段寄存器(%ds
、%es
、%fs
、%gs
和 %ss
)归零:
mov [=10=], %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
指令从字符串中获取一个字符(LOaD String Byte,自动递增%si
给你:
lodsb // Character is stored in `%al` now
另一个建议是不要手动寻址显存。使用 BIOS Interrupt 0x10.
祝你的引导加载程序好运!