2015-02-26 4 views
1

Я пишу маленький сапог для обучения.GNU 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 

я сталкиваются с проблемой, что метка не относительно ссылка: при загрузке байта «A» он использует абсолютный адрес, скажем, 0x7c14).

Так что я не могу переместить этот загрузочный сектор во время выполнения (например, скопировав его дальше в память). Было бы лучше, если бы метка была просто указана через смещение от текущей инструкции.

Возможно ли это?

+0

Вы можете установить '-Ttext' в' 0' и убедиться, что вы начинаете с далекого перехода к '0x7c0: 0'. Затем вы можете переместить свой код в любой сегмент. – Jester

ответ

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

Теперь на Ваш вопрос: Это обычно для решения строк с использованием segmentation в виде %ds:%si. При перемещении загрузчика просто измените значение %ds.
Предполагая, что вы называете строку label:

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

Вы можете получить символ из строки, используя lodsb инструкцию (LODS Тринг B YTE, который автоматически увеличивает %si для вы:

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

Другая рекомендация не является для обращения к видеопамяти вручную. Используйте BIOS Interrupt 0x10.

Удачи вам в загрузчике!

+0

Если я сохраню '' '-Ttext 0x7C00''', то' ''% si''' будет содержать абсолютный адрес, такой как '' '0x7C14'''. Будет проблемой, если я переместлю загрузчик до '' '0x7C00''' (скажем,' '' 0x6000'''), независимо от того, что будет '' '% ds''', нет? И если перемещение происходит после '' '0x7C00''', мне придется каким-то образом вычислить разницу между' ''% si = 0x7C14''' и моим новым перемещением и установить эту разницу как '' '% ds '' '? – anotherCode245

+0

Да, '% si' будет содержать абсолютный адрес, но должно быть возможно изменить'% ds' таким образом, чтобы он все еще указывался на нужную точку. '% si' * относительно *'% ds'. – ababababanababab

+0

Невозможно переместить загрузчик перед '' '0x7C00''', потому что' ''% si''' содержит уже больший адрес – anotherCode245