さて、アセンブリ/C で 2 段階のブートローダーを作成しようとしましたが、JMP を機能させることができませんでした。最初は読み取りが失敗していると思いましたが、次のテストの後、それを除外しました。
__asm__ __volatile__(
"xorw %ax, %ax;"
"movw %ax, %ds;"
"movw %ax, %es;"
"movb $0x02, %ah;"
"movb $0x01, %al;"
"movw $0x7E00, %bx;"
"movw $0x0003, %cx;"
"xorb %dh, %dh;"
"int $0x13;"
"movb 0x7E00, %al;"
"movb $0x0e, %ah;"
"int $0x10;"
//"jmp 0x7E00"
);
これにより、期待どおりに「f」が出力され(セクターの最初のバイトは「f」のASCIIコードである0x66です)、読み取りが成功し、これjmp
が問題であることを証明しています。これは私のコードです:
__asm__(".code16\n");
__asm__(".code16gcc\n");
__asm__("jmpl $0x0000, $main\n");
void main(){
__asm__ __volatile__(
"xorw %ax, %ax;"
"movw %ax, %ds;"
"movw %ax, %es;"
"movb $0x02, %ah;"
"movb $0x01, %al;"
"movw $0x7E00, %bx;"
"movw $0x0003, %cx;"
"xorb %dh, %dh;"
"int $0x13;"
"jmp $0x200;"
);
}
実行すると、プログラムが単にハングします。これは、プログラムがメモリ内の間違った場所にジャンプしている可能性があることを意味します。ところで、私は明らかにこれを VMWare プレーヤーの下でリアル モードで実行しています。これを次のコマンドでコンパイルしています。
gcc -c -0s -march=i686 -ffreestanding -Wall -Werror boot.c -o boot.o
ld -static -Ttest.ld -nostdlib --nmagic -o boot.elf boot.o --no-check-sections
objcopy -0 binary boot.elf boot.bin
これはtest.ld
次のとおりです。
ENTRY(main);
SECTIONS
{
. = 0x7C00;
.text : AT(0x7C00)
{
*(.test);
}
.sig : AT(0x7DFE)
{
SHORT(0xAA55);
}
}
注: これはインライン asm の問題ではないことを確認しました - 純粋なアセンブリの実装も試してみましたが、同じ結果が得られました - C を使用している唯一の理由は、これを少し拡張する予定であり、はるかに快適だからです。 Cループと関数で...
編集:フロッピー ドライブの最初の 3 セクタをここにアップロードしました
編集 2:提案を使用してブートローダーを動作させることができませんでした。@RossRidge からのアドバイスに基づいて、同じプログラムのアセンブリ バージョンと、入力をエコーする単純なアセンブリ プログラムを作成しました。悲しいことに、これらも機能していません..
ブートローダー:
org 0x7c00
xor ax, ax
mov ds, ax
mov es, ax
mov ah, 0x02
mov al, 0x01
mov bx, 0x7E00
mov cx, 0x0003
xor dh, dh
int 0x13
jmp 0x7E00
セクター 3 のプログラム:
xor ax, ax
int 0x16
mov ah, 0xe
int 0x10
これらはどちらも次のようにコンパイルされてnasm Linux/boot.S -o Linux/asm.bin
おり、対応する C と同じように動作します。