私は8ビットのレジスタを持っています。他のビットを変更せずにビット4,5,6を変更したいと思います。 これらのビットは、000
から111
までの値を取ることができます(以前の状態に関係なく)。 ワンステップで変更する方法はありますか、それとも個別に変更する必要がありますか?レジスタ内の複数のビットを変更する
答えて
あなたは0である、既知の状態で要求されたビットを置くためにマスクを必要とします私たちは、変更することが0にビットを設定する反転マスクを使用
#define mask 0x70 // 01110000b bit 4, 5 & 6 set
reg = (reg & ~mask) | (newVal & mask);
をし、そのままマスクに:私のプログラミングの習慣ごとなど、より便利に、そしてあなたがまたは操作を1にしたいとライトバックビットを設定私たちがしたくないビットを0に設定する新しい価値を妨げる
新しい価値の不要なビットは常にあなたが簡素化することができます0であることを確認している場合:
#define mask 0x8f // 10001111b bit 4, 5 & 6 reset
reg = (reg & mask) | newVal; //newVal must have always bits 7, 3, 2, 1 & 0 reset.
あなたは、ビットごとの操作によってそれを行うすなわち最初の3ビットをクリアし、それらを設定することができます。
unsigned char value = 0x70;
unsigned char r = 0xFF;
r = (r & 0x8F) | value;
ビット単位または '|'を意味すると思いますか? – Unimportant
ああ、確かに、はい、固定、ありがとう@ user1320881 – fluter
あなたは、構造体の内側bit-fieldを使用することができます。
typedef struct{
unsigned char b0_3 : 4;
unsigned char b4_6 : 3;
unsigned char b7 : 1;
}your_reg_type;
your_reg_type my_register;
//modify only the bits you need
my_register.b4_6 = 0x02;
は、あなたのコンパイラが注文する方法をご覧ください構造体内のビットを試してみてください。order your bit-field accordingly
この回答はCで保証されていないので、最初のビットはビット7です。ビット0でもかまいません。 – user3629249
だから私は "ターゲットのエンドエンティティをチェックアウトしました..." – simpego81
1バイトの場合、それはエンディアンの問題ではなく、むしろコンパイラの実装です。実際にはマルチバイトの場合でもエンディアンの問題ではありません。エンディアンはバイトオーダーではなくバイトオーダーに関するものです。コンパイラは、バイト順序にかかわらずMSBまたはLSBからビットをパックすることがあります。ですから、ターゲットのエンディアンではなくコンパイラのドキュメントをチェックしてください。これは、同じターゲットの異なるコンパイラ間で変更される可能性があることに注意してください。 – Clifford
3つの連続したビットの値が意味を持つ場合(つまり、すでに提案されています) 。例えば、独立したフラグまたは制御ビットの集合ではなく、0から7の値である)、値内のビット位置の詳細を直接符号化するのではなく、単純な数値範囲0〜7としてその値を保持すると便利です。その場合には:もちろん
assert(val <= 7) ; // During debug (when NDEBUG not defined) the
// assert trap will catch out-of-range inputs
reg = (reg & mask) | (val << 4) ;
あり(シフト動作を追加することによって)このようにインターフェイスを簡略化するために支払うためにいくつかの小さなコストであるが、利点は、レジスタ・フィールドレイアウトの詳細についての知識があることです1か所に制限されています。
- 1. レジスタ内の値でビットをシフトする
- 2. レジスタの奇数ビットをミラーリングする
- 3. mxcsrレジスタのビットを反転する
- 4. データセット内の複数の変数を変更する
- 5. ビット・イン・ポート・レジスタへのポインタ
- 6. avx2レジスタのビット反転
- 7. SIMDレジスタの64ビットから32ビット整数を解釈する問題
- 8. レジスタのビット数を0に設定する
- 9. x86 - レジスタの数と予約済みビットの数
- 10. レジスタ変数
- 11. queryList内の複数のアイテムのAngular2レジスタのobservableイベントハンドラ
- 12. レジスタ値の各ビットを介したアセンブリループ
- 13. 複数のフォルダ内の複数のファイルの名前を変更する
- 14. ループ内の複数のプロットの色を変更する
- 15. UITableview内の複数のスイッチの値を変更する
- 16. ビット単位のデータを複数の列に変換する
- 17. 複数のテキストファイルの内容を変更する
- 18. アクティブディレクトリ内の複数のユーザパスワードを一度に変更する
- 19. R内の複数boxplotのウィスカー長を変更する
- 20. Excelで範囲内の複数の式を変更する
- 21. 文字列内の複数の文字を変更する
- 22. サブディレクトリ内の複数のファイル名を変更する
- 23. x86の余分なレジスタ64ビット
- 24. アセンブリローカル変数とレジスタ
- 25. フラッシュ内のビット数
- 26. 複数のビットのパターンをスキャンするビット配列
- 27. 複数行ファイルの内容をリストに変更する
- 28. 配列のビットを変更する
- 29. CPUレジスタに変数を格納する
- 30. XMM 128ビットレジスタを2つの64ビット整数レジスタに分割する方法は?
既知の状態では '0'が' 1'よりどのように便利であるかわかりません。次のステップで、あなたが望むビットを( '|'演算で)オンにするか、オフにするビットをオフにするか( '&'演算で)のどちらかの問題です。 –
@ JohnBollinger、私はあなたが言ったように、必要なビットをセットするために値の間に値が必要なので、より便利であると考えます。それらをリセットするには、レジスタ値を反転させる必要があります。入力値。 2つの操作が必要です。 –
いいえ、代替案はあなたの例とまったく同じくらい複雑で、入力を反転する必要はありません: 'reg =(reg | mask)&(newVal |〜mask)'。 –