エンディアンについて (ワード編)

たけおか

初出: 2010/NOV/01



0. はじめに

エンディアンというのは、ワード(語)のばあいは、メモリ上で、ワードを構成 する各バイトが配置される順序、すなわちバイト・オーダ(バイト並び、 バイト順、byte order)についての呼び名である。
また、 bitの場合は、基本語の中のビットの番号が、 MSBか、LSBのどちらから ついているか、を示す呼び名である。

1. ワードのエンディアン

ワードのエンディアンとは、

である。
エンディアンを変更可能な機械は、バイ・エンディアン(Bi-Endian)という。

リトル・エンディアン
x86, VAX, 組込みARM, 組込みMips
ビッグ・エンディアン
680x0, Sparc, PowerPC
0x12345678という数値の、メモリ上での
各エンディアンのバイト並び

(PowerPC, MIPS, SH4, ARM は、バイ・エンディアンなので、 WindowsCE 系のハードウェアでは、リトル・エンディアンを採用している場合 がある)

1980年代前半は、8086は、しょぼくて、1MBytes までのメモリしか扱えないマイコン。
逆に、UNIXの動くワークステーションは、68000や68020やSparc, Mipsを 使用し、また、かっこいいMacintosh も、68000, 68020であった。

1986年頃、セコいマイコンは、リトル・エンディアンであり、かっこいい 680x0 は、ビッグ・エンディアンである。
当時、「ビッグ・エンディアンは自然であり、正しいのである」とまで言う人も居た。

2. ワードのエンディアン問題

エンディアン問題について、 宗教論争だという人がいるが、とんでもない。
すべてのメモリ操作が、ワードで閉じていればエンディアンの差は無いが、 機械の基本単位(ワード)を越えた長い数値(多倍長データ)を扱えば、 エンディアンの差がはっきり出る。

現在の、通常のハードウェアを相手にした場合、本質的な差がある。
また、有限な数値を扱う数学の面から考えても、リトルエンディアンの方が利 にかなっていると言えよう。

1) 実プログラム面から

四則演算を考えた場合、通常、下の桁から計算を行う。対象にするワードが、 計算機の扱う基本単位に収まっていれば、エンディアンの差は関係ない(こと が多い)。
が、基本単位を越えた、いわゆる「多倍長演算」を行うと、 下桁のワードから処理した方が効率が良い。
人間が筆算を行うとき、下の桁から行うのと、同じ原理である。


0x1234 + 0x5678の筆算

コンピュータでも、加算と減算においては、下の桁から計算を行うの が効率よい。
なぜなら、桁上がりの伴う計算を行う場合は、一般に、下の桁から計算した方 が、効率が良いからである。
乗算においても、部分積たちを正しく加算するには、下の桁から計算を行った方が よい。なぜなら、それは加算であるから。

除算については、上の桁からできる、という話があるのだが、 長いワードの除算は、結局、多倍長の減算を行う必要があり、 それも下の桁から減算を行うことになる。

さて、一番下の桁から順番に上の桁をアクセスするのに都合の良い、データ表現は、
・リトル・エンディアン(80x86 並び)

・ビッグ・エンディアン(68000 並び)
のどちらであろうか。

多倍長のデータは、通常、数値を表すデータを、メモリ上に連続に並べる。 それを指すポインタがある。
(可変長データの場合は、それに加えて、 データ長を表す情報が近所に置いてあるだろう)

さて、リトル・エンディアンは、ポインタが一番下の桁を指しており、 ビッグ・エンディアンは、ポインタが一番上の桁を指している。
リトル・エンディアンでの計算
ビッグ・エンディアンでの計算
各エンディアンにおける、計算の開始


四則演算(少なくとも、加算、減算、乗算の3則)では、リトル・エンディアンの 方が有利であることが明白であろう。
ビッグ・エンディアンの場合、最下位桁の位置を得るのに、 演算を行わねばならない。



2) やや抽象的に

さて、多倍長の話をしたので、データの数値がいくらでも大きくなるデータ、 または、大きくなる数値のことを考えよう。

どんなデータでも、なにかの基準点は固定的であるほうが、健全で合理的だ。
基準点が、データ毎に変化するということは、 動的に何かの操作を行わねばならず、しんどいに決まっている。

数値表現が、いくらでも大きくなる可能性があった場合、どこを基準にするの が、いいだろう?

普通の多くの人は、2^0 (2の零乗) つまり、「一の位」を基準にするのが、楽だ。
なにしろ、小学校の時から、一の位を基準にものを算数を習ってきている。
そして、一の位を押さえておいて、数値は、上に伸びればいいのだ。
どうせ、加算も減算も、一の位から計算を始めるのだ。

ということで、一の位を押さえるのが、いわゆる「自然」であり、 数値表現を、上の桁方向に、自由に、伸ばし易くもある、 ということに、異論のある人は少ないだろう。
(異論のある人が皆無だとは思わないが)


各エンディアンが、基準としてどこを押さえているか

ということで、一の位を、ポインタが指しているリトル・エンディアンは、 かなり融通の利く、手間のかからない表現であると言えるだろう。

3. おまけ 1

インターネット・プロトコルのソフトウェア処理は、一般に、 ビッグ・エンディアンの方が有利(または、直感的)である。
筆者は、自分自身で、TCP/IPなどのインターネット・プロトコルを処理するプ ロトコル・スタックを作った経験がある。
IPv4では、絶対的にリトル・エンディアンが不利なわけではないが、コーディングに 注意を要する。また、各CPUの特徴を把握してよく考えなければならない。 (ソース・コードを全CPUで共通にしたいので)
ビッグ・エンディアンのCPUであれば、ほとんど注意が不要である。
IPv6においては、ビッグ・エンディアンにした方が、無難であろう。



4. おまけ 2

リトル・エンディアンは、80x86を除くと、DEC社が採用していた。
8080(Intelの8086の前の機械)は、命令セットなどが、DEC社PDP-11を意識して いた。おかげで、リトル・エンディアン。
Z80は8080の上位互換なので、リトル・エンディアン
1970年代のメジャーなマイクロ・プロセッサでリトル・エンディアンであった のは、8080(その他Intelの8bit系),Z80と、6502 (Apple ][ や、ファミコンのCPUと して有名)である。
6800, 6809 は、ビッグ・エンディアンである。

DEC社は、昔は、世界第二位のコンピュータ・メーカ。 ミニコン・メーカとしては世界最大。Compaqに吸収され、現在は、HP。
DEC社のPDP-11, VAX-11, Alpha は、すべてリトル・エンディアン固定。
DEC Alphaは、極端にパイプライン深度が深く、命令が単純化されたRISCである、 高速なマイクロ・プロセッサ。(のちにバイ・エンディアンになった)
PDP-11は、AT&Tで(普通の)UNIXが最初に動いた機械として有名。
VAX-11は4.2BSDが開発された機械であり、 計算機の速度を測る1MIPSの標準機としても有名。
ただし、DEC社のDEC-10は、バイト操作は、ビッグ・エンディアン

MIPS CPUは、SGIをはじめとするワークステーション、UNIXマシン企業では、 ビッグ・エンディアンで使用された。
それらの会社は、大抵がすでに 680x0 CPUでUNIXマシンを作り、販売していた。
よって、ビッグ・エンディアンを踏襲するのが、自然であった。
しかし、DEC社だけは、MIPSをリトル・エンディアンで使用した DEC-Stationシリーズを出荷した。
MIPSは、WindowsNT, WindowsCEが動作した。それらは、リトル・エンディアンである。
組込み系は、WindowsCEの周辺機器を利用するリファレンスが多かったので、 組込みMIPSは、リトル・エンディアンがほとんである。
ただし、組込みMIPSでも、ネットワーク機材だけは、ビッグ・エンディアンで 使用されるのが普通である。

SUNは、680x0系CPUを使用していたので、SUN主導で作られたSPARCは、 長いことビッグ・エンディアン固定であった。

日立は、6800のセカンド・ソースを作っており、ビッグ・エンディアン会社である。
大型計算機もビッグ・エンディアンである。
日立のH-8, H-16, SH-2,SH-3,4はすべて基本がビッグ・エンディアンである。
しかし、SH-3,4は、バイ・エンディアンで、WindowsCEではリトル・ エンディアンで使用されている。
MIPS同様、組込みでは、WinCEの周辺機器を流用したリファレンスがあり、 SH-4用のLinuxでもリトル・エンディアン使用が多くある。

IBMはビッグ・エンディアン会社である。
IBMが開発したPower, PowerPC アーキテクチャは、 バイ・エンディアンであるが、基本はビッグである。
PowerPCも、WindowsNT, WindowsCEが動作した。
Mac, IBM-PowerStationは、PowerPCをビッグ・エンディアンで使用した。

ARMは、昔はビッグ・エンディアン使用が多かった。
しかし、ARM(XScale, StrongARM)にWindowsCEを搭載したPDAが 数多く出た 1999年-2000年頃から、リトル・エンディアン 使用が多くなった。
現在では、ほとんどの組込みARMは、リトル・エンディアンである。
しかし、ルータのような、純粋ネットワーク機材に使用されている場合は、 ビッグ・エンディアンであることがほとんどである。
Intelは基本的にリトル・エンディアン企業だが、XScaleコアを使用した ネットワーク用チップ IXP シリーズは、ビッグ・エンディアンである。



5. おまけ 3

PDP-11 longとかMixed-endianとか、middle-endianとか呼ばれる 置き方(バイト順)がある。

数値 0x12345678をメモリ上では下のように配置した。


16bitの中はリトルだが、16bit単位では、ビッグな配置になっている。

これは、DEC社PDP-11で採用されていた。
PDP-11は、リトル・エンディアンの16bit 機であったが、 32bit整数を表すのに、PDP-11 longを採用していた。
PDP-11用のUNIXもこの表現を使用している。

EthernetのMACアドレスもこれに似たような雰囲気である。
Ethernetを作るときに、DEC社とIntel社が深く関わっていたことを忘れては ならない。


ちなみに、筆者はDECファンであり、PDP-11 を長く使っていた。
その後、SUNとMacも長く使ったが、ビッグ・エンディアンが それほど好きなわ けではない。


参考
英語版Wikipedia Endianness

ビットのエンディアンについて
たけおかのホーム・ページ