MIPS32の予習


頼んだ本はまだ来ない。普通なら、アマゾンか何処かでの即日、翌日配達を指定するんだろう
けど、私は、そういう早急なのは嫌いだったりする。
子供の頃の、「もー幾つ寝ると、お正月」と言うのを今でも引きずっている。。そして、無闇に
郵便受けを見に行ったり、それで足りなかったら biff を何処からか連れてきたくなったり
する。

------
BIFF(1)                 FreeBSD 一般コマンドマニュアル                 BIFF(1)

名称
     biff - メールの到着時に、メールの着信とメールの発信人を報告するかどうか設
     定する
 :
歴史
     biff コマンドは 4.0BSD から登場しました。 biff コマンドの名前は、 Heidi
     Stettner の犬の名前にちなんでいます。彼は、1993年の8月に15歳で亡くなりま
     した。
------

本が来るまで、少し予習をしておこう。ネットを漁ると、京都産業大学の、コンピュータ
基礎1・2へ行き着いた。このページの一番下にある、CPUと機械語 が、お目当ての所。
しばし、学生になった気分で、最初から読んで行くと楽しい事が書いてある。

 「アキュムレータ: レジスタの古い呼び名。この用語を「レジスタ」の同義語として口にする
 人がいたら、その人が相当の古株であることはまず間違いない。
 ---Eric Raymond, The New Hacker's Dictionary, 1991」 

ERがそんな事を言っていたんだ。知りませんでしたよ。

 MIPS CPU は設計に無駄が少なく、理解しやすいと言われており、よく欧米の授業の題材になっている。

 ※逆に、Intel Pentium シリーズなどは、やたらに複雑で大きく、命令セッ トも
  ごちゃごちゃして汚いと言われている。
 MIPS は Microprocessor In PlayStation の略である(というのは冗談であ る)。 

正しくは、
MIPSは、Microprocessor without Interlocked Pipeline Stages(パイプラインステージが
インターロックされないマイクロプロセッサ)の略であり、その設計思想を端的に表している。
との事。ヘネパタ本に書いてあるのかな?
また、命令セットが汚いのは、電卓の石を増築につぐ増築で発展させたから、と思いますね。
これもひとえに、営業戦略の勝利なんでしょうね。

ひとしきり楽しんだ後、やがて来る本の事を思い出してみると(詳しい目次が出て
たので、参照していもいいけど)、C言語でも解説があるようだ。
ならば先回りして、MIPS用のクロスコンパイラーも用意しちゃえ。
きっと、FreeBSDにもあるはず。

探してみたら、やはりありました。
コンパイルには、結構な時間がかかるはずなので、女房のお買い物に付き合わされる
前に、仕掛けておいたら、以外に短時間で終了してました。
(遅いCPUを使う時は、運用を工夫するか、アルゴリズムを再考するしかありません)
命令が単純、レジスターが多数あるためやり繰りが簡単とかで、複雑な処理をしなく
ても、良質なコンパイラーが出来るのでしょう。
下記は、出来上がった、クロス環境です。

-r-xr-xr-x  1 root   wheel   566988  3 22 10:34 mips-rtems-size*
-r-xr-xr-x  1 root   wheel   566024  3 22 10:34 mips-rtems-strings*
-r-xr-xr-x  2 root   wheel   582056  3 22 10:34 mips-rtems-ranlib*
-r-xr-xr-x  2 root   wheel   821272  3 22 10:34 mips-rtems-objdump*
-r-xr-xr-x  2 root   wheel   710884  3 22 10:34 mips-rtems-objcopy*
-r-xr-xr-x  2 root   wheel   582056  3 22 10:34 mips-rtems-ar*
-r-xr-xr-x  2 root   wheel   710884  3 22 10:34 mips-rtems-strip*
-r-xr-xr-x  1 root   wheel   229860  3 22 10:34 mips-rtems-readelf*
-r-xr-xr-x  2 root   wheel   574568  3 22 10:34 mips-rtems-nm*
-r-xr-xr-x  1 root   wheel   565544  3 22 10:34 mips-rtems-addr2line*
-r-xr-xr-x  1 root   wheel   565344  3 22 10:34 mips-rtems-c++filt*
-r-xr-xr-x  2 root   wheel   941872  3 22 10:34 mips-rtems-as*
-r-xr-xr-x  1 root   wheel   622372  3 22 10:34 mips-rtems-gprof*
-r-xr-xr-x  2 root   wheel   859600  3 22 10:34 mips-rtems-ld*
-r-xr-xr-x  1 root   wheel    30224  3 22 11:34 mips-rtems-gcov*
-r-xr-xr-x  1 root   wheel    16117  3 22 11:34 mips-rtems-gccbug*
-rwxr-xr-x  1 root   wheel   201801  3 22 11:34 mips-rtems-cpp*
-r-xr-xr-x  2 root   wheel   197770  3 22 11:34 mips-rtems-gcc-4.2.3*
-r-xr-xr-x  2 root   wheel   197770  3 22 11:34 mips-rtems-gcc*

ちょっと長ったらしいコマンド名なので、短いコマンド名も付けておこう。
名前は、3秒考えてインテルに対抗すべく、mccに決定。
(iccって、インテル製コンパイラーの名前だったはず)

[sakae@fb /usr/local/bin]$ sudo ln mips-rtems-gcc mcc
[sakae@fb ~]$ mcc -v
Using built-in specs.
Target: mips-rtems
Configured with: ./configure --target=mips-rtems --enable-languages=c --with-system-zlib --disable-nls --with-libiconv-prefix=/usr/local --without-included_gettext --with-newlib --with-dwarf2 --with-gxx-include-dir=/usr/local/mips-rtems/lib/gcc//include/cxx/ --disable-shared --prefix=/usr/local --mandir=/usr/local/man --infodir=/usr/local/info/ i386-portbld-freebsd6.4
Thread model: single
gcc version 4.2.3


まてよ、どうせアセンブラのソースを吐かせて眺めるのが目的だから、aliasで
mips-rtems-gcc -O0 -S
とでも、しておいた方が良かったかな。
それでは、早速試運転しておこう。

[sakae@fb ~/mips32/programs-euc/chapter-07]$ cat ls.c
int  src = 2001;
int  dst;

int main()
{
   dst = src;

   return 0;
}

[sakae@fb ~/mips32/programs-euc/chapter-07]$ mips-rtems-gcc -O0 -S ls.c
[sakae@fb ~/mips32/programs-euc/chapter-07]$ cat -n ls.s
     1          .file   1 "ls.c"
     2          .section .mdebug.abi32
     3          .previous
     4          .globl  src
     5          .data
     6          .align  2
     7          .type   src, @object
     8          .size   src, 4
     9  src:
    10          .word   2001
    11          .text
    12          .align  2
    13          .globl  main
    14          .ent    main
    15  main:
    16          .frame  $fp,8,$31               # vars= 0, regs= 1/0, args= 0, gp= 0
    17          .mask   0x40000000,-8
    18          .fmask  0x00000000,0
    19          .set    noreorder
    20          .set    nomacro
    21
    22          addiu   $sp,$sp,-8
    23          sw      $fp,0($sp)
    24          move    $fp,$sp
    25          lui     $2,%hi(src)
    26          lw      $3,%lo(src)($2)
    27          lui     $2,%hi(dst)
    28          sw      $3,%lo(dst)($2)
    29          move    $2,$0
    30          move    $sp,$fp
    31          lw      $fp,0($sp)
    32          addiu   $sp,$sp,8
    33          j       $31
    34          nop
    35
    36          .set    macro
    37          .set    reorder
    38          .end    main
    39          .size   main, .-main
    40
    41          .comm   dst,4,4
    42          .ident  "GCC: (GNU) 4.2.3"

どうやら、動いているっぽい。
chapter-07にある ls.as と見比べてみると、ls.s で対応してる本質部分は、25-29行、
それに、33行になるのかな。それ以外のコードが書かれている行は、呼び出し規約に
則った、プロローグ、エピローグだろう。そこまではいいんだけれど、34行目にある
nopは、何のためにあるんだろう? この前のRHGで、PCLの本を読んでいた時、
Common Lispが吐き出す、ネイティブコードの DisAssmbler 出力にも、このような
位置に、(一見不要と思われる)nopが有ったなあ。
何故? って質問してみたら、アライメントの調整の為とかパイプラインの都合とか
じゃないの? って、事だったけど、正解は?
こんな、重箱の隅をつついてばかりいると、頭が禿るからと、言われますので、
これぐらいにしておきます。
兎も角、80X86のアセンブラーじゃ、体が受け付けないけど、これなら何とかなりそう
なので、ほっとしました。
早く、本こないかなー。