組み込みCを初めて使用しています。私のCは錆びていますが、コードを読むことはできますが、なぜ特定の行がそうであるのかを理解できていません。たとえば、変数がtrueであるかfalseであるかを知り、それを別のアプリケーションに送り返したいと思っています。変数を1または0に設定するのではなく、元の実装者は0xFFを選択しました。
彼はそれをアドレス空間に設定しようとしていますか?または、ブール変数を255に設定するのはなぜですか?
0xFF
は、すべてのビットをcharに設定します。
元の実装者はおそらく標準0
および1
は十分ではなく、すべてのビットoffがfalseの場合、すべてのビットonはtrueであると判断しました。
これは、Cでは0以外の値がtrueであるため機能します。これはchar内のすべてのバイトを設定しますが、変数に1ビットが設定されるとそれがtrueになるため、他の変数タイプでも機能します。
どうしてもメモリが必要な場合は、1つのバイトに8つのブール値(またはlongに32など)を格納することをお勧めします。
これは、フラグマスクを使用して簡単に行うことができます。
// FLAGMASK = ..1<<n for n in 0..7...
FLAGMASK = 0x10; // e.g. n=4
flags &= ~FLAGMASK; // clear bit
flags |= FLAGMASK; // set bit
flags ^= FLAGMASK; // flip bit
flags = (flags & ~FLAGMASK) | (booleanFunction() & FLAGMASK); // clear, then maybe set
これは、booleanFunction()が0(すべてのビットがクリア)または-1(すべてのビットがセット)を返す場合にのみ機能します。
0xFFは〜0の16進表記です(例:11111111)
たとえば、VBおよびAccessでは、-1がTrueとして使用されます。
彼らは何を知っているのですか?
元の埋め込み言語の1つ-PL/M(8051、-85、-86、-286、-386のように-51はい)-論理演算子(!、&&、|| C)とビット単位(〜、&、|、^)。代わりに、PL/MにはNOT、AND、ORおよびXORが両方のカテゴリを処理します。2つのカテゴリを使用する方がよいですか?わからない。Cの論理^^演算子(xor)がありませんが、それでも、論理カテゴリを使用しなくてもCでプログラムを作成できると思います。
PL/Mでは、Falseは0と定義されています。ブール値は通常、バイト変数で表されます。 TrueはNOT Falseとして定義され、0ffh(Cの0xffのPL/M-ese)を提供します。
ステータスフラグキャリーの変換がバイト変数(ブール値は型として使用できなかった)に格納される前にどのように行われたかを確認するために、PL/Mは格納前にアセンブリ命令「sbb al、al」を使用できます。キャリーが設定されている場合、alは0ffを含み、そうでない場合は0hを含みます。反対の値が必要な場合、PL/Mはsbbの前に「cmc」を挿入するか、または(実際にはxor-どちらか一方)の後に「not al」を追加します。
したがって、TRUEの0xffはPL/Mからの直接互換性ポートです。必要? (Cで)自分のスキルがわからず、非常に安全にプレイしない限り、おそらくそうではありません。
私のように。
PL/M-80(8080、8085およびZ80で使用)は整数または浮動小数点をサポートしていなかったので、PL/M-51でも同じであったと思います。 PL/M-86(8086、8088、80188および80186で使用)は、整数、単精度浮動小数点、セグメント:オフセットポインター、および標準メモリモデル(小、中、コンパクト、大)を追加しました。そのような傾向がある人のために、日曜大工のハイブリッドメモリモデルを作成するための特別な指示がありました。 Microsoftの大容量メモリモデルは、Intelの大容量メモリモデルと同等でした。 MSはまた、小型、小型、コンパクト、中型、大型のモデルを採用しました。
多くの場合、組み込みシステムでは、すべてのコードを書く1人のプログラマーがいて、彼/彼女の特異性はソース全体にあります。多くの組み込みプログラマはハードウェアエンジニアであり、システムをできる限り稼働させる必要がありました。 「移植性」の要件や概念はありませんでした。組み込みシステムにおけるもう1つの考慮事項は、コンパイラーがCPU HWに固有であることです。このCPUのISAを参照し、「ブール値」のすべての使用を確認してください。
この質問について知っておくべき本当に重要なことは、「var」のタイプです。あなたは「ブール値」と言いますが、それはC++/C99のブール値ですか、それとも(組み込みCアプリである可能性が高い)ブール値として使用されている完全に異なるタイプの何かですか?
他の人が言ったように、それはすべてのビットを1に設定します。これはCに埋め込まれているため、これをレジスターに格納して、各ビットが何かにとって重要であるため、それらをすべて1に設定する必要があります。アセンブラで書く場合も同様です。
また、0xffに1を追加すると、0に設定され(unsigned charを想定)、チェックはループして、インクリメントしてブレークする可能性があります。
考えられる理由は次のとおりです。0xff
は0
のバイナリ補数です。組み込みアーキテクチャでは、0xff
を変数に格納する方が、たとえば1
を格納するよりも効率的で、追加の命令や定数をメモリに格納する必要がある場合があります。
または、アーキテクチャ内のレジスタの「真の値」をチェックする最も効率的な方法は、「チェックビットセット」命令を使用することです。 TRUE値として0xff
を使用すると、問題ありませんwhichビットがチェックされます...すべて設定されています。
もちろん、上記は単なる推測であり、使用している組み込みプロセッサの種類はわかりません。 8ビット、16ビット、32ビット? PIC、AVR、ARM、x86 ???
(他の人が指摘したように、ゼロ以外の整数値はCのブール式の目的ではTRUEと見なされます。)