初めて組み込み C を使用しています。私のCは錆びていますが、コードを読むことはできますが、特定の行がなぜそうなのかについてはよくわかりません。たとえば、変数が true か false かを知り、それを別のアプリケーションに送り返したいとします。変数を 1 または 0 に設定するのではなく、元の実装者は 0xFF を選択しました。
彼はそれをアドレス空間に設定しようとしていますか? または、なぜブール変数を 255 に設定するのでしょうか?
0xFF
すべてのビットを char に設定します。
元の実装者はおそらく、標準が不十分であると判断し、すべてのビット0
オフがfalseの場合、すべてのビットオンがtrueであると判断しました。1
これは、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 (すべてのビットがセット) を返す場合にのみ機能します。
この若者たちは何を知っているのですか?
元の組み込み言語の 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」を使用できます。キャリーが設定されている場合は 0ff が含まれ、設定されていない場合は 0h が含まれます。反対の値が必要な場合、PL/M は sbb の前に「cmc」を挿入するか、後に「not al」を追加します (実際には xor - どちらか一方)。
したがって、TRUE の 0xff は PL/M からの直接互換ポートです。必要?自分のスキル (C) に確信が持てず、非常に安全にプレイしない限り、おそらくそうではありません。
私が持っていたように。
PL/M-80 (8080、8085、Z80 で使用) は整数または浮動小数点数をサポートしていませんでした。PL/M-51 でも同じだったと思います。PL/M-86 (8086、8088、80188、および 80186 で使用) では、整数、単精度浮動小数点、セグメント:オフセット ポインター、および標準メモリ モデル (小、中、コンパクト、および大) が追加されました。そのような傾向がある人のために、日曜大工のハイブリッド メモリ モデルを作成するための特別な指示がありました。Microsoft のヒュージ メモリ モデルは、Intel のラージ メモリと同等でした。MS はまた、極小、小、コンパクト、中、大のモデルを備えていました。
0xFF は ~0 の 16 進数表現です (つまり、11111111)
たとえば、VB や Access では、-1 が True として使用されます。
多くの場合、組み込みシステムでは 1 人のプログラマーがすべてのコードを記述し、その特異性がソース全体に現れます。多くの組み込みプログラマーは HW エンジニアであり、システムをできる限り稼働させなければなりませんでした。「携帯性」の要件も概念もありませんでした。組み込みシステムにおけるもう 1 つの考慮事項は、コンパイラが CPU HW に固有であることです。この CPU の ISA を参照し、「ブール値」のすべての使用を確認してください。
他の人が言ったように、すべてのビットを 1 に設定しています。これは C に組み込まれているため、これをレジスタに格納し、各ビットが何かにとって重要な場合は、すべてのビットを 1 に設定する必要があります。アセンブラで書く場合も同様です。
この質問について知っておくべき本当に重要なことは、「var」のタイプです。あなたは「ブール値」と言っていますが、それは C++/C99 のブール値ですか、それとも (組み込み C アプリである可能性が高い)、ブール値として使用されているまったく異なる型のものですか?
また、0xff に 1 を追加すると、それが 0 に設定され (unsigned char を想定)、チェックがインクリメントを伴うループで中断された可能性があります。
考えられる理由は次のとおりです。0xff
は の 2 進補数です0
。組み込みアーキテクチャでは、たとえば、追加の命令やメモリに格納された定数が必要になる可能性がある0xff
格納よりも、変数への格納の方が効率的である可能性があります。1
または、アーキテクチャ内のレジスタの「真の値」をチェックする最も効率的な方法は、「チェック ビット セット」命令を使用することです。TRUE 値として、どの0xff
ビットがチェックされるかは問題ではありません...それらはすべて設定されています。
もちろん、上記は憶測にすぎません。使用している組み込みプロセッサの種類はわかりません。8ビット、16ビット、32ビット? PIC、AVR、ARM、x86???
(他の人が指摘したように、ゼロ以外の整数値は、C のブール式の目的で TRUE と見なされます。)