ふんがさんの授業では,pico や poco を扱っていると思うんけど,
pico 用のアセンブラ〜 poco 用のアセンブラ〜 とかやってると,
新しいアーキテクチャを開発する度にアセンブラも新しく作らなきゃならんのょね…
そんな時に出てくる一声「あぁ〜ダル…」
shapa は授業で扱うレベルのアーキテクチャならば,
命令セットが変わったって,ワード長が変わったって対応できるようになってるのが最大の特徴す!
その為には,パラメータファイルってのを用意する必要があるけど,
アセンブラ書くよりは大分楽っしょ☆
因みにパラメータファイルってのは,
shapa にどういう形式でバイナリファイルを吐き出して欲しいか,ってのを表現したファイルす.
SHAcho {Pa,Pi,Pu,Pe,Po}co Assembler の名前の由来は,
今後,paco とか puco とか peco とか,新しいアーキテクチャを授業で扱うようになっても,
対応できる所にあるんねぃ〜
因みに,落としてきたファイルの "shapa" が本体.
"pico.rb" もしくは "poco.rb" がパラメータファイルす.
pico 実験で pico を改造した時は,
"pico.rb" とかをちょちょいと書き換えれば,いいって訳っすな!
以下,アーキテクチャパラメータファイルのフォーマットです.
多分読む気失せるので,雰囲気を掴んだ方が早いと思います.
#!/usr/bin/env ruby
class Poco < Arch
def initialize
super('poco', 'poco.rb')
@pc_incr = 1
@vars = {
'dst' => {:bitnum => 3, :sign => 'unsigned', :label => false, :jump => nil, :asm_radix => 10, :bin_radix => 10},
'src' => {:bitnum => 3, :sign => 'unsigned', :label => false, :jump => nil, :asm_radix => 10, :bin_radix => 10},
'adr' => {:bitnum => 3, :sign => 'unsigned', :label => false, :jump => nil, :asm_radix => 10, :bin_radix => 10},
'imm8' => {:bitnum => 8, :sign => 'signed', :label => false, :jump => nil, :asm_radix => nil, :bin_radix => 10},
'lr_imm8' => {:bitnum => 8, :sign => 'signed', :label => true, :jump => 'relative', :asm_radix => nil, :bin_radix => 10},
...
}
@opcodes = {
'NOP' => {:asm => '', :bin => '00000_xxx_xxx_00000' },
'ADD' => {:asm => 'r${dst}, r${src}', :bin => '00000_${dst}_${src}_00110'},
'LB' => {:asm => 'r${dst}, \(r${adr}\)', :bin => '00000_${dst}_${adr}_01100'},
'LDI' => {:asm => 'r${dst}, #${imm8}', :bin => '01000_${dst}_${imm8}' },
'JR' => {:asm => 'r${dst}', :bin => '00000_${dst}_xxx_01010' },
...
}
end
def absolute_branch_address(cur_pc, dst_pc)
return dst_pc
end
def relative_branch_address(cur_pc, dst_pc)
return dst_pc - cur_pc - @pc_incr
end
end
$arch = Poco.new
シングルクォーテーションの使用
Ruby において,ダブルクォーテーションとシングルクォーテーションは異なる意味を持つ.
故に,パラメータファイルでは,シングルクォーテーションを用いる事.
3行目: "class アーキテクチャ名 < Arch"
アーキテクチャ名の先頭文字は必ず大文字."< Arch" は変えちゃダメ.
4行目〜25行目: "def initialize 〜 end"
Poco の名前,命令セット等を定義.詳細は以下で説明.
"def initialize" initialize という関数のようなモノを定義しているんだけど,initialize という名前は変えちゃダメ.
5行目: "super('アーキテクチャ名', 'パラメータファイルの名前')"
エラーメッセージを出力する際に必要.
6行目: "@pc_incr = 1"
1命令実行した後に Program Counter がいくつインクリメントされるかを定義."@" は必ずつける.
7行目〜15行目: "@vars = {...}"
命令セットを定義する時に使用する変数の宣言.宣言する内容は,
'変数名' => {:bitnum => ビット幅, :sign => 符号, :label => ラベルの使用, :jump => 相対/絶対分岐の指定, :asm_radix => 変数の○進数, :bin_radix => 変数の○進数} で定義.羅列する場合はカンマを忘れずに!
あと,":sign" は ":sign" であって,"sign" ではないので注意.
:sign は 'signed' か 'unsigned'.
:jump は 'relative' か 'absolute'.
:asm_radix は,アセンブリ言語を書いている時に,○進数で表記せねばならないかを指定.特に指定しない場合は nil.2,8,10,16,nil が指定可能.
:bin_radix は,バイナリ言語からアセンブリ言語に変更する際に,○進数で出力するかを指定.2,8,10,16 が指定可能.nil はダメ.
17行目〜25行目: "@opcodes = {...}"
7行目〜15行目で定義した @vars を使用して,命令セットを定義.
'オペコード' => {:asm => 'アセンブリ言語のオペコードを抜かした部分', :bin => 'バイナリフォーマット'}
例えば "ADD rd, rs" のバイナリコードが "00000_rd_rs_00110" の場合,
'ADD' => {:asm => 'rd, rs', :bin => '00000_rd_rs_00110'} となる.
この時,rd や rs は変数である.
@vars で "dst" と "src" を宣言しておいて,
'ADD' => {:asm => 'r${dst}, r${src}', :bin => '00000_${dst}_${src}_00110'} というように変数を${var}で埋め込む.
19行目の 'LB' ように,(カッコ) を用いる場合はバックスラッシュを付ける事.
他の正規表現で使われる,以下の記号の前にもバックスラッシュを付ける事.
(小カッコ),{中カッコ},[大カッコ],
プラス+,ハイフン-,アスタリスク*,スラッシュ/
ピリオド.,ハテナマーク?,バックスラッシュ\,パイプ|,行頭のハット^,行末のドル$
但し,変数として使用する場合は,${var} には特にバックスラッシュはつけなくてよい.
28行目: def absolute_branch_address(cur_pc, dst_pc)
分岐命令で,絶対分岐アドレスをどう算出するかを cur_pc(現 Program Counter) と dst_pc(飛び先アドレス) を用いて式化する.
(普通は dst_pc を返すだけでよい)
33行目: def relative_branch_address(cur_pc, dst_pc)
分岐命令で,相対分岐アドレスをどう算出するかを cur_pc と dst_pc を用いて式化する.
39行目: $arch = Poco.new
3行目で Poco を定義したら "$arch = Poco.new",Pico を定義したら "$arch = Pico.new" と書く.
例えば,独自のパラメータファイルを用意した場合,パラメータファイルを作っただけでは,読み込まれません.
shapa を実行する際に,そのパラメータファイルを読むように指示しなければなりません.
その方法は2つあります.
方法その1: コマンドラインで指定
普段 shapa を実行する際は,デフォルト設定されたパラメータファイル "poco.rb" や "pico.rb" が読み込まれますが,
コマンドライン上で,-a オプションを利用する事で,パラメータファイルを指定する事が可能です.
% shapa -a PARAMETER_FILE sample.prg
方法その2: shapa をイジってデフォルトパラメータファイルを変更
毎回コマンドライン上で "-a" を使うのはメンドウな人は,
emacs 等で,shapa を開いてみて下さい.
12行目周辺に "DEF_PARAM_FILENAME = ..." という記述があります.
これを自作のパラメータファイル名前に書き換えればいい訳です.
% emacs shapa
#!/usr/bin/env ruby
################################################################################
# SCRIPT : SHAcho {Pa,Pi,Pu,Pe,Po}co Assembler
# VERSION : 2.011
# LAST UPDATE : 2009/09/28(Mon)
# AUTHOR : Yoshiki Saito (shacho)
# URL : http://www.am.ics.keio.ac.jp/members/shacho/parthenon/shapa
# AFFILIATION : Amano Laboratory, Department of Computer Science,
# : Open and Environmental Systems, Keio University, Japan
################################################################################
DEF_PARAM_FILENAME = './poco.rb' ←コレを自作のパラメータファイル名に変更
DEF_DST_FILENAME = './prg.bin'
DEF_PC_INCR = 2
DEF_HEAD_FILENAME = nil
DEF_TAIL_FILENAME = nil
...