4

周辺機器のメモリマップレジスタへのアクセスについて読んでいますが、複数の方法ができるようです。例えば:

方法 1:

#define MyReg 0x30610000

volatile int *ptrMyReg;
ptrMyReg = (volatile int *) MyReg;
*ptrMyReg = 0x7FFFFFFF; /* Turn  ON all bits */

方法 2:

#define MyReg 0x30610000

volatile unsigned char *ptrMyReg;
ptrMyReg = (volatile unsigned char *) MyReg;
*ptrMyReg = 0x7FFFFFFF; /* Turn  ON all bits */

質問: ある人が他の人よりも 1 つを選択する特定の理由はありますか?

想定: アーキテクチャ上の int のサイズは 4 バイトです。

4

4 に答える 4

5

*ptrMyReg = 0x7FFFFFFF;

2 番目のケースでは、 *ptrMyRegis 型unsigned charso0x7FFFFFFFに変換されunsigned charます (つまり、変換後の値は になります0xFF) 代入の前に、1 バイトだけが書き込まれます。もともと4バイトを書き込むつもりだった場合、これはあなたが望むものではないと思います。

于 2013-04-21T17:20:29.830 に答える
2

タイプキャストが一致しないため、2 番目の例は有効なコードではありません。それを次のように修正すると:

ptrMyReg = (volatile unsigned char *)MyReg;

それから、はい、彼らは違います。2 番目のケースでは、その定数は切り捨てられ、エンディアンに応じて0xFF、単語の最上位バイトまたは最下位バイトのいずれかにのみ書き込みます。0x30610000とにかく、0x30610000書き込まれるのは の 1 バイトであり、他のバイトではありません。

于 2013-04-21T17:14:22.367 に答える
1

CPU アーキテクチャでは、ペリフェラル レジスタへのすべてのアクセスが、たとえば 32 ビット幅である必要がある場合があります。その場合、バイトアクセスを行うと、CPU 例外またはサイレントエラー実行が発生する可能性があります。これは、多くの ARM SoC に当てはまります。

于 2013-04-21T19:50:22.663 に答える
0

int方法 2 では、ポインターを逆参照して全体にアクセスすることはありませんchar(もちろん、sizeof(int)プラットフォームで =1 でない限り)。

それ以外は、ハードウェアを確認する必要があります。異なるサイズのメモリオペランドを使用してアクセスすると、動作が異なる場合があります。

于 2013-04-22T06:49:10.507 に答える