kivantium活動日記

プログラムを使っていろいろやります

PowerPC64のアセンブリ開発環境を整える

PowerPC64のアセンブリを書く課題を手元のx86マシンでテストするための環境構築に関するメモ。

インストール

Ubuntu 14.04での開発を前提としています。

sudo apt-get install gcc-powerpc-linux-gnu qemu-user

また、~/.bashrcに

export QEMU_LD_PREFIX=/usr/powerpc-linux-gnu/

を追加する必要があります。

追加したあとbashを再起動するか

source ~/.bashrc

を実行してください。

使用例

ここではstrlen()に似た動作をするmystrlen()関数をアセンブリで書く例を取り上げます。

まずはC言語ソースコードを書きます。

#include <stdio.h>
extern int mystrlen(char* str);

int main() {
    char str[] = "abcde";
    int len;

    len = mystrlen(str);
    printf("%d\n", len);
    return 0;
}

このようにC言語側のソースコード内ではアセンブリで書きたい関数をexternをつけて宣言しておきます。これをmain.cという名前で保存します。

つぎにアセンブリのコードです

.text
    .align 2
    .globl mystrlen

mystrlen:
    li %r4, 0
.loop:
    lbzx %r5, %r3, %r4
    cmpwi %r5, 0
    beq .end
    addi %r4, %r4, 1
    b .loop
.end:
    mr %r3, %r4
    blr

これをmystrlen.sという名前で保存します。

気持ちだけ説明しておくと、

  • r3には最初メモリアドレスが入っている
  • r4でカウントする
  • r3+r4のアドレスに入っている文字が'\0'(=0)でなければr4を1増やす
  • '\0'であればr4の値をr3に移して終了

という感じです。

コンパイル

powerpc-linux-gnu-gcc -m64 mystrlen.s main.c

のように行います。

ちゃんとPowerPC64のバイナリになっているか確認しておくと

$ file a.out
a.out: ELF 64-bit MSB  executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0dcaa42ed89df39fe14f28b6589a94651e6ce7b4, not stripped

となったので良さそうです。

実行は

qemu-ppc64 a.out

のように行います。

5が出力されたので正しく実行できたようです。

よく使うPowerPCの命令一覧とかは別の機会にまとめて書きたいと思っています。

追記

(仮想環境で実行している場合に?)この方法で実行するとSegmentation Faultする場合があるようです。
バグ報告が上がっていて、それによるとコンパイル時に

powerpc-linux-gnu-gcc -m64 -static mystrlen.s main.c

のように-staticオプションをつけると回避できるらしいです。(未検証)