1

私はリアルモードでプログラミングを学んでいて、私にとって非常に役立つSOに関する投稿を見つけましたが、特定のコードで物事がどのように機能しているかについて疑問があります

基本的な NASM ブートストラップ

  ;This is NASM

    BITS 16                 ; 16 bits!

    start:                          ; Entry point
    mov ax, 07C0h           ; Move the starting address (after this bootloader) into 'ax'
    add ax, 288             ; Leave 288 bytes before the stack beginning for some reason
    mov ss, ax              ; Show 'stack segment' where our stack starts
    mov sp, 4096            ; Tell 'stack pointer'  that our stack is 4K in size

    mov ax, 07C0h           ; Use 'ax' as temporary variable for setting 'ds'
    mov ds, ax              ; Set data segment to where we're loaded


    mov si, text_string     ; Put string position into SI (the reg used for this!)
    call print_string       ; Call our string-printing routine

    jmp $                   ; Jump here - infinite loop!

     text_string db 'This is my cool new OS!', 0 ; Our null terminated string

                                                ; For some reason declared after use


   print_string:                   ; Routine: output string in SI to screen
    mov ah, 0Eh             ; I don't know what this does..
                            ; Continue on to 'repeat'
   .repeat:
    lodsb                   ; Get character from DS:SI into AL
    cmp al, 0               ; If end of text_string
    je .done                ; We're done here
    int 10h                 ; Otherwise, print the character (What 10h means)
    jmp .repeat             ; And repeat

   .done:
    ret

    times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
    dw 0xAA55               ; The standard PC 'magic word' boot signature

1)DS と CS はここで重複していますか??

2)CS は 0h の位置から始まりますか?? ここに画像の説明を入力、添付の画像は、アセンブラによって生成されたブートセクタである 512 バイトを示しています

3)DS、CSともに07c00Hから開始されていますか?? まず、文字列のデータを入れる前にコード部分を埋めます

4) スタックは 07c00+288 から始まりますか?? mov sp,4096 は (07c00+288+4096-07c00+288) のサイズのスタックを定義します。

4

2 に答える 2

1

簡単な答え: はい。リアル モード セグメント: オフセット アドレスは重複する可能性があります。BIOS は 7C00h でブートセクタをロードします。これはおそらくcsゼロで、オフセットは 7C00h です (特定の Compac Presario BIOS が 07C0:0000 にロードされたという噂がありますが)。同じアドレスです!これは、リアル モードでアドレスが計算される方法であるため、16 を掛けます (セグメント時間 16 とオフセット)。数字を 4 ビット左にシフトすることで 16 を掛けることができます。

ブーツセクターが一番上にあると言うのが一般的ですorg 7C00h。このコードには がないためorg、Nasm はorg 0. この「一般的な」ブートセクタでは、0 をds(およびes?) に入れます。でorg 07C0h が必要ですds。0000:7C00h と 07C0h:0000 は同じアドレスです。これを見つけることが重要text_stringです。

あなたが見つけたコードのコメントはやや欺瞞的です...それは実際には「288バイト」ではありません。これは hex - 120h と書くとわかりやすいかもしれません。これが 7C0h に加算されて 8E0h になります。次にsp、10 進数の 4096、つまり 1000h がロードされます。したがって、スタックの線形アドレス (セグメント * 16 + オフセット) は 9E00h から始まり、8E00h まで機能します - 7C00h から 7E00h (10 進数の 512 = 200h はブートセクターのサイズ) でコードにぶつからないように十分な余裕があります。

「データ」がコードの途中にあることに注意する価値があるかもしれませんが、それは実行されない位置にあるので問題ありません。

私は算数が正しく、あなたをさらに混乱させていないことを願っています!

于 2013-07-15T17:03:10.437 に答える