5

アセンブリを使用してブートストラップを作成する練習をしています (AT&T 構文と gnu/gas)。小さなプログラムが組み立てられてリンクされ、仮想ディスクの最初のセクターにコピーされます。BIOS はそれを にロードしますが0000:7c00、ここで問題が発生します。は、実行中に からにcall hello変換されます。しかし、は移転しません。は、まだありません。その結果、画面上で を作成できません。代わりに、ランダムなデータが画面に表示されます。call 0010call 7c10movw $message, %asax00267c26Hello World0000: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
4

1 に答える 1

1

主な問題は、コードをコンパイルする方法にあることがわかります。

コードを機能させるための正しい手順は次のとおりです。

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>

2 バイト (最初のジャンプ命令の長さ) の後にディスク記述テーブルを配置する必要があるため、これは BIOS コードがハード ドライブをどのように認識するかに準拠していることに注意してください。

さらに、次のasようなより似た構文で最後の命令をリファクタリングできます。

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

変数.はロケーション カウンターです。このカウンターがどのように機能するか (ではなくのコンテキストで) の詳細については、このページを参照してください。ldas

お役に立てれば!

于 2012-10-09T21:13:25.247 に答える