2012-04-24 4 views
2
ブートセクタを書き込むための方法を

最近イム学習は、ここで私が学んでいます完全なコードですいただきました!:あなたがブートする方法を知っていればアセンブリにおける「組織XXXX」の使用は

org 07c00h 
    mov ax, cs 
    mov ds, ax 
    mov es, ax 
    call DispStr 
    jmp $ 

DispStr: 
    mov ax, BootMessage 
    mov bp, ax 
    mov cx, 16 
    mov ax, 01301h 
    mov bx, 000ch 
    mov dl, 0 
    int 10h 
    ret 

BootMessage: db "Hello, OS!" 
times 510-($-$$) db 0 

dw 0xaa55 

非常に簡単なコードはシステム。結果は、画面に表示されたHello OS!という行です。最初の行はorg 07c00hです。この行は、コード行がコンパイラに7c00hの場所にアドレスを割り当てることを通知しますが、その説明は次のとおりです非常にあいまいで、私は実際にここでその使い方を知っていません。どのintheworldラインorg 07c00hここですか?私はその行を削除しようとし、binファイルを作成するためにnasmを使い、bochを使ってbinファイルをブートしました。以前のものとは何の違いもありません。「こんにちはOS!画面にも表示されます。最初の行はここで何もしないと言うことができますか?どのようなorg xxxx intheworldの使用ですか?

+0

本書の内容を正確に示しています。あなたがそれを理解していない場合は、おそらく基礎を再検討する必要があります。特に、メモリの仕組みを理解する必要があります。 –

+3

[nasm manual](http://www.nasm.us/doc/nasmdoc7.html#section-7.1.1)は次のように述べています。「ORG指令の機能は、NASMがプログラムがメモリにロードされたときに開始されます。 "私。あなたはアセンブラに、それ自身では理解できない何かを伝えています:プログラムがロードされるアドレス。 – user786653

+0

@カール:まず、助けて親切なことと、ちょうど怒っているのではなく、啓発するように人々に答える方法を理解する必要があります。 – SasQ

答えて

3

ここでは、アセンブラとリンカを1つのステップで使用します。 orgは、アセンブラに、リンカにこれらの場合はしばしば同じプログラムを指示します。物理メモリ空間では、後に続くコードを配置します。 Cコンパイラやその他の高水準言語コンパイラを使用する場合は、コンパイルとリンクのステップが別々になることがよくあります(ただし、コンパイラはたいていあなたのためにリンカを呼び出します)。ソースは、位置に依存しないオブジェクトファイルにコンパイルされ、リンクステップで待機していない命令の一部が残っています。リンカは、オブジェクトと、リンカスクリプトまたはメモリ空間を記述するユーザからの情報を受け取り、そこからそのメモリ空間の命令を符号化する。

User786653アセンブラは命令に位置依存エンコードを行う必要がある場合に、これらの命令が生きるメモリ空間/アドレスを自分自身で把握することができます。また、elf、srec、ihexなどのアドレス情報を含むバイナリの場合は、出力バイナリ内のその情報を使用します。

+0

thxですが、 'org 7c00h'はどういう意味ですか?セグメントが7c00h、またはオフセットが7c00hですか?どのツールを使用してアドレスを検出できますか? – Searene

+0

大丈夫、bochsデバッガを使って、0x7c00hがオフセットアドレスの部分に追加されていることがわかりました。もし 'org 07c00h'の最初の行がなければ、システムは' BootMessage'という文字列の間違ったアドレスをロードします。 。私は多くのことを学びました。 – Searene

2

アセンブラは、ソーシングコードの各行をプロセッサ命令に変換し、出力バイナリファイルに順に1つずつ順番に出力します。そうすることで、彼はそのような命令の現在のアドレスを0から上にカウントする内部カウンタを維持する。

通常のプログラムをアセンブルしている場合、これらの手順は、後でリンカによって適切なアドレスが埋め込まれなければならないアドレス用の空白スロットを持つオブジェクトファイルのコードセクションに終わるでしょう。問題。

しかし、セクション、再配置、その他の書式設定なしで、生のマシン命令だけを使用してフラットなバイナリファイルをアセンブルする場合、ラベルの場所とデータのアドレスについては、アセンブラの情報はありません。たとえば、指示がmov si, someLabelの場合、アセンブラはバイナリファイルの先頭にある0から始まるこのラベルのオフセットを計算することしかできません。つまり、コードセグメントのオフセット0から始まるメモリにコードが配置されていると想定します。

これが真実ではなく、メモリ内のマシン命令を別のアドレスから開始する場合は、 7C00の場合は、ソースの先頭にorg 0x7C00と記述して、プログラムの開始アドレスが7C00であることをアセンブラに伝える必要があります。このディレクティブは、0ではなく、7C00から内部アドレスカウンタを起動する必要があることをアセンブラに通知します。その結果、そのようなプログラムで使用されるすべてのアドレスは7C00だけシフトされます。アセンブラは、ラベルごとに計算されたアドレスのそれぞれに7C00を単に追加します。その効果は、バイナリイメージファイルの先頭から48バイトだけオフセットされていても、ラベルが00480000 + 48)の代わりに、アドレスが7C487C00 + 48)のメモリに配置されているかのようになりますオフセット7C00でロードすると適切なアドレスが得られます)。

その他の質問:7C00は、ブートローダの物理アドレスです。この物理アドレスは、セグメントが重複するため(次のセグメントは前のセグメントの後に16進数で16進数で16進数で始まります)、論理アドレス(セグメント:オフセット)で表すことができます。たとえば、最も簡単な構成である論理アドレス0000:7C00を使用できます。セグメント0をRAMの先頭から、オフセット7C00をその0から使用します。または、論理アドレス07C0:00007C0番目のセグメント)を使用できます。セグメントは互いに16バイト離れていることを覚えていますか?したがって、7C010(小数点では16)と単純に掛け合わせると、7C00が得られます - 参照してください。あなたの16進アドレスの1桁右シフトの問題です!今度は0のオフセットを追加するだけで、物理的にはまだ7C00です。セグメントの0バイトは、メモリ内で7C00で始まります。

もちろん、あなたはまた、のようなより複雑なアドレスを、使用することができますセグメントが2340から始まり、あなたがそれにオフセット58C0を追加するとき、あなたは再び:-)しかし、ことをやって7C00を買ってあげることを意味たとえば、0234:58C0、用混乱する可能性があります。それはすべてあなたが必要な構成に依存します。セグメントの先頭に7C00という物理アドレスを使用する場合は、セグメント07C0を使用し、最初の命令はオフセット0になるので、orgディレクティブを入力する必要はなく、org 0を入力することもできます。しかし、7C00アドレスの下のデータを読み書きする必要がある場合(たとえば、BIOSデータや割り込みベクタを参照するなど)、セグメント0とオフセット7C00を使用すると、最初の命令(バイナリファイルの0番目のバイト)がメモリ内の7C00の物理アドレスに配置してください。上記の理由からorg 0x7C00指令を追加する必要があります。

関連する問題