バイトオーダーに悩む

古いマイコンで使っていたプログラムを移植するに当たって、

バイトオーダーをどうすればいいんだろうという話をしていた。

新しいマイコンはバイトオーダーが変わるのは確定していて、

外部とのインターフェースは従来のバイトオーダーであるというのも決まっている。

どこでバイトオーダーを切り替えるかという問題である。

というのもマイコンにつながるバス部分はある程度自由度があるからである。


バイトオーダーというと2バイト以上の数値をメモリ上にどう並べるかという話である。

0x1234という数値をメモリ上に{12 34}と並べるのがビッグエンディアン、

{34 12}と下位ビットを含むバイトから順番に並べるのがリトルエンディアンである。

リトルエンディアンの方が処理性能を出しやすいとか見たことがある。

人間が足し算・引き算・かけ算をやるときも下の桁から順番に計算するように、

コンピュータにとってもLSBから順番に計算する方が好都合なのだ。


一方でネットワーク上を流れるデータというのはビッグエンディアンが多いらしい。

例えばデータ長が0x1230というのを伝達するために{12 30}と送信して、

受信した側は届いた順番にメモリに格納してそのデータを4byteの整数として解釈すると、

ビッグエンディアンのシステムでは0x1230と解釈できるが、

リトルエンディアンのシステムでは0x3012となってしまうのでこれではいけないと。

なので実際には読み出し後にビット順を入れ換えたり(ex. 0x3012→0x1234)

メモリの順番を入れ換えてから読んだり(ex. {12 30}→{30 12}と入れ換えてからリードすると0x1230)、

そういう変換処理を挟まなければいけなくなるわけである。


とはいえ、外部とのやりとりでも、そういう変換が必ずしも必要とも言えないところはある。

例えば、バスに接続されるペリフェラルの内部レジスタへのアクセス、

32bit幅のバスで、必ず4byteアクセスするという約束もあるので、

レジスタに0x80000000をライトすれば、レジスタのMSBがセットされる。

こういう作りにする方が自然ではないかと思う。


問題が起きやすいのは、データの順番が決まっている場合と、メモリを共有する場合ではないかと思う。

データの順番が決まっているというのは冒頭に書いた例の通りである。

届いた順に前から書く、前に書いてあるデータから順番に送るというのは、そうならざるを得ない。

メモリを共有する場合も、ビックエンディアンのシステムで0x12345678を書いて、

リトルエンディアンのシステムで読めば0x78563412となるのは当然である。


ただ、回避策がないとも言えないところはある。

データの順番が決まっている場合、後ろから書く、後ろから送るという方法が

バイトオーダーの雑記 (へっぽこ実験室)

Intelはメモリ構造を図示するときに、右下を最下位アドレスとして、

右から左にバイトを並べて、上の行に進んでいくという書き方をしているらしい。

この方法でメモリダンプを表示するとあまり違和感なく読めますねとある。

このようにアドレスを減らす方向に使って行くという考えは1つある。


メモリを共有する場合も必ず32bit幅でアクセスするとか約束して、

結線時に入れ換えておけばそれはそれでうまくいきそうな気がする。

共有メモリの実データはビックエンディアンで格納されていて、

必ず4byte単位でリード/ライトして32bit幅のバスとやりとりする。

共有メモリ上に{12 34 56 78}と並んでいれば、エンディアンによらず必ず0x12345678と読める形にすると。

4byte単位でしかデータを使わないならば、これで全く問題ない。


ただ、このデータを1byte単位で使いたいとなれば面倒である。

ローカルのRAM上にデータを転写して操作する必要があるが、

ビックエンディアンのシステムでは{12 34 56 78}と共有メモリと同じ順に並ぶ一方、

リトルエンディアンのシステムでは{78 56 34 12}と共有メモリとは異なる並びになる。

読み出したデータを0x12345678→0x78563412と入れ換えて格納すれば、

{12 34 56 78}と共有メモリと同じ順番で格納することはできる。


これを書きながらいろいろ考えていたけど……

うまくやればバイトオーダーを入れ換える操作を意図して書くべき場所は減らせそうな気がした。

ちょっと実験してみないとわからないところはあるんだけど。

メモリ上のデータの取扱単位を4byte単位に揃えることが出来れば、

バイトオーダーの入れ替えを意図的にあれこれする場面は減りそうな気がした。

実際に並ぶデータの順番を意識してやらないといけないところはそこを考えて作る必要はあるが。

あとはメモリダンプみたいに何らか取得できればよいというものもありますからね。

読む側で解釈すればよいからという理屈である。