1

x86 アセンブリ言語を学習しており、セグメントの目的と使用法を理解しています。セグメントは重要なデータを保持し、追加のデータを格納するためにも使用できます (つまり、メモリ セグメンテーション モデル)。これが私の質問です。セグメントを使用して追加のデータを保存できる場合、セグメントにデータを保存しても既存のデータが上書きされないようにするにはどうすればよいですか?

たとえば、CS レジスタはコード セグメントを指します。コード セグメントには、プログラムのコードが含まれています。CS レジスタをオフセット付きで使用してデータを格納した場合、格納しているコードを上書きしないようにデータを配置する場所をどのように知ることができますか?

私にお知らせください。私は Intel シンタックス アセンブリを使用し、NASM でアセンブルしています。

ありがとう

4

4 に答える 4

0

それは組み立てなので、あなたはすべてに責任があります。コードとデータを分離するのは、2つの数値を分離するのと同じくらい簡単です。各メモリ位置を最大で1回使用するだけです。

于 2009-10-23T10:34:37.730 に答える
0

すでに述べたことに加えて、通常はコードセグメントに「データ」を格納したくないことを付け加えておきます。そのため、データセグメント(DSが指すベース)または「追加の」データセグメント(-> ES)があります。明らかに、基本的な仮定は、コードセグメントにあるものはすべて実行されるということである必要があるため、そこにランダムなデータ値を書き込むことは非常に賢明ではありません。

コードセグメントにデータを保存する必要がある場合は、次のように、データが実行されないようにしてください。


..some code here..
jmp AfterDataDeclaration
  db 12  ; declare some data here
AfterDataDeclaration:
..some more code here..

[編集:]特定のデータにアクセスする場合は、常に参照ポイントが必要です。これは通常、ラベルで宣言するのが最も便利です。アセンブラを使用すると、実際のアドレスを知らなくても、これにシンボリックにアクセスできます。

コードセグメントに何かを書きたい場合の1つのケースは、そこでマシンコードにパッチを適用したい場合です(つまり、自己変更コード)。

于 2009-10-23T12:07:30.290 に答える
0

すでに述べたように、セグメント レジスタは 16 ビット ポインタのみを保持します。このポインタは、CPU が 20 ビットの大きなアドレス メモリ空間をアドレス指定できるように、内部で 16 倍されます。

1) 十分なメモリがある場合は、スタック用に 64Kb の RAM、データ メモリ用に 64Kb、コード メモリ用に残りを選択できます。SS (スタック セグメント レジスタ) が 0x0400、DS (データ セグメント レジスタ) が 0x0800、CS (コード セグメント レジスタ) が 0x1B00 であるとします。この場合、コードは他のメモリ セグメントをオーバーライドできません。さらに 64K のデータ メモリが必要な場合は、ES セグメントと ES プレフィックスを使用して簡単に拡張できます。

2) 十分なメモリー空間 (コンパクトなプログラム) がない場合は、メモリー境界を予測する必要があります。

3) プログラムでメモリ ポインターを使用する外部呼び出しを使用する場合は、境界を確認する必要があります。この目的のために、x86 ニーモニックの存在するBOUND命令。

于 2009-10-23T16:39:59.193 に答える