問題タブ [real-mode]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - JMPが機能しない
さて、アセンブリ/C で 2 段階のブートローダーを作成しようとしましたが、JMP を機能させることができませんでした。最初は読み取りが失敗していると思いましたが、次のテストの後、それを除外しました。
これにより、期待どおりに「f」が出力され(セクターの最初のバイトは「f」のASCIIコードである0x66です)、読み取りが成功し、これjmp
が問題であることを証明しています。これは私のコードです:
実行すると、プログラムが単にハングします。これは、プログラムがメモリ内の間違った場所にジャンプしている可能性があることを意味します。ところで、私は明らかにこれを VMWare プレーヤーの下でリアル モードで実行しています。これを次のコマンドでコンパイルしています。
これはtest.ld
次のとおりです。
注: これはインライン asm の問題ではないことを確認しました - 純粋なアセンブリの実装も試してみましたが、同じ結果が得られました - C を使用している唯一の理由は、これを少し拡張する予定であり、はるかに快適だからです。 Cループと関数で...
編集:フロッピー ドライブの最初の 3 セクタをここにアップロードしました
編集 2:提案を使用してブートローダーを動作させることができませんでした。@RossRidge からのアドバイスに基づいて、同じプログラムのアセンブリ バージョンと、入力をエコーする単純なアセンブリ プログラムを作成しました。悲しいことに、これらも機能していません..
ブートローダー:
セクター 3 のプログラム:
これらはどちらも次のようにコンパイルされてnasm Linux/boot.S -o Linux/asm.bin
おり、対応する C と同じように動作します。
x86 - デバイス ドライバー開発に関連するリアル モードの制限事項
私の質問は、デバイス ドライバーの開発に関するものです。
Toy OS を作成するためにリアル モードを使用したいが、ネットワーク スタック/ネットワーク ドライバーのセットを作成することにした場合、それを行う十分な余地はありますか? そのようなことを達成するには、DOS のようにして保護モードに切り替える必要がありますか?
bios - GRUB からリアルモード BIOS / VESA 呼び出しを使用するには?
起動プロセスの初期段階でいくつかの追加のビデオ設定/初期化を有効にする単純な Grub モジュールを開発しています。私の実際の最良のアイデアは、タスクにいくつかの VESA 呼び出しを使用することです。
残念ながら、最近、Grub からリアル モード呼び出しを利用できないことがわかりました。
しかし GRUB は、おそらく BIOS の助けなしには想像もつかないような、本当に複雑な操作を行うことができます。
それはどのように可能ですか?grub から bios を呼び出すにはどうすればよいですか?
x86 - リアル モードでページングを有効にすることはできますか?
BIOS の実行中など、リアル モードでページングを有効にすることは可能ですか。有効になっている場合、リアルモードでのページングの使用は何ですか
x86 - ビッグリアルモードでのアドレス変換
http://wiki.osdev.org/Unreal_Modeが言うように、大きなリアル モードでアドレス変換がどのように行われるかについていくつか質問があります。
アンリアル モードは、リアル モード セグメントの「64Kb」制限を破ることで構成されますが、ディスクリプタ キャッシュを微調整することで、16 ビットの命令とセグメント * 16 + オフセット アドレスの形成を維持します。
しかし、私の質問は、プロセスでgdtがどのように使用されるか、または線形アドレスへの変換中にまったく使用されるかです。ビッグ リアル モードに切り替えるための仕様やその他のリファレンスを誰かが指摘できれば、非常に役に立ちます。
よろしく、
アルカ
c - リアル モードで動作しないいくつかの clang 生成アセンブリ (.COM、タイニー メモリ モデル)
まず、これはリアルモード DOS .COM 用のカスタム メモリ アロケータ (フリースタンディング)のフォローアップのようなものです — デバッグ方法は? . しかし、自己完結型にするために、背景は次のとおりです。
clang
(そしてgcc
、あまりにも)には-m16
スイッチがあるため、命令セットの長い命令はi386
「16ビット」リアルモードで実行するためにプレフィックスされます。このブログ投稿.COM
で説明されているように、GNU リンカを使用して DOS 32bit-realmode-executables を作成するためにこれを悪用できます。(もちろん、まだ小さなメモリ モデルに制限されています。1 つの 64KB セグメント内のすべてを意味します) これで遊んでみたくて、非常にうまく動作するように見える最小限のランタイムを作成しました。
次に、最近作成したcurses ベースのゲームをこのランタイムでビルドしようとしましたが、クラッシュしました。私が最初に遭遇したのは、古典的なheisenbug でした。問題のある間違った値を出力すると、正しくなりました。次のクラッシュに直面するためだけに、回避策を見つけました。したがって、私が念頭に置いていた最初の責任は、カスタムmalloc()
実装でした。他の質問を参照してください。しかし、これまでのところ本当に問題があることに誰も気付いていなかったので、ハイゼンバグをもう一度見てみることにしました。次のコード スニペットで明らかになります (他のプラットフォーム用にコンパイルした場合、これは問題なく機能したことに注意してください)。
sizeof(Slot)
は 8 (clang
とi386
アーキテクチャ)、sizeof(Board)
は 20 とw
はh
ゲーム ボードの寸法です。ここで何が起こっているかをデバッグするために、malloc()
出力をそのパラメーターにしました。値 12 ( sizeof(board) + (-1) * sizeof(Slot)
?)で呼び出されました。
印刷するw
とh
正しい値が表示されましたが、それでもmalloc()
12になりました。印刷するとsize
、正しく計算されたサイズが表示され、今回malloc()
も正しい値が得られました。だから、古典的なハイゼンバグ。
私が見つけた回避策は次のようになります。
奇妙なことに、これはうまくいきました。次の論理的なステップ: 生成されたアセンブリを比較します。x86
ここで、私はまったく新しい6502
. したがって、次のスニペットでは、私の仮定と考えをコメントとして追加します。ここで修正してください。
最初に「壊れた」元のバージョン ( w
,h
は ,%esi
にあります%edi
):
さて、私にはこれで良さそうに見えますが、malloc()
前述のように 12 と表示されます。ループを使用した回避策は、次のアセンブリにコンパイルされます。
前述のように、この 2 番目のバリアントは期待どおりに機能します。結局のところ、私の質問は、この長いテキストと同じくらい単純です...なぜですか? ここで欠けているリアルモードについて何か特別なことはありますか?
参考までに、このコミットには両方のコード バージョンが含まれています。回避策のあるバージョンを入力するだけmake -f libdos.mk
です (後でクラッシュします)。バグの原因となるコードをコンパイルするには、最初に-DDOSREAL
からを削除します。CFLAGS
libdos.mk
更新:コメントを考慮して、私はこれを自分でもう少し深くデバッグしようとしました。dosboxのデバッガを使うのはちょっと面倒ですが、やっとこのバグの位置で壊れるようになりました。したがって、次のアセンブリ コードは によって意図されていclang
ます。
最終的には次のようになります (dosbox の逆アセンブラーで使用される intel 構文に注意してください):
この命令は疑わしいと思います。lea
実際、その後、間違った値が に含まれていax
ます。そこで、同じアセンブリ ソースを GNU アセンブラーにフィードしてみまし.code16
た。次の結果が得られました ( objdump
.
唯一の違いは、このlea
指示です。67
ここでは16ビットリアルモードで「アドレスは32ビット」という意味から始まります。私の推測では、アドレスを操作するためのものであり、ここでデータ計算を行うためにオプティマイザによって単に「悪用」されるため、これは実際に必要です。lea
私の仮定は正しいですか?もしそうなら、これはclang
の内部アセンブラのバグ-m16
でしょうか? 多分誰かがこれがどこから668D060C00
放出されたのclang
か、そしてその意味を説明できるでしょうか? 66
「データは32ビット」を意味し、8D
おそらくオペコード自体です---しかし、残りはどうですか?
assembly - リアルモードで far アドレスにジャンプする
リアル モードで far アドレスにジャンプする必要がある状況があります。レジスタにセグメント値があり、fs
レジスタにオフセットがgs
あり、ジャンプ中に正確なレジスタの内容を維持する必要があります。次のような 1 つのアイデアを思いつきました。続く、
と仮定しbp
、呼び出された宛先で読み取られない場合、NASM far jump / far call in real mode と ASM コード規則で見つけた別の方法を使用できます。fs
gs
どの方法を使用すべきか、またはこれを達成する他の方法があるかどうか疑問に思っていますか? 私は x86 アセンブリのスキルがあまりないので、私の無知を許してください。
よろしく、
アルカ
networking - NASM (カスタム OS) でネットワーク デバイスを一覧表示する方法
NASM に完全に組み込まれたカスタムの DOS ライクな OS を持っています (C コードはありません)。非常に控えめです (FAT ファイル システムがあり、いくつかのアプリがあり、リアル モードであるなど)。現在接続されているすべてのネットワーク デバイス (ネットワーク カード) を一覧表示するコマンドを作成したいと考えています。
私の仮定は次のようになります: ネットワーク カード用のドライバーを作成する必要があります (簡単にするために手動でカーネル内に配置するので、動的な読み込みは存在しません)、そのドライバーが名前を提供するだけで十分です。カードの場合、ネットワーク カードは実際に機能する必要はありません。その機能を正確にその1つのネットワークカードに接続するようにOSに指示するにはどうすればよいですか? これは私が青ざめていることです。OSが通常、ハードウェアとコード(そのドライバー)をどのように一致させるのかわかりません。
assembly - 16ビットリアルモードで1MBしかアクセスできないのはなぜですか?
16 ビット リアル モードで 1MB のメモリしかアクセスできない理由がわかりません。1MBの制限はメモリアクセスを示していますか? システムの起動時に下位互換性のために 16 ビット レジスタに制限されていることは知っていますが、メモリに対する制限はなぜ、どのように行われるのでしょうか?