2

低レベルのプログラミングでは、特定のメモリ位置で、これが私のアドレスであると言う必要がある場合があります。この投稿では、例としてPIR1PIC16F886 および関連するマイクロコントローラーのレジスターを取り上げます。常にアドレス 0x000C にあります。

私はこのアプローチを取りました:

#define pir1 (*(uint8_t*)0xc)

これで、変数に次のようなものを割り当てることができますpir1 |= 0x40(わかりました、マジック ナンバーの代わりに #defined 定数を使用しますが、あなたは私のドリフトを取得します)。これは GCC で問題なくコンパイルされ、使用しても警告は表示されません-Wextra -Wall。私の仮定を確認するために、GCC は次の x86_64 を吐き出します。

movl    $12, %eax
movb    $64, (%rax)

まさに私が望んでいたものです(わかりました、なぜそれが時々あるのかがわかりました。それはおそらくさらに別の愚かなx86の癖ですが、とにかくPIC14コードが欲しいので無関係ですeaxrax

さて、PIC14 をターゲットにするために、実際に SDCC コンパイラを使用しています。私はこのようにそれを呼び出しています

sdcc --std-c99 -mpic14 -p16f886 --use-non-free source.c

で始まる上記のコードで#defineは、次の警告が表示されます。

source.c:412: warning 88: cast of LITERAL value to 'generic' pointer
from type 'const-int literal'
to type 'unsigned-char generic* fixed'     

私は代わりにこれをやってみました:

__code __at (0xc) uint8_t PIR1;

しかし、それはエラーメッセージになります

error 33: Attempt to assign value to a constant variable (=)

課題を出そうとしたとき。

だから私の質問は、Cでこれを行う慣用的な方法が欠けているかどうかです? SDCC が警告しているのはなぜですか? ここで無視している特定の SDCC 固有のファンクはありますか?

4

2 に答える 2