符号拡張
符号拡張(ふごうかくちょう、Sign extension)とは、符号付の数値を表現するビット列が格納領域のビット幅より短い場合に、隙間を適切に埋めることによって数値としての同一性を維持する手法である。
例えば、8ビットの (-10)10 という値は2の補数表現では以下のようになる。
11110110
これを16ビットに符号拡張すると以下のようになる。
11111111 11110110
符号拡張しないで16ビットの領域に格納した場合、以下のようになる
00000000 11110110
これを整数として解釈すると (246)10 となってしまい、数値としての同一性が維持されない。
符号拡張にはしばしばマイクロプロセッサやコンパイラのバグが隠れていることがある。
ビットシフトでの符号拡張
算術ビットシフトで右シフトを行う場合、MSBが空く。 これを符号拡張で埋める。
ロード命令での符号拡張
たとえば、32ビットのCPUで、レジスタの長さはたいていの場合32ビットである。 メモリから32ビットより小さい幅のデータをロードする場合、レジスタの内容の一部だけがロードしたデータに置き換わる。 このデータが符号付整数であった場合、その後の演算をするには符号拡張を行う必要がある。 このため、一般的なマイクロプロセッサでは、符号拡張付きのロード命令と符号拡張のないロード命令を用意している。 そして、符号拡張のないロード命令ではレジスタ上の空いているビット列は全部 0 にすることが多い。
イミディエート値の符号拡張
マイクロプロセッサの命令セットには、命令ワード内に直接書かれた値を算術演算などに使用する命令がある場合がある。 これをイミディエート値または即値というが、この数値はレジスタのビット幅より小さいことが多い。 イミディエート値とレジスタの内容を符号付整数として解釈して加算などを行う場合、プロセッサは実行ユニット内部でイミディエート値を符号拡張する。 ただし、この場合も一般的に符号拡張する命令と符号拡張しない命令が存在することが多いので注意が必要である。
x86 での符号拡張
x86系のマイクロプロセッサでは、符号拡張は cbw, cwd, cwde, cdq という命令で行われる(例えば cbw は "convert byte to word")。
参考文献
- Mano, Morris M.; Kime, Charles R. (2004). Logic and Computer Design Fundamentals (3rd ed.), pp 453. Pearson Prentice Hall. ISBN 0-13-140539-X.