ByteScope

Bitwise Calculator

AND、OR、XOR、シフト、クリックできるビット格子 — さらに目の前のレジスタをそのまま分解するビットフィールド表示。

ファイルはブラウザから送信されません — 処理はすべてローカルで行われます。

符号なし

0

符号付き

0

ビットグリッド

ビットをクリックすると反転し、下の表記すべてに反映されます。

MSBLSB

演算

ビット演算

シフト・ローテート

A

0x00

A は常に上の値です。

結果

2 進

0b0000_0000

16 進

0x00

10 進

0

MSBLSB

レジスタのビットフィールド表示

レイアウトを一度書いておけば、上の値が変わるたびに自動でデコードします。

name:width をカンマ区切りで、上位フィールドから順に。幅の合計は選択中のビット幅以内に収めます。

保存したレイアウト

保存先はこのブラウザ内(localStorage)だけです。サイトデータを消すかブラウザを変えると失われます。

保存したレイアウトはまだありません。

このツールについて

datasheet を開いていて、レジスタの値は 0x3F80。知りたいのは各フィールドが何を言っているか、それだけです。値を貼って、レイアウトを一度書くだけ — reserved:1, mode:3, prescaler:4, enable:1, status:7 — 各フィールドのビット範囲、生の2進、10進と16進の値が並びます。レイアウトはブラウザに保存されるので、リファレンスマニュアルの412ページを読みながら打ち込んだ定義は来週もそこにあります。同じ値が次にログに出てきたときは、紙の上でニブルを数える代わりに2秒で読めます。

signed と unsigned の読みは、切り替えボタンの裏ではなく隣同士に置いてあります。0xFF は 255 でもあり −1 でもある。どちらが本当かは、その値を作ったコードが変数をどう宣言したかだけで決まり、ここを取り違えるのは立派なバグの一類型です — −1 °C を 255 と報告するセンサー、とんでもない件数に見えるステータスフィールド。両方の列が同時に見えていれば、それは「やってしまうミス」ではなく「答えられる問い」になります。unsigned が 65,535、signed が −1 なら、もう何を見ているかは分かります。

幅は飾りではありません。1 << 40 は 32-bit なら 0、64-bit なら 1,099,511,627,776。NOT 0x0F は1バイトなら 0xF0、1ワードなら 0xFFFFFFF0。負の値の右シフトも、何ビットの世界にいるかで答えが変わります。JavaScript の <<>>& は計算を始める前にオペランドを 32-bit へ切り落とすので、ウェブの計算機が 64-bit の答えを黙って間違えるのはこれが原因です — 1 << 31 が負になり、2^32 を超えるものは 0 に潰れる。このページは BigInt で計算してから選んだ幅でマスクするため、64-bit の結果は厳密で、8-bit は uint8_t と同じようにきちんと折り返します。

画面の 0b0011_1111_1000_0000 を目で追って bit 7 が立っているか判断する、これは深夜2時の人間がいちばん間違える種類の数え方です。だからクリックできるビット格子があります。どのビットにも番号が振ってあり、クリックすれば反転し、2進・10進・16進、signed と unsigned の読み、ビットフィールドの分解までが一緒に更新されます。処理はすべてブラウザ内、裏にAPIのない静的ページです。これはここでは実質的な話で、未発表ハードウェアのレジスタ値は普通に機密ですし、ペリフェラルを解析しながら付けたフィールド名は、数字と同じくらいそのチップのことを喋ってしまいます。

よくある質問

>>>>> は何が違うのですか?

>> は算術シフトです。上に空いたビットへ符号ビットをコピーして符号を保つので、-8 >> 1-4、負の数は負のままです。>>> は論理シフトで必ず0を詰めるため、同じビットパターンが下にずれて大きな正の数として読めます。正の値では両者は同じ結果になるので、差が出るのは最上位ビットが立ってからです。C には >> が1つしかなく型が挙動を決めます — signed なら算術、unsigned なら論理 — なのでこのページは幅と符号の有無を暗黙にせず、はっきり表に出しています。

なぜ JavaScript では 1 << 31 が負になるのに、ここでは違うのですか?

JavaScript のビット演算子は、オペランドをまず 32-bit の符号付き整数に変換するからです。1 << 31 は 32-bit signed の最上位ビット、つまり符号ビットを立てるので −2147483648 と表示され、もう一つ進めた 1 << 32 はまた 1 に戻ります(シフト量が 32 で割った余りになるため)。この計算機は BigInt で計算してから選んだ幅を当てるので、32-bit では unsigned 列が 2,147,483,648、その隣に −2,147,483,648 が並び、64-bit の 1 << 40 は 0 ではなく本当の 1,099,511,627,776 になります。

フィールドのレイアウトはどう書きますか?

1フィールドにつき name:width を1つ、カンマ区切りで並べます。status:4, error:1, reserved:3 なら 8-bit のレジスタです。並び順は datasheet の図と同じく最上位ビットから下へ、幅の合計は選んだレジスタ幅とぴったり一致させます — 足りなければ、超えていれば、その場で教えます。どうでもいい隙間は reserved: で埋めてください。残しておくことが、その下のフィールドのビット位置を正しく保つコツです。保存したレイアウトにはそれぞれ名前が付くので、同じチップの CTRL1STATUSFIFO_CFG を並べて持てます。

signed か unsigned を選ばせずに、両方出すのはなぜですか?

値を貼った時点では、まだ分かっていないことが多いからです。シリアルのダンプから出てきた1バイトは、ただの8ビットです。0xFE が 254 なのか −2 なのかは、それを書いたコードの性質で、ビット自体の性質ではありません。先に選ばせると一定の確率で外し、しかもどちらの読みも単体ではもっともらしいので気づけません。並べて出せば 0xFE は 254 と −2、物理量に合う方はすぐ分かります — バイト数は負になりませんが、温度はなります。

ビット幅を変えると何が変わるのですか?

すべての結果に掛けるマスク、つまり符号ビットの位置が変わります。8-bit なら 0x1FF0xFF に切られ、NOT 00xFF、signed の読みは 0x80 から上が負になります。64-bit なら同じ演算が 64 ビットぶん保たれ、符号ビットは bit 63 です。シフトも変わります。幅の上から押し出されたビットは覚えておかれず捨てられる — uint16_t のレジスタがまさにやることです。幅を切り替えると、2進・16進・ビット格子・ビットフィールドの分解まで、すべてのパネルが新しいサイズで再計算されます。

入力した値や保存したレイアウトはどこかへ送られますか?

送られません。ページは静的ファイルで、計算はすべてブラウザ内、保存したフィールドレイアウトはブラウザの localStorage にあります。マシンの外へは出ませんし、ログインするアカウントもありません。裏返しの制約として、ブラウザごと・プロファイルごとに別物です。サイトデータを消せば消えますし、ノートPCで作ったレイアウトはデスクトップには現れません。datasheet から打ち直したくないレイアウトは、控えを取っておいてください。