2017-03-08 11 views
2

https://github.com/cfenollosa/os-tutorial/tree/master/05-bootsector-functions-stringsから学んで、私は自分自身のブートセクタを書くことを試みてきました。NASM命令シーケンス

現在、指定された文字列を印刷しようとしています。

これらは私の二つのファイルです:

boot_main.asm

[org 0x7c00] 

mov bx, hello 
call print 
jmp $ 

hello db 'HI', 0 

%include "boot_print.asm" 

times 510 - ($ - $$) db 0 
dw 0xaa55 

boot_print.asm

print: 
    pusha 

start: 
    mov al, [bx] 
    cmp al, 0 
    je done 

    mov ah, 0x0e 
    int 0x10 

    add bx, 1 
    jmp start 

done: 
    popa 
    ret 

print_nl: 
    pusha 
    mov ah, 0x0e 
    mov al, 0x0a 
    int 0x10 
    mov al, 0x0d 
    int 0x10 

    jmp done 

は今、これは画面の上で完全に、版画 "HI" で動作します。しかし、私が命令hello db 'HI', 0を最初に動かすと。すなわち

boot_main.asm

[org 0x7c00] 

hello db 'HI', 0 

mov bx, hello 
call print 
jmp $ 

%include "boot_print.asm" 

times 510 - ($ - $$) db 0 
dw 0xaa55 

これがすべてで何かを印刷することができません。私は2つの違いを理解しようとしています。どんな助け?

答えて

3

アセンブラは、ソースファイルに書き込む場所に従って、メモリにstuffを配置します。 orgディレクティブの後に最初に置くと、HI\0の文字列がそこに置かれ、CPUはコードであるかのように実行します(無意味なことやエラーが発生する可能性があります)。

元のコードでは、文字列はjmp $の後ろにあり、命令ポインタによって到達されていない場所に安全に格納されます。

あなたはCPUがあなたはそれが再び作業を開始していることがわかります文字列擦り替える作るためにあなたのコードを変更する場合:

再び
[org 0x7c00] 
    jmp real_start 
    hello db 'HI', 0 
real_start: 
    mov bx, hello 
    call print 
    jmp $ 
    %include "boot_print.asm" 
    times 510 - ($ - $$) db 0 
    dw 0xaa55 

あなたはdbが本当に魔法何もしないと思われる場合、これは明らかになったが文字列については、出力バイナリの任意のバイトを書き込む位置に出力します。実行パスにそれらを書き込むと、CPUがそれらの上を走ります。もし、CPUにそれらを回避するように指示すれば、回避するでしょう。

+1

あなたの例では、ケーキのアイシングが美しく、ありがとう! :) –

+1

@KarthikNayak:うれしかったよ!興味深いことに、データを混在させないようにするコードは、位置に依存しないコードを生成する際に実際には「実生活で」使用されますが、小さなデータではあるが即時性はありませんが、それを使用している寒さと一緒にキャッシュに入っています。 –

+0

オフトピック、あなたのプロフィールのジョークを説明できますか? –