• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:プロテクトモードのプログラムで・・・ebpはスタックセグメントを使う?)

プロテクトモードでebpを使用してスタックセグメントを設定する方法

このQ&Aのポイント
  • Pentiumのプログラムで0x0009-0000~0x0009-ffffの64KBのスタックセグメントを設定する方法について質問があります。
  • コードセグメントとデータセグメントは0x0000-0000~0x000f-0000の1MBに設定しています。
  • プログラムの動作が正しくない場合、mymain関数の外にあるchar *ptr = (char *)0xa0000;の部分を関数内に移動することで解決できることがあります。

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

確認してみましたが, 確かに EAX は DS に対するオフセット, EBP は SS に対するオフセットとなります. なので, lea $0xfffffffc(%ebp), %eax incl (%eax) と incl $0xfffffffc(%ebp) は意味が異なります (記憶が忘却の彼方ですが, 確か後者みたいにも書けたはず...). アクセスするオフセットは同じでもセグメントが違います. *普通の32ビット実行環境*だと CS, DS, SS のベースアドレスは全て同じであることが多く結果的に問題となりませんが, DS と SS でベースアドレスが異なる場合にはダメですね. ということで, incl (%eax) に対して SS を使うプレフィクスが必要です. char *ptr を外に出すと DS に対するアクセスになるので問題が解消される, ということではないでしょうか. これ, 組込み用のコンパイラだったらただのバグだよぉ.

ttr133
質問者

補足

すばやい書き込みありがとうございます。 だいたいおっしゃるとおりだと理解しました。 たしかに私はCS=DS≠SSとしておりました。 ptrを外に出すとDSが使われていました。 結局CS=DS=SSとすることで解決しました。 ありがとうございます。すっきりしました。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

リスト1 とリスト2 の関係がよくわかりませんが, どのセグメントを使うかはベースレジスタで決まっていて EIP: CS EBP, ESP: SS その他: DS だったはず. だから incl (%eax) のところは SS を使うようにセグメントオーバーライドプレフィクスが必要.

ttr133
質問者

補足

リスト1をコンパイルしてそのオブジェクトファイルから逆アセンブルしたのがリスト2です。 やはり incl (%eax) はDSが対象になっているのですよね? だからSSを使うようにプレフィクスが必要という ことですね?

関連するQ&A