2012-03-24 6 views
3

私はリアルモードOSで作業していました。アセンブリで書いて、NASMでフラットな.bin実行ファイルにコンパイルしています。
私はCにOSの一部を書くのが好き、と私は最初の文字列にアクセスし、印刷したいの実験プログラム(ctest.c)を書いただろう:私はこれをコンパイル
16ビット.com CプログラムのリアルモードOS

void test(); 

int main() { test(); return 0; } 

char msg [] = "Hello World!"; 

void test() { 
    _asm 
    { 
     mov si, word ptr [msg] 
     mov al, [si] 
     mov ah, 0eh 
     int 10h 
    } 
    for(;;); 
} 

をOpen Watcom v1.9ではwcl ctest.c -lr -l=COMを使用しています。これによりctest.comが作成されます。 NASMアセンブリで書いたカーネルは、このプログラムを0x2010:0x0000にロードし、DSとESを0x2000:0x0000に設定して0x2010:0x0000にジャンプします。これは、アセンブリで書かれ、nasm -f bin test.asm -o test.comでコンパイルされた.COMプログラムを呼び出す方法です。
OSをテストすると(Bochsを使用)、ctest.comを正常に読み込みますが、msg []の一部ではない無意味な文字が出力されます。
誰もこれについて何か提案はありますか?私は文字列がちょうど間違った場所で初期化されていると思う。私はこれを16ビットOSとして保存したいと考えています。
ありがとう!

+2

.comメモリイメージの最初の128バイトには、CP/Mと同様のオペレーティングシステムデータが含まれています。 DOSはそれに依存します。次の128バイトにはコマンドラインが含まれています。実行は0x100から開始されます。 –

答えて

4

間違ったアドレスを使用しています。

あなたは0x2000でのいずれかの負荷:は0x0100と0x2000で移動:は0x0100(それより前のDS = ES = SS = 0x2000でとSP = 0を設定することを忘れないでください)ORあなたは0x2000で時にロード:0x0000に(等価0x1FF0:0x0100 = 0x1FF0 * 0x10 + 0x0100 = 0x20000 =リアルモードの物理メモリアドレス)0x1FF0にジャンプ:0x0100(DS = ES = SS = 0x1FF0とSP = 0の設定を忘れないでください。それ)。

なぜなら、コンパイルされたx86コードは一般に位置に依存しないため、コードを移動すると、コード内の一部のデータオフセットを調整する必要があります。明らかに、あなたはこれらの調整を行っていませんでした。単純なケースでは、調整するものは何もなく、間違ったアドレスで逃げました。

EDIT

実際には、より多くの問題がここにあります:あなたは文字列の中にあるものでsiをロードしたくないので

  1. mov si, word ptr [msg]lea si, byte ptr [msg]に変更する必要がありますがしたいです、文字列のアドレスでロードします。
  2. OWによってプログラムにリンクされているスタートアップコードは、DOSに依存しており、プログラムを起動するときには持っていないDOS関数を呼び出します。これを回避するにはhereを参照してください。
1

MS-DOSでは、COMプログラムはオフセット0x100で読み込まれました。私はOpen Watcomがその前提を作ってくれると思います。 0x2010:0x0100にCOMプログラムをロードして、それが何をするかを見てみましょう。

+0

私はちょうどそれを試み、それは動作しませんでした。ちなみに、私は仮想フロッピーディスクからセクタを読み取るためにint 13h ah 2を使用しています。 – user1112148

+0

最後のアドレスは明らかに間違っています。 –

関連する問題