質問

Cのメモリモデルし、その利用のポインタを演算すべて、モデルの平坦なアドレス空間です。16ビットパソコン用グメモリアクセス。どうして16ビットのCコンパイラでコンパイルの問題とシミュレーションを平らなアドレス空間の視点からは、Cプログラマー?例えば、大体アセンブリ言語の指示が以下のコードをコンパイルに関する8086の?

long arr[65536];  // Assume 32 bit longs.
long i;
for(i = 0; i < 65536; i++) {
    arr[i] = i;
}
役に立ちましたか?

解決

どうして16ビットのCコンパイラに対応 この問題をシミュレーション平住所 スペースの観点からC プログラマー?

れなかった。その代わりに、それられた区分では、Cプログラマー、さらには言語により複数のポインター: near, far, は、 huge.A near ポインタがオフセットを farhuge ポインタが複合セグメントを相殺するものとする。また、コンパイラオプションの設定を 記憶モデル, を決定するかどうか、デフォルトのポインタ型になった。

Windowsのコードは、現在もなお、いくtypedefsのように LPCSTRconst char*).の年録音の本作は、コルトレーン"は、ホールドオーバーからの16ビットの日そのために"(これまでのポインタ".

他のヒント

Cのメモリモデルは、どのような方法でフラットなアドレス空間を意味するものではありません。それはやったことはありません。実際には、C言語仕様は、具体的には、非平坦アドレス空間を可能にするように設計されています。

はセグメント化されたアドレス空間と最も些細な実装では、最大連続オブジェクトのサイズは、セグメント(16ビットプラットフォーム上で65536バイト)のサイズによって制限されるであろう。このような実装でsize_tは16ビットであろうと、あなたが許可された最大より大きいサイズを持つオブジェクトを宣言しようとしているので、あなたのコードは単純に、コンパイルされないであろうと、この手段ます。

Aより複雑な実装では、いわゆるの巨大なのメモリ・モデルをサポートしています。あなたは見、何の問題セグメント化されたメモリモデルののいずれかのの大きさの連続したメモリブロックのアドレス指定は、それだけでポインタ算術演算では、いくつかの余分な努力が必要で、本当にありません。だから、巨大なメモリモデル内で、実装が少し遅くコードになるだろうそれらの余分な努力をするだろうが、同時に、事実上任意のサイズのオブジェクトを扱うことが可能になります。だから、あなたのコードは完全に罰金をコンパイルします。

真の16ビット環境では、任意のアドレスに達する16ビット・ポインタを使用します。例としては、PDP-11、6800家族(6802、6809、68HC11)、および8085.これは単純な32ビットアーキテクチャのような、クリーンで効率的な環境である。

を含みます

私たちに宇宙への対処-theネイティブ8086いわゆる「リアルモード」でのハイブリッド16ビット/ 20ビットのアドレス空間を強制的に80×86家族。これに対処するための通常の機構は、2つの基本的な種類、near(16ビットポインタ)とfar(32ビットポインタ)へのポインタの種類を高めることでした。コードとデータポインタのデフォルトは、「メモリモデル」により一括で設定できます。tinysmallcompactmediumfar、およびhuge(いくつかのコンパイラは、すべてのモデルをサポートしていません)。

tinyメモリモデルは、空間全体(コード+データ+スタック)が64K未満である小さなプログラムのために有用です。すべてのポインタは16ビットまたはnearを(デフォルトでは)です。ポインタは、暗黙的にプログラム全体のセグメント値に関連付けられている。

smallモデルは、データ+スタックは以下64K以上と同じセグメント内にあることを前提とし、コードセグメントは、コードが含まれているので、128Kの最大メモリフットプリントのため、ならびに64Kまで有することができます。コードポインタはnearと暗黙CS(コード・セグメント)に関連しています。データポインタはまたnearとDS(データ・セグメント)に関連している。

mediumモデル(小のような)データ+スタックの64Kまで持っているが、コードの任意の量を有することができます。データ・ポインタは16ビットであると暗黙的にデータセグメントに接続されています。コード・ポインタは32ビットfarポインタであり、リンカーはコードグループ(不潔簿記手間)を設定したかに応じて、セグメント値を有する。

compactモデルは、媒体の補数である:コードの64Kよりも小さいが、データの任意の量。データポインタはfarとコードポインタがnearされている。

large又はhugeモデルでは、ポインタのデフォルトのサブタイプは、32ビットまたはfarです。主な違いは、巨大なポインタが常にそれらを自動的にインクリメントすることは64Kラップアラウンドの問題を回避できるように正規化されていることです。こののrel="nofollow">

DOS 16ビットでは、私はそれを行うことができることを覚えてはいけません。あなたは(セグメントを調整し、オフセットゼロにする可能性があるため)各64K(バイト)だった複数のものを持っている可能性がありますが、単一のアレイとの境界を越えることができれば覚えていけません。我々は(386個のまたは486プロセッサ上)32ビットDOSプログラムをコンパイルすることができるまであなたは配列に言ってあなたはウィリーnilly深いとあなたが望んでいたものは何でも割り当てると達する可能性がフラットなメモリ空間が起こるdidntの。恐らく他のオペレーティングシステムおよびMicrosoft以外のコンパイラとボーランドは、64Kバイトよりも大きいフラットアレイを生成することができます。 Win16の私は、Win32のヒットまで、その自由を覚えていけない、おそらく私の記憶が錆びてきている...あなたはとにかくメモリのメガバイトを持っている幸運や豊かだった、256kbyteまたは512Kバイトのマシンは前代未聞ではなかったです。あなたのフロッピードライブは、最終的に1.44メガにMEGの一部を持っていたし、もしあれば、あなたのハードディスクは、大規模なものということが多いますので、ちょうどdidntの計算の事、ダースまたは数メガを持っていました。

あなたは地球上のすべての登録ドメイン名の全体のDNSデータベースをダウンロードすることができたときに

私はDNSについての学習をしていた特定の挑戦を覚えて、実際には、あなたは、ほとんどの時に必要とした独自のDNSサーバーを設置する必要がありましたウェブサイトを持っています。そのファイルは35メガバイトだった、と私のハードディスクは、その一部を噛んで100メガバイト、プラスDOSとWindowsました。おそらくメモリの1または2メガを持っていた、一度に32ビットのDOSプログラムを行うことができたかもしれません。それは私が複数のパスでやったASCIIファイルを解析したいましたが、各出力は別のファイルに行かなければならなかった、と私は、次のファイルをディスク上の余裕を持って前にファイルを削除しなければならなかった渡す場合パート。あなたが別のハードディスクおよびディスクコントローラカードを買う余裕ができれば、ここでの標準的なマザーボード、ハードディスク用とCD-ROMドライブに1つ、再びこのようなものの波平の安い上の2つのディスクコントローラは、予備のISAスロットの多くはありませんでした。

Cで64Kバイトを読み込むのにも問題がありました、あなたは65536バイト65535に0をないもので16ビットのint、で読みたかったバイトのfread数を通過し、そしてあなたも、サイズに読んdidntの場合、パフォーマンスは劇的に低下しましたあなたが最終的にfreadに渡された値が今あったことを確信したときセクターがあなただけのパフォーマンスを最大化するために、一度に32Kバイトを読み込むので、64kのdidntのDOS32日にうまくまで来る32ビット数と上位16を切り落とすしようとしてコンパイラの波平ビットだけ(あなたが十分コンパイラ/バージョンを使用している場合が多いが起こった)下位16ビットを使用します。私たちは16〜32ビットの移行に行ったように我々は現在、32ビット64への移行で同様の問題に苦しんでいます。あなたが適応とほとんど使用されてプログラムをコンパイルなるようにint型や仕事のために何が、最も興味深いのは、長い16から32ビットのintに変更サイズが、unsigned char型に行くと符号なしがなかったことを学んだことを、私のような人々からのコードです16と32ビットの両方。 (の生成種類の人々からのコードは、それを通って住み、同じトリックを使用する他の人に目立ちます)。しかし、32 64への移行、それは他の方法で回避され、UINT32型宣言を使用するようにリファクタリングしないコードのために苦しんでいる。

ちょうど周りに包まれたが、また、常に巨大用にコンパイルすることができない、リング鐘を行うことを巨大なポインターの事、入って来たことをwallykの答えを読みます。小さなあなたは、セグメントを心配する必要はありdidntのため、我々は今日に慣れている、と今日は簡単だったと同じようにフラットなメモリモデルでした。だから、ときにできた小さな用にコンパイルするために望ましいとしました。あなただけのdidntは正常にデータを扱うように、あなたはまだメモリやディスクまたはフロッピー多くのスペースを持っていませんでしそれほど大きくます。

また、別の答えに同意、セグメントオフセット事が8088/8086インテルがしました。全世界がまだインテルに支配されていなかったので、ちょうどフラットなメモリ空間を持っていた他のプラットフォームがあった、またはproblを解決するために(プロセッサ外)おそらくハードウェアに他のトリックを使用しましたEM。そのため、セグメント/オフセットインテルもはやそれはおそらく持っている必要がありますよりも、16ビットのものに乗ることができました。セグメント/オフセットは、あなたがそれを行うことができ、いくつかのクールで面白いものを持っていたが、それは何か他のものほどAの痛み通りでした。あなたはどちらかあなたの人生を簡素化し、フラットなメモリ空間に住んでいたか、あなたは常にセグメント境界を心配しています。

本当に古いのx86の上のアドレスサイズをダウンピン留めすると、ソートトリッキーです。あなたは、その16ビットは、算術ので、あなたが16ビットのレジスタに収まらなければならないアドレスに行うことができると言うことができます。また、実際のアドレスは16ビットの汎用レジスタと16ビット・セグメント・レジスタ(32ビットすべてが重要である)に対して計算されているので、それは、32ビットのだと言うことができます。また、単にセグメントレジスタをアドレス指定するハードウェア放置し、GPレジスタに追加4ビットシフトしているので、それは、20ビットだと言えるでしょう。

彼らはすべてのC抽象マシンのほぼ同じ近似値であるため、

これは実際に、あなたが選択したこれらの多くが1という問題ではありません。他の人がちょうどその32ビットのアドレスを想定しながら、いくつかのコンパイラは慎重に16ビットが命令を発するオーバーフローする可能性その操作を確認し、あなたがコンパイルごとに使用していたメモリモデルを選択しましょうそのハンドルその場合、正しくます。

こののWikipediaのエントリをチェックしてください。ファーポインタについて。基本的に、その可能性は、他のセグメントにジャンプすることを可能にする、セグメントオフセットとを指示する。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top