Compiler Construction Lecture 10/19

Compiler Construction Lecture 10/19

先週の復習



問題1

GCC は以下の手順で生成される IとTを使って、以下のコンパイルを図示せよ (I-T図)

実行系のArchitecture

Compilerのtargetにはいろいろあるが、あるComputer上でもっとも高速なのは、 そのComputerのmachine language(機械語)である。したがって、machine language がもっとも重要なCompiler targetだということができる。ここでは、いくつかの CPUのProgramming Modelを学び、その実行を調べる方法を学ぶ。

CPUのprogramming modelは、以下の要素からなる。

個々のCPUには、それぞれ特徴があり、compilerを作る際にはその特徴を 考慮する必要がある。しかし、極端に異なるachitecutreを持っているものは 少なく、どれをとっても同じようなものだともいうことができる。

すべてのCPUに詳しくなる必要はないが、どれか一つの専門家にはなって いたい所である。


Little-Endian, Big-Endian

Computer には memory がつきものだが、memory は、1 byte (= 8bit) 単位でlinear address (byte addressing) がふられている。しか し、最近のCPUは、16bit, 32bit, 64bit 単位(word)で処理をおこ なう。従って、wordをどのように byte addressing に割り振る(map) かという問題がある。これには主に2種類の mapping があり、それ ぞれLittle-Endian, Big-Endian と呼ばれている。

どちらが優れているかという議論はあったが、現在では卵のとがっている 方から割るか、丸い方から割るかぐらいの違いしかないと認識されている ようだ。


もう、このmappingは、CPU - memory 間の転送も考慮する必要がある。 同じ 1 word を転送するのでも、Busが64bit幅だったりすれば、その アドレス下位3bitの値によって、一回で転送できる場合とそうでない 場合がある。これを word alignment の問題という。当然、一回で 転送できる方が高速に動作する。

これらの問題は、普通のプログラミングでは考える必要はないが、 効率の良いMachine Languageを生成する場合には考慮する必要が ある。


Addressing Mode

実際にCPUとmemoryのdataのやり取りをするのが、load/store 系の命令 である。CPUの命令の中で大きな割合を占める。Addressing modeとは、 register や命令で、どのように memory address を指定するかを決める 方法である。昔は、MC6809のように豊富なIndex modeを持つものが 歓迎された。今では、RISC Architecture という、simple な Address mode を持つ命令が好まれている。

現在のプログラミングでは、配列(array)やリスト(list)、構造体(structure) のアクセスが重要なので、Addressing mode は、それを1命令で実現しやすい ように設計されているのが普通だ。だいたい図のようなAddressing mode を採用しているものが多い。





いろいろなCPUのProgramming Model

Motorola MC6809

「究極の8bit CPU」とかいわれたCPU。OS-9というOSに合わせて開発されて いる。8bit CPUにしては珍しく、2つのAccumulator, 4つのIndex Register を持つ。

Addressing modeには以下のようなものがある。

 Immediate                        LDA #$F0      constantをloadする
 extended                         LDA $F000     指定されたaddressからloadする
 indexed                          LDA 5,X       indexとoffsetで示されたaddress からload する
 accumulator offset indexed       LDA A,X
 indexed + post increment         LDA A,X+      loadしたあと X を一つ増やす
 indexed + pre decrement          LDA A,-X      loadする前に X を一つ減らす
さらに、これらを一段間接にしたindirect addressing も用意されている。 演算は、基本的にaccumulatorとmemory間で行われる。



Intel x86 32bit mode

現在もっとも良く使われているCPU。しかし、16bit modeを使っている所も 多いだろう。ここでは、比較的きれいなarchitectureを持っている32bit mode のみを紹介する。

8bit CPU(8080)の拡張によってできたCPUなので、32bit modeでも それをかなり引きずっている。命令はMC6809と同じ8bitの可変長命 令である。80386によって、16bit/32bit切替と仮想記憶がサポート され爆発的な成功を納めた。最近のPentinumPro では、内部でRISC 命令に変換してから実行するというようなことをしている。16bit ではregisterの役割が偏っていたが、32bitでは若干対称性が良く なっている。4本のAccumulator、4本のIndex register を持つ。

Addressing modeには以下のようなものがある。

 Immediate                        movb al,$F0     constantをloadする
 extended                         movb al,[$F000] 指定されたaddressからloadする
 indexed                          movb al,[EAX+5] indexとoffsetで示されたaddress からload する
 accumulator offset indexed       mov [EBX+EAX]
 accumulator offset indexed       mov [EBX+EAX+5]
さらに、x86には segement register というのがあり、それによっ てvirtual memory (メモリ空間) を切り替えることができる。しか し、普通はすべて同じメモリ空間が設定されている。他のCPUでも データ(data)とコード(code)は別空間にできるものが多い。

演算はレジスタとレジスタの間で行うことが多い。





どのように学ぶのか



宿題2

IBMPC上で、6809 CPU用のGCC cross compilerを作成し、 それから6809CPU上で動作するGCCを作成する手順をI-T図で示せ。

以下のprogram check_endian.c がある。

int check = 0x12345678;
main()
{
    char i, *ptr;
    
    ptr = (char *)✓ 
    i = ptr[1];
    return i;
}
このprogramをcompileしたassemblerを、どれか一つのCPUで表示 させて見よ。また、gdb で i にどのような値が入るかを 確認せよ。そのCPUは、Little-Endian か Big-Endian かを答えよ。 また、 trace の結果を、
Subject: compiler report 10/19
というSubjectのメールにして、kono@ie.u-ryukyu.ac.jp まで送ること。 また授業を受けなかったものは、課題を、
Subject: compiler lecture 10/19
というサブジェクトで送ること。

Kono's home page http://bw-www.ie.u-ryukyu.ac.jp/~kono/