7

免責事項: 私は C/C++ を初めて使用します。

C の変数に手動でメモリ アドレスを割り当て、その値をエコーアウトしようとした場合...メモリ内の何かを表示するための無制限のアクセス権がありますか、それとも制限がありますか?

例えば:

char * p = (char *)0x28ff44;
printf("Memory value: %c", *p);

そのアドレスにあるものが char 型のサイズに収まらない場合、それは恐ろしくクラッシュすると思いますが、これは単なる例です。私が本当に興味を持っているのは、このようなことが可能かどうか、またはオペレーティングシステムが制限を課して、指定されたメモリ空間のメモリへのアクセスのみを許可するかどうかです.

4

4 に答える 4

6

ああ、そうですね。

技術的には、はい、できます。MMU や保護の形式 (または、リアル モードの x86) を使用しない組み込みデバイスでは、そこに投稿したことを正確に行うことができます。どのオペレーティング システムでもユーザー モードで実行できますが、実際に有効なメモリに到達する可能性は非常に低くなります。

実際には、いいえ、それだけではできません。仮想メモリとメモリ保護を考えると、アクセスしようとしている領域がマップされていない可能性が高く、失敗する可能性があります。さらに、保護されたメモリ (OS に属するものなど) にアクセスすると、アクセスが失敗します。これらのシナリオはどちらも、セグメンテーション違反の原因です。

あなたのステートメントは有効であり(有効な定義が異なるため)、プログラムは要求されたメモリにアクセスしようとします。実際には何にもマップされていない可能性があるというだけです。

これがメモリ マップド I/O の仕組みであることにも注意してください。書き込むと、接続された UART/シリアル ラインに 1 バイトを書き込むハードウェア制御レジスタがあるとします (簡単にするために、これは魔法のように機能し、他のレジスタを設定する必要はありません)。C では、これは私の過度に単純化されたデバイスに対して次のように記述されます。

#define UART1_OUT 0xFC56   

volatile char* uart = UART1_OUT;   // Definition of pointer to variable.
                                   // volatile is required here. Look it up, but
                                   // it basically stops your compiler optimising
                                   // anything to do with this variable

*uart = 'A';                       // Write an A character to the serial line

もちろん、実際のデバイスはもう少し複雑です ;)。

于 2012-10-09T17:45:33.143 に答える
2

これは、プログラムが実行されているコンピューター アーキテクチャとオペレーティング システムによって異なります。最新のオペレーティング システムには、保護され仮想メモリの概念があります。仮想メモリでは、メモリ アドレスは物理メモリではなく、現在のアプリケーションに割り当てられた仮想メモリ空​​間を参照します。このような場合、割り当てられたメモリ空間外でメモリの読み取りまたは書き込みを試みると、プログラム フォールト (通常はセグメンテーション フォールトまたは保護フォールト) が発生します。

于 2012-10-09T17:43:02.350 に答える
1

C の変数に手動でメモリ アドレスを割り当て、その値をエコーアウトしようとした場合...メモリ内の何かを表示するための無制限のアクセス権がありますか、それとも制限がありますか?

C 言語では喜んでそれを試すことができますが、ほとんどのオペレーティング システムでは、プロセスのメモリ空間外のメモリにアクセスすることはできません。コードとハードウェアの間にあまりない組み込みシステム用のコードを書いている場合は、おそらく好きな場所から読み書きできるでしょう。ただし、保護されたメモリを備えたシステムのコードを書いている場合は、それほど多くはありません。

そのアドレスにあるものがchar型のサイズに合わない場合、それはひどくクラッシュすると思います

いや...コンパイラは、特定のアドレスに格納されているデータのタイプを気にしません。あなたがそれを言っていると言うとき(char *)0x28ff44、それ0x28ff44は でありchar *、それはコンパイラにとって十分です。0x28ff44ただし、有効なアドレスではない場合など、他の理由でコードがクラッシュする可能性があります。

于 2012-10-09T17:47:50.477 に答える
1

メモリ管理ユニット (MMU) を備えたシステムでは、任意のメモリにアクセスできない可能性が非常に高くなります。最新の OS はすべてメモリ保護を使用します。しかし、組み込みセクターでは、メモリ保護を採用していない OS が多く、アドレス指定可能な任意のメモリにアクセスすることが実際に可能です。

于 2012-10-09T17:45:13.270 に答える