間違いだらけの備忘録

このページの内容は無保証でありこのページの内容によって直接、または間接に損害を受けられたとしても私は責任を取りません。

x86系で32bit以上のシフトをするときの問題

上記がらみでY氏と話していたときに出たネタ

http://mirror.href.com/thestarman/asm/index.html

SAL - Shift Arithmetic Left
(中略)
The count is masked to 5 bits, which limits the count range to 0 to 31.

シフト命令のワイヤードロジック化による影響
http://nssearch.hp.infoseek.co.jp/clang/1032606064.html

x86形の話だけど、コンパイラはシフトをアセンブラレベルの
シフト命令(shr/sar)に展開するのね。
で、8086の頃は、シフト命令は1ビットだけシフトする命令か、
CLレジスタに数値を入れてシフトさせるしかなかったのね。
で、ハードウェア的には、本当に繰り返しで処理してたのね。
80186(かな?)以降は、直接nビットシフトする命令が出来たんだけど、
これもハードウェア的には(マイクロコードで)繰り返し処理してたのね。
で、386になってから、多ビットシフトのハードウェアが導入されて、
ようやくシフトが"軽い"命令になったわけ。

で、たしか、386からだと思うけど、clレジスタに32以上の数値を指定しても、
下位ビットだけがマスクされて、実際には31ビット以下のシフトしか
行われないようになったわけ。
だから、16bitコンパイラを使って、32bit以上のシフト命令を使ったプログラムを作ると、
むかーしのCPUと今のCPUで結果が異なるわけ。
この結果を、CPU種別の判別なんかに使ってたりしたんだな。

コンパイラは、CPUの判別なんかしない(実行環境は別だし、以降に生まれたCPUにも対応できない)から、
効率重視のC言語において結果が異なる(未定義になる)のは
ある意味仕方がないとも言えるんだろうね。

めも、未検証

このページにはhatena以外のサービスからのコンテンツが埋め込まれています。 hatenaによりGoogle AdSense 広告が埋め込まれています。