Вопрос

Я практикуюсь в написании начальной загрузки с использованием ассемблера (в синтаксисе AT&T и gnu/gas).Небольшая программа ассемблируется и компонуется, а затем копируется в первый сектор виртуального диска.BIOS загрузит его в 0000:7c00, и тут возникает проблема.А call hello будет переведен с call 0010 к call 7c10 во время бега.Но movw $message, %as не переезжает.А ax все еще 0026, нет 7c26.В результате я не могу сделать Hello World на экране.Вместо этого некоторые случайные данные в 0000:0026 будет отображаться на экране.

Как я могу сделать это правильно во время загрузки?Должен ли я изменить исходный код asm, используя некоторые директивы?Или мне следует изменить сценарий ссылки?

Спасибо!

.text
.global     _start
.code16

_start:
movw    %cs, %ax
movw    %ax, %ds
movw    %ax, %es
call    hello
jmp     .

.org    0x10

hello:
movw    $message, %ax
movw    %ax, %bp
movw    $13, %cx
movw    $0x1301, %ax
movw    $0x000c, %bx
movb    $0, %dl
int     $0x10
ret

message:    
.ascii  "Hello, World!"

.org    0x01fe
.byte   0x55
.byte   0xaa

Я использую следующие сценарии сборки и компоновки

as -o boot.o boot.s  
    //generate object code

ld -Ttext 0x0 -e _start -s -o boot.out boot.o  
    //relocate .text to 0x0
    //entry is _start

objcopy -O binary -j .text boot.out boot
    //copy .text section to boot

vboxmanage convertfromraw boot boot.vdi --format VDI
    //create vdi for virtual box
Это было полезно?

Решение

Я вижу, что основная проблема заключается в том, как вы компилируете свой код.

Правильные шаги для того, чтобы ваш код работал:

as boot.s -c -o boot.o
ld --oformat binary --Ttext 0x7C00 -o boot.bin boot.o

Обратите внимание, как уже говорили другие, я передаю --Ttext 0x7C00 параметр для ld, чтобы заставить его переместить ваш код по этому адресу.

В качестве дополнительного предложения попробуйте структурировать свой код следующим образом:

.text
.global     _start
.code16

_start:
jmp stage1_start

...

stage1_start:

<your bootloader here>

Обратите внимание, что это соответствует тому, как код BIOS выглядит на жестких дисках, поскольку после 2 байтов (длина первой инструкции перехода) следует разместить таблицу описания диска.

Кроме того, вы можете реорганизовать свои последние инструкции в более as-подобный синтаксис:

. = _start + 0x0200 - 2
.short 0x0AA55

Где . переменная — счетчик местоположения.Посмотри на эта страница для получения дополнительной информации о том, как работает этот счетчик (в контексте ld, нет as).

Надеюсь это поможет!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top