はじめに
玄箱と玄箱 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
目次
- 玄箱でアセンブリ 1 - はじめに (2005/04/17)
- 玄箱でアセンブリ 2 - PowerPC のレジスタ (2005/04/17)
- 玄箱でアセンブリ 3 - PowerPCの命令概要 (2005/04/17)
- 玄箱でアセンブリ 4 - アセンブラ GNU as の基礎知識 (2005/04/17)
- 玄箱でアセンブリ 5 - 演算命令 (2005/04/17)
- 玄箱でアセンブリ 6 - メモリ転送命令 (2005/04/23)
- 玄箱でアセンブリ 7 - 比較命令と分岐命令 (2005/05/17)
- 玄箱でアセンブリ 8 - シフト/ローテイト命令 (2005/05/28)
- 玄箱でアセンブリ 9 - その他の命令 (2005/07/09)
- 続く...
- 玄箱でアセンブリ A - システムコールと引数 (2005/04/17)
- 玄箱でアセンブリ B - PowerPCのシステムコールの仕組み (2005/04/23)
- 玄箱用 RVTL - インタプリタの作成 (2005/6/19)