C言語関係掲示板

過去ログ

No.931 0x00100番地に値を代入したい

[戻る] [ホームページ]
No.11838

アドレスに関して
投稿者---み〜(2004/01/16 11:39:57)


アドレスに関して分からない点があります。
アドレス0x00100番地(例)に何の値が入っているか参照するのは
特に難しくありませんが、その逆で、0x00100番地に値を代入
したい場合はどのようにすれば良いのでしょうか?
よろしくお願いします。

No.11839

Re:アドレスに関して
投稿者---NykR(2004/01/16 12:00:40)


>アドレス0x00100番地(例)に何の値が入っているか参照するのは
>特に難しくありませんが、その逆で、0x00100番地に値を代入
>したい場合はどのようにすれば良いのでしょうか?

間接参照演算子 * は左辺値を作るので、オペランドが指す領域が読みとり専用になっていない場合はその内容を(見るだけでなく)変更することができます。

生の数字を使うなら(普通はやらない)こんな感じ。

*(int*)0x00100 = 3;

普通にやるなら

int i = 0;
int *p = &i; /* まずどこを指すか指定する */

*p = 3; /* 指している領域を変更する */

No.11840

Re:アドレスに関して
投稿者---み〜(2004/01/16 13:17:01)


>>アドレス0x00100番地(例)に何の値が入っているか参照するのは
>>特に難しくありませんが、その逆で、0x00100番地に値を代入
>>したい場合はどのようにすれば良いのでしょうか?
>
>間接参照演算子 * は左辺値を作るので、オペランドが指す領域が読みとり専用になっていない場合はその内容を(見るだけでなく)変更することができます。
>
>生の数字を使うなら(普通はやらない)こんな感じ。
>
>*(int*)0x00100 = 3;

↑このように書くとコンパイルは出来るのですが、
実際、実行してみるとうまくいきません。

>普通にやるなら
>
>int i = 0;
>int *p = &i; /* まずどこを指すか指定する */
>
>*p = 3; /* 指している領域を変更する */

↑この方法の場合、どのようにすればアドレス0x000100番地と指定
出来るのでしょうか?

よろしくお願いします。

No.11842

Re:アドレスに関して
投稿者---NykR(2004/01/16 13:41:17)


>>間接参照演算子 * は左辺値を作るので、オペランドが指す領域が読みとり専用になっていない場合はその内容を(見るだけでなく)変更することができます。

>>生の数字を使うなら(普通はやらない)こんな感じ。
>>
>>*(int*)0x00100 = 3;
>
>↑このように書くとコンパイルは出来るのですが、
>実際、実行してみるとうまくいきません。

打ち間違い、
普通はやらない--->やってはいけない。

単項*演算子のオペランドになることが出来るのは、オブジェクト型または関数型を指すポインタだけです。

#オブジェクト型というのは、サイズを知ることができる型のこと。
#char型なら1バイトとか、

また、関数は普通書き込み禁止領域に置かれるので、
こちらは変更もできません。

というわけでこのコードは、まず動きません。
((int*)0x00100が何を指すポインタかわからないから)

>どのようにすればアドレス0x000100番地と指定
>出来るのでしょうか?

というようなことも、やろうとしてはいけません。

No.11843

Re:アドレスに関して
投稿者---NykR(2004/01/16 13:50:24)


>((int*)0x00100が何を指すポインタかわからないから)

て、intを指してますね、えーと、つまり、(int*)0x00100が指す領域に、オブジェクトまたは関数があるという保証がないから、*を作用させることが出来ないわけです。

No.11844

Re:アドレスに関して
投稿者---NykR(2004/01/16 13:58:46)


>オブジェクトまたは関数があるという保証

int型のオブジェクトがあるという保証

#あるいはint型を第一メンバとする構造体型のオブジェクト
#とかintの配列でもよかった***かもしれない***

No.11847

Re:アドレスに関して
投稿者---み〜(2004/01/16 14:36:43)


指定したアドレスに値を直接代入するような事はしては
いけないという事ですね。
指定したアドレスに何か変数が入っていた場合、その
変数の変更というのは可能なのでしょうか?

(例)
0x000100 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

となっていた場合に
0A⇒32
に変更!という事は可能ですか?

お願いします。

No.11851

Re:アドレスに関して
投稿者---pi-ta(2004/01/16 15:06:38)


こんにちは、pi-taです。
まず、動作環境をはっきりさせてはいかがですか?

>指定したアドレスに値を直接代入するような事はしては
>いけないという事ですね。
これは組み込み系などでは全く問題ありません。
実際に *(int *)0x00100 = 3 みたいなこともやっていますし。

ただ、WindowsやUNIXで動作するプログラムで上記のようなことは
できません。
ですので、どのような環境で使用し、なぜアドレス直接指定
での値の代入が必要なのか。
このあたりをはっきりさせると、レスしやすいと思いますよ。


>(例)
>0x000100 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
>
>となっていた場合に
>0A⇒32
>に変更!という事は可能ですか?

組み込み系などで、0x00100番地付近がRAMや入出力ポートである場合
*(unsigned char *)0x00109 = 0x32;

unsigned char *p = 0x00100;
p[9] = 0x32;
などとすることはできます。

No.11853

Re:アドレスに関して
投稿者---volatile(2004/01/16 15:16:40)


>指定したアドレスに値を直接代入するような事はしては
>いけないという事ですね。

「やってはいけない。」と言ってる人もいますが、
OSもサービスプログラムもユーザーのフロントエンドとなるアプリケーションプログラムも
ひとつの同じ言語で記述できるのが C の利点です。
小規模なシステムでハードウェアに直接アクセスするプログラムの場合は
アドレスを数値で指定することも当たり前に行われます。
「やってはいけない。」は条件付きですので、
Cの言語理解の為ならやってみて構いません。

>指定したアドレスに何か変数が入っていた場合、その
>変数の変更というのは可能なのでしょうか?
>
>(例)
>0x000100 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
>
>となっていた場合に
>0A⇒32
>に変更!という事は可能ですか?

ご質問の内容は、
char array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
if(&array[0] == 0x000100){
    *(array + 9) = 0x32;
}

とゆうようなことかと思いますが、どうでしょう。


No.11861

Re:アドレスに関して
投稿者---み〜(2004/01/16 16:58:50)


NykRさん、pi-taさん、volatileさん、色々とアドバイスなど
ありがとうございました。参考にして、もう一度考えて分からない
場合は、また質問させて頂きます。その時はお願いします。