低レベルのプログラミングでは、特定のメモリ位置で、これが私のアドレスであると言う必要がある場合があります。この投稿では、例としてPIR1
PIC16F886 および関連するマイクロコントローラーのレジスターを取り上げます。常にアドレス 0x000C にあります。
私はこのアプローチを取りました:
#define pir1 (*(uint8_t*)0xc)
これで、変数に次のようなものを割り当てることができますpir1 |= 0x40
(わかりました、マジック ナンバーの代わりに #defined 定数を使用しますが、あなたは私のドリフトを取得します)。これは GCC で問題なくコンパイルされ、使用しても警告は表示されません-Wextra -Wall
。私の仮定を確認するために、GCC は次の x86_64 を吐き出します。
movl $12, %eax
movb $64, (%rax)
まさに私が望んでいたものです(わかりました、なぜそれが時々あるのかがわかりました。それはおそらくさらに別の愚かなx86の癖ですが、とにかくPIC14コードが欲しいので無関係ですeax
)rax
さて、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 固有のファンクはありますか?