k-ogawa2025’s ブログ

メカトロ制御回路設計に関する情報発信ブログ

1.5 エンディアン

本項ではメカトロ制御に使うCPUが扱うエンディアンについて記載しています。

エンディアンは1つの値を表すのに複数の単位ブロックを一塊として使うときに、一塊の中での単位ブロックの並び順を指すと思います。ここでは下記の2つについて書きます。

  • バイト単位の並び順
  • ビット単位の並び順

1.5.1 バイト単位の並び順

一般に「エンディアン」というとデータ幅が8bitより大きい16bitや32bitのデータをメモリーに配置する並べ方、すなわちバイト単位の並び順のことを指します。「バイトオーダー」と呼ばれることもあります。並べ順が発生するのはメモリーが8bit(1バイト)を1単位として扱い、1単位ごとにアドレスを割り当てているからです。

ですから、有効なビット数が8bitまでのデータであればメモリーの1アドレスに格納することができます。しかし、8bitを超えるデータはメモリーの複数のアドレスに格納することになります。そうすると、データのどのバイトをメモリーのどのアドレスに配置するかという並べ方に複数の方法が発生します。この並べ方をエンディアンまたはバイトオーダーと呼びます。

エンディアンで、主に使われているのはリトルエンディアンとビッグエンディアンの2つです。

  • トルエンディアンは、メモリーのアドレスの小さいほうから大きいほうに向かってデータの最下位バイトから順に格納する並べ方。
  • ビッグエンディアンは、メモリーのアドレスの大きいほうから小さいほうに向かってデータの最下位バイトから順に格納する並べ方。

32bitデータと16bitデータのメモリーでの配置を下図に示します。参考に8bitデータでの配置も下図に示しますが、8bitデータはメモリーの1つのアドレスに格納できるのでリトルエンディアンとビッグエンディアンの配置は同じです。

図 1.5-1 32bitデータのメモリー配置

図 1.5-2 16bitデータのメモリー配置

図 1.5-3 (参考)8bitデータのメモリー配置

このメモリーにデータを配置するエンディアン(バイトオーダー)が使用するCPUではどちらなのかを意識しないといけない場合に下記があります。

  • プログラムをビルドするとき
  • デバッガーでメモリーの値を確認するとき
  • プログラムの中でメモリーへの書き込み時と読み出し時でデータ幅が異なるとき

プログラムをビルドしてオブジェクトファイルを作るときに使用するCPUのエンディアンと合わせる必要があります。プログラムの中の命令には長さが1Byte(8bit)よりも長いものがあり、その場合は1つの命令を複数のアドレスに配置することになるからです。ビルドに使うツールの設定でオブジェクトファイルのエンディアンを指定できると思います。

デバッガーでメモリーに書かれた16bitデータや32bitデータの値を確認するときは使用するCPUのエンディアンに合わせた読み方をする必要があります。またデバッガーのアプリでデータ幅とエンディアンを指定して表示させることもできると思います。

特別な理由がなければやらないと思いますが、プログラムの中でCPUがメモリーへ書き込む時のデータ幅と読み出す時のデータ幅を変える場合は、書き込むアドレスと読み出すアドレスをCPUのエンディアンに合うようにソースコードを書く必要があります。例えば図 1.5-1のようにメモリーのm+0番地からm+3番地に32bitデータが書き込んであるとします。次に8bitデータ幅で読み出して最下位バイトだけをメモリーから取り出す場合、使用するCPUがリトルエンディアンだとm+0番地から読み出します。ビッグエンディアンだとm+3番地から読み出します。

1.5.2 ビット単位の並び順

ここまではメモリーにデータを配置するときのバイト単位の並び順のエンディアン(バイトオーダー)についてみてきました。他のエンディアンにビット単位の並び順のエンディアン(ビットオーダー)があります。

  • トルエンディアンは、データの最下位ビットから順にビット番号のb0から割り振る並べ方。
  • ビッグエンディアンは、データの最上位ビットから順にビット番号のb0から割り振る並べ方。

16bitデータのビット順を下図に示します。

図 1.5-4 16bitデータのビット順

このビット単位の並び順のエンディアン(ビットオーダー)は現在のメカトロ制御に使うCPUではほとんどがリトルエンディアンだと思います。ですからCPUの資料でエンディアンの項を見てもビット単位の並び順のエンディアン(ビットオーダー)は触れていないことが多いと思います。ビッグエンディアンの場合は明記すると思うので見当たらなかったらリトルエンディアンと考えてよいと思います。

例として用いるCPUのエンディアン

例として用いるCPUのArm製Cortex-M33ではメモリーにデータを配置するときのバイト単位の並び順のエンディアン(バイトオーダー)は、命令はリトルエンディアンで、データはリトルエンディアンとビッグエンディアンのどちらにするか実装時に設定できます[1]。実装時に設定できるということはArm製Cortex-M33をMCUに組み込むときに設定されます。動作の確認に使うCortex-M33を搭載したSTマイクロエレクトロニクス製STM32H503では命令とデータの両方がリトルエンディアンなので、データはリトルエンディアンに設定されているようです[2]。ビット単位の並び順のエンディアン(ビットオーダー)は、エンディアンの説明の図を見ると最下位ビット(Least significant bit)にビット0が割り振られているので普通にリトルエンディアンだと思います[3]

ルネサスMCU RX110グループに搭載のRX CPUではメモリーにデータを配置するときのバイト単位の並び順のエンディアン(バイトオーダー)は、命令はリトルエンディアンでデータはリトルエンディアンとビッグエンディアンのどちらかにするか設定できます[4]。ビット単位の並び順のエンディアン(ビットオーダー)は、エンディアンの項には記載が見当たりませんでしたがレジスタのデータ配置とメモリー上のデータ配置の項にある図で最下位ビット(LSB)にb0が割り振られているので普通にリトルエンディアンだと思います[5]

ひとりごと

今までメカトロ制御に使うCPUではメモリーにデータを配置するときのバイト単位の並び順のエンディアン(バイトオーダー)はビッグエンディアンが主流だと思っていました。しかし、例として用いる2つのCPUのように最近のCPUではリトルエンディアンが主流になると思いました。昔からパソコン用のCPUはリトルエンディアンですし、将来はリトルエンディアンの一択になりエンディアンがどちらかを気にすることは無くなるかもしれません。


[1] Arm Limited.Arm® Cortex®-M33 Devices Generic User Guide.Issue 0100-06.1 August 2024,2.1.5 Data types and data memory accesses.p.33,A.1 Processor implementation options.p.307.

[2] STMicroelectronics.STM32 Cortex®-M33 MCUs programming manual.Revision 4.24-May-2024,2.1.5 Data types and data memory accesses.p.19.

[3] Arm Limited.Arm®v8-M Architecture Reference Manual.Version B.y.2024/Aug/09,B7.5 Endianness.p.225.

[4] ルネサスエレクトロニクス.RX110グループ ユーザーズマニュアル ハードウェア編.Rev.1.20.2016.07,2.5 エンディアン.p.66.

[5] ルネサスエレクトロニクス.RX110グループ ユーザーズマニュアル ハードウェア編.Rev.1.20.2016.07,2.5.4 データ配置.p.70-71.

メカトロ制御向け CPUの構造と動作