はじめに

玄箱と玄箱 HG に使用されている CPU は Motorola (freescale) の MPC8241 で PowerPC603eをベースとした組み込み用の CPU です(玄箱PROはARM系で異なります)。玄箱は PowerPC のアセンブリプログラミングを試すには、OS として Linux を使っているため、コンパイラやアセンブラといった開発環境が付属した非常に安価に入手できるコンピュータです。


かつてはIBMの RS6000 や PowerMac を購入するしか PowerPC を使えませんでしたが、最近では任天堂の Wii に使われており、ソニーの Playstation3 でも 64bit PowerPC である Cell processor が使われ、またマイクロソフトの XBox360 も PowerPC ベースの CPU が使われています。


玄箱を使って身近になりつつある PowerPC をアセンブリプログラミングをしながら探っていこうと思います。

玄箱の開発環境

玄箱のCD-ROMには開発環境のバイナリファイルがに付属していますが、標準のセットアップではインストールされません。アセンブラを使用するには、玄箱付属のCD-ROMから以下のようにしてインストールする必要があります。

バイナリファイルのコピー

Windowsから玄箱にCD-ROMの内容をコピーします。玄箱のネットワークフォルダにCD-ROMというフォルダを作成して、その中に玄箱にCD-ROMのbinaryフォルダをコピーしているものとしています。その他のフォルダにコピーした場合は、 /mnt/share/CD-ROM/binary/*.tar.gz の部分を適当に読み替えてください。

展開

玄箱に telnet で root でログイン(パスワードは玄箱の説明書に書かれています)して、次のようにバイナリファイルをインストールします。

 for filename in /mnt/share/CD-ROM/binary/*.tar.gz
 do
    tar vzxf $filename -C /
 done

アセンブリ言語とは

アセンブリ言語とは、CPUが直接理解できる2進数でできた命令(機械語またはマシン語)を人間が理解しやすい名前(ニーモニック)を使ってプログラミングするための言語です。アセンブリ言語で書かれたソースプログラムは、アセンブラという名のプログラムを使って機械語に翻訳(アセンブル)します。ソースプログラムの1行は「ほぼ」機械語の1命令に相当します。アセンブラが複数の命令を1つの命令に翻訳する場合や、1つの命令が複数のニーモニックを持っている場合があり、単純に1対1の対応が成り立たない場合もあります。


CPUの種類ごとに複数のアセンブラが存在するため、アセンブリ言語は、非常に多くの言語の総称となっています。しかし、1種類のアセンブリ言語を習得すると、ほかの言語も比較的容易に習得できると思います。

解説の範囲

Linuxカーネルのシステムコールを直接呼び出すアセンブリプログラミングに関して解説していきます。玄箱の CPU は PowerPC603e 相当の32bitCPUのため 32bit の PowerPCのレジスタと命令のみを扱います。また、ユーザモードで使用可能なレジスタ、命令のみに限定し、OS レベルのレジスタ、命令は解説しません。浮動小数点命令も当面扱わない予定です。

PowerPCの特徴

PowerPCと他のCPU(x86, MIPS, ARM)との最も異なる点は、条件比較命令で変化する条件レジスタが 8 セットあり、比較命令でフラグを設定する条件レジスタを指定することができ、各セット間の論理演算が可能な点と分岐命令の分岐条件に条件レジスタの 8セットのうちの1つを指定できる部分ではないかと思います。

また、読み書きの対象となるメモリアドレスの指定方法(アドレッシングモード)が単純である一方、ネイティブなニーモニックが複雑(人間向きでない)である点も特徴であると思います。


その他の特徴としてMIPS, ARMと同様に命令が32ビット固定長、ARMと同じくMIPSやSHので採用されている遅延スロット(慣性:分岐する場合でも1命令余分に実行)がない、 MIPSと同じくx86やARMが持つようなレジスタをスタック退避する便利な命令がない (MIPSよりは便利)といった、MIPSとARMの中間の性質があります。


また、PowerPC系ならば浮動小数点演算はほとんどのCPUで使用可能である点は MIPSやARMより優れています。

エンディアン

玄箱はビッグエンディアンマシンです。つまり、メモリ上で最上位バイト(MSB)が最下位アドレスに位置することになります。イメージ的に逆のように感じますが、メモリ内容をリスト (メモリダンプ) した場合、左から最上位バイトが並ぶため自然に感じます。


Big Endian
Little Endian

Windowsマシンで使われる Pentium(i386系)のCPUはリトルエンディアンを採用していて、上位のバイトは上位のメモリアドレスに位置します。文章で表すと、こちらの方が自然な感じがしますが、メモリダンプを 32ビット単位でリストした場合と、8ビット(1バイト)単位でリストした場合の並びが逆になり、私は好きではありません。


実際に整数値(16進数)がメモリ中にどのように格納されるか見てみましょう。

                .align 2
  bytedata:     .byte 0x23
  shortdata:    .short 0x2345
  longdata:     .long 0x12345678
                .align 2
  bytedata2:    .byte 0x23
                .align 2
  shortdata2:   .short 0x2345
                .align 2
  longdata2:    .long 0x12345678

上のリストをアセンブルして、メモリ内容をダンプすると次のようになります。

--------+------------
アドレス   データ
--------+------------
1000007C  23 23 45 12
10000080  34 56 78 00
10000084  23 00 00 00
10000088  23 45 00 00
1000008C  12 34 56 78
--------+------------

最終行が分かり易いですが、「0x12345678」という16進数値を1バイト単位でリストした場合に、「12 34 56 78」という形に並ぶ方式をビッグエンディアンと呼びます。ビッグエンディアンの場合は32ビット単位でリストしても「12345678」とならびます。最上位の桁(ここでは 12)が左に来ていますが、メモリアドレスとしては下位(番地が小さい) になっています。

参考資料

32ビットPowerPC アーキテクチャプログラミング環境
https://www.freescale.co.jp/pdf/MPCFPE32BJ_R0.pdf

AN2491 Simplified Mnemonics for PowerPC Instructions
https://www.freescale.com/files/32bit/doc/app_note/AN2491.pdf

G2 PowerPC Core Reference Manual
https://www.freescale.com/files/32bit/doc/ref_manual/G2CORERM.pdf

MPC603e RISC Microprocessor User's Manual
https://www.freescale.com/files/32bit/doc/ref_manual/MPC603EUM.pdf

PowerPC Compiler Writer's Guide
https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF7785256996007558C6


目次