0

私は、画面にいくつかのものを出力するだけのこのブートローダーを書いています。これは私がこれまでに組み立てたものです:

    .globl _start

    .code16

_start:

    movw $0x0003, %ax
    int $0x10

    movb $0x0e, %ah
    movb $0x69, %al
    int $0x10

    movw $_header, %bx
    movb %bl, %al
    int $0x10

_header: .ascii "W\0"

    .org 0x1FE

    .byte 0x55
    .byte 0xAA

したがって、現在はASCII 69( "i")を出力しますが、.ascii宣言も出力するようにします。今は設定しているだけ"W"なので、で簡単に見つけることができますObjdump。その値にアクセスできないようです(57)。できleal $_header, %edxますが、の値にアクセスできないようです%edx

使ってみlodsbましたが、わからないようです。%di0x00に設定し、 with%siのアドレスに設定しましたが、その後に続くものは何も出力されないようです。どんなアイデアでもありがたいです。_headerleal %si, _headerlodsbint 0x10

4

1 に答える 1

1

ここ:

movw $_header, %bx
movb %bl, %al

まず、movb %bl, %alメモリからにバイトを読み込んでいるのではなく、からalバイトを読み込んでいますbl。次のように変更します。

movb (%bx), %al

1つの文字だけを取り出すには_header、その文字をメモリからal直接次のようにロードします。

movb _header, %al

第二に、そして最も重要なことに、あなたはいくつかの仮定をしているようです:

  1. コードがcs=0x7c0、ip=0で実行を開始すること。cs代わりに=0、ip= 0x7c00にすることができますが、コードはip= 0を期待しています(コードから、アセンブラーが暗黙的にアセンブルを開始することを推測します.org 0)。この2番目のオプションに対してコードを回復力のあるものにする必要があります。次のようなジャンプ命令と、次の行の対応するラベルを使用して、リロードcsしてより適切な値に戻すことができます。ipjmp $0x7c0,$_next_next:
  2. コードがds=0x7c0で実行を開始すること。ds必要な値に設定される保証はありません。自分で初期化する必要があります。

最後に、最後の後に何が起こりint $0x10ますか?

修正すると、コードは次のようになります。

    .globl _start

    .code16

_start:
    /* .org 0 is implied here! But the code may start with ip != 0. */

    jmp $0x7c0,$_next
_next:
    /* We have just ensured that cs=0x7c0,ip=$_next */

    /* Let's now load data segment registers with proper values */
    movw %cs, %ax
    movw %ax, %ds
    movw %ax, %es

    movw $0x0003, %ax
    int $0x10

    movb $0x0e, %ah
    movb $0x69, %al
    int $0x10

    movw $_header, %bx
    movb (%bx), %al /* read into al a byte from memory at address from bx */
    int $0x10

    /* Halt execution, don't just execute whatever garbage is in memory */
    /*after the end of the code. */
_halt:
    hlt
    jmp _halt

_header: .ascii "W\0"

    .org 0x1FE

    .byte 0x55
    .byte 0xAA
于 2012-10-08T02:01:35.917 に答える