2

私は、bootsect.s が言及されているオペレーティング システムをオンラインで学習している初心者です 。 boot/bootsect.S しかし、このコードは私にとって非常に奇妙です:

        mov ax,#BOOTSEG
        mov ds,ax
        mov ax,#INITSEG
        mov es,ax
        mov cx,#256
        sub si,si
        sub di,di
        cld
        rep
        movsw
        jmpi    go,INITSEG

奇妙な部分は最後の3行です。私の理解によると、rep movswは既にコード自体を移動しているため、pc が指しているときに、pc が指すjumpiコードをコンピューターが実行しようとすると、コードが移動されているためエラーが発生するはずjumpi go, INITSEGです。では、なぜこのコードがまだ機能し、jumpi go, INITSEGまだ見つけて実行できるのでしょうか?

4

1 に答える 1

3

OPのコメントより

...しかし、PC は #BOOTSEG で始まるセクションを指しており、そこにはもうコードはありません。だから私はjumpi go、INITSEGが実行されないと思った。

安心してください、コードはまだそこにあります!

これは、BIOS が線形アドレス 00007C00h でブートセクタをロードしたときにメモリがどのように満たされたかを示しています。

00007C00    mov ax,#BOOTSEG     ; 07C0h
00007C03    mov ds,ax
00007C05    mov ax,#INITSEG     ; 9000h
00007C08    mov es,ax
00007C0A    mov cx,#256
00007C0D    sub si,si
00007C0F    sub di,di
00007C11    cld
00007C12    rep movsw
00007C14    jmpi    go,INITSEG  ; Far jump (EAh, 19h, 00h, 00h, 90h)
00007C19    go:

命令が処理を完了rep movswすると、00090000h のメモリには、00007C00hにある 512 バイトの正確なコピーが格納されます。このコードの作成者は、コード自体が移動すると述べていますが、これは単なる言論の問題です。作成されるのは常に複製です。ソース バイトは、もちろん と の 2 つのメモリ領域の間にオーバーラップがない限り、まだそこにありますが、DS:SIここES:DIではそうではありません。

結果として、命令ポインターは 00007C14h になり、 goラベルがある線形アドレス 00090019h へのファー ジャンプ (セグメント間) を実行します。
この時点から、00007C00h の 512 バイトは無視できます。

于 2019-06-16T19:16:54.120 に答える