ビットシフトにはまる

アバター
いわん
記事: 32
登録日時: 9年前

ビットシフトにはまる

投稿記事 by いわん » 7年前

つまるところちゃんとカッコを使いましょうということなのですが、
まさかローテートになっていようとは・・・・
コンパイラや処理系によっても結果は違ってくるのかな。
こんなのではまってしまいました。修業が足りない。

CODE:

unsigned char Year[2];
Year[0] = 0x20;
Year[1] = 0x18;
printf("year=%x\n", Year[0]<<8 + Year[1]);
実行結果

CODE:

year=20

アバター
みけCAT
記事: 6734
登録日時: 14年前

Re: ビットシフトにはまる

投稿記事 by みけCAT » 7年前

C言語では、(拡張後の)左辺の幅以上のシフトは未定義動作です。
N1570 6.5.7 Bitwise shift operatorsの3 さんが書きました: The integer promotions are performed on each of the operands. The type of the result is
that of the promoted left operand. If the value of the right operand is negative or is
greater than or equal to the width of the promoted left operand, the behavior is undefined.
(http://chimera.roma1.infn.it/SP/COMMON/ ... 9-1990.pdf)

C++でも同様です。
N3337 5.8 Shift operatorsの1 さんが書きました: The operands shall be of integral or unscoped enumeration type and integral promotions are performed.
The type of the result is that of the promoted left operand. The behavior is undefined if the right operand
is negative, or greater than or equal to the length in bits of the promoted left operand.
(http://www.open-std.org/jtc1/sc22/wg21/ ... /n3337.pdf)

【追記】
CPUの実装で、シフト幅を31ビット(レジスタサイズ-1)までにマスクするものがあるようです。

Tips IA32(x86)命令一覧 Sから始まる命令 SAL/SAR/SHL/SHR命令
IA-32アーキテクチャにおける互換性
8086は、シフトカウントをマスクしません。しかし、(インテル® 286プロセッサ以降の)その他のすべての

IA-32プロセッサは、シフトカウントを5ビットにマスクするので、最大カウントは31になります。このマスク設定は

(仮想8086モードを含め)全ての動作モードで行われ、命令の最大実行時間を減らしています
x86系で32bit以上のシフトをするときの問題 - 間違いだらけの備忘録
386になってから、多ビットシフトのハードウェアが導入されて、

ようやくシフトが"軽い"命令になったわけ。

で、たしか、386からだと思うけど、clレジスタに32以上の数値を指定しても、

下位ビットだけがマスクされて、実際には31ビット以下のシフトしか

行われないようになったわけ。
最後に編集したユーザー みけCAT on 2018年2月02日(金) 07:26 [ 編集 2 回目 ]
理由: CPUの実装の話を追加

アバター
いわん
記事: 32
登録日時: 9年前

Re: ビットシフトにはまる

投稿記事 by いわん » 7年前

>みけさん
情報ありがとうございます。
未定義動作、いやな言葉です(;^_^A そういうのを見つけてくれる解析ツールあったかな。
他人が作ったソースをデバッグしてると時たまこういうのに遭遇して悩まされます。