1 \input texinfo @c -*-texinfo-*-
3 @setfilename yacasl2.info
4 @settitle YACASL2 - Linux上のCASL II処理系
8 Copyright @copyright{} 2010 j8takagi
20 @subtitle Linux上のCASL II処理系
37 @node YACASL2の概要, YACASL2のインストール, Top, Top
40 YACASL2は、Linux上で動作するオープンソースのCASL II処理系です。CASL IIは情報処理試験で用いられるアセンブラ言語で、次の資料により仕様が公開されています。
43 @uref{http://www.jitec.ipa.go.jp/1_00topic/topic_20081027_hani_yougo.pdf, 試験で使用する情報処理用語・プログラム言語など(2008年10月版)}[PDFファイル]
47 YACASL2は、CASL IIアセンブラ言語で記述されたファイルをアセンブルし、仮想マシンCOMET II上で実行します。アセンブルと実行は、連続で行うことも別々に行うことも可能です。
48 YACASL2の動作はCASL IIの仕様に準拠しているため、情報処理試験の問題をはじめ各種参考書やサイトに記載されたCASL IIのプログラムをそのままアセンブルして実行できます。また、本パッケージ中にCASL IIのサンプルプログラムが多数収録されています。
50 YACASL2は、「ふつうの処理系」として動作します。ほかの多くのCASL IIエミュレーターと違い、デバッガーとして動作したり、コンピューター内部の模式図を表示したりすることはありません。そのかわり、YACASL2は、次のような動作内容をすべてテキストで出力します。
67 出力された動作内容は、GNU/Linuxのさまざまなツール、たとえば@command{cat}、@command{less}、@command{grep}、@command{wc}などを使って解析できます。
70 YACASL2は、Linux上で動作します。現在動作を確認しているのは、次のディストリビューションです。
75 Ubuntu Linux 9.04 / 8.04
81 インストール時に、@command{tar}、@command{gcc}、@command{make}が必要です。
83 @node YACASL2のインストール, YACASL2の使い方, YACASL2の概要, Top
84 @chapter YACASL2のインストール
85 YACASL2をインストールするには、Linux上で次の作業をします。
90 @file{yacasl2.tar.gz}のダウンロード
93 @file{yacasl2.tar.gz}の検証
96 @file{yacasl2.tar.gz}の展開
99 @command{casl2}、@command{comet2}、@command{dumpword}のビルド
102 @command{casl2}の実行テスト
111 以下の操作は、端末を開きコマンドを実行します。
113 @section @file{yacasl2.tar.gz}のダウンロード
119 $ @command{wget somewhere/yacasl2.tar.gz}
120 $ @command{wget somewhere/yacasl2.tar.gz.md5sum}
124 @section @file{yacasl2.tar.gz}の検証
128 ダウンロードが完了したら、@command{md5sum}と@command{diff}で正しくファイルがダウンロードができているかを検証します。
132 $ @command{md5sum yacasl2.tar.gz | diff -s yacasl2.tar.gz.md5sum -}
133 Files yacasl2.tar.gz.md5sum and - are identical
137 @section @file{yacasl2.tar.gz}の展開
139 @file{yacasl2.tar.gz}をダウンロードしたら、次のコマンドで展開します。
143 $ @command{tar xvzf yacasl2.tar.gz}
147 @section @command{casl2}、@command{comet2}、@command{dumpword}のビルド
149 展開したら、次のコマンドで@command{casl2}、@command{comet2}、@command{dumpword}をビルドします。
153 $ @command{cd yacasl2}
156 make[1]: Entering directory ‘/home/kazubito/yacasl2/src’
157 gcc -c -g -Wall -I ../include casl2.c
158 gcc -c -g -Wall -I ../include word.c
159 gcc -c -g -Wall -I ../include hash.c
160 gcc -c -g -Wall -I ../include cerr.c
161 gcc -c -g -Wall -I ../include struct.c
162 gcc -c -g -Wall -I ../include cmd.c
163 gcc -c -g -Wall -I ../include assemble.c
164 gcc -c -g -Wall -I ../include token.c
165 gcc -c -g -Wall -I ../include label.c
166 gcc -c -g -Wall -I ../include macro.c
167 gcc -c -g -Wall -I ../include exec.c
168 gcc -c -g -Wall -I ../include dump.c
169 gcc -g -Wall -I ../include -o ../casl2 casl2.o word.o hash.o cerr.o st
170 ruct.o cmd.o assemble.o token.o label.o macro.o exec.o dump.o
171 gcc -c -g -Wall -I ../include comet2.c
172 gcc -g -Wall -I ../include -o ../comet2 comet2.o word.o hash.o cerr.o
173 struct.o cmd.o exec.o dump.o
174 gcc -c -g -Wall -I ../include dumpword.c
175 gcc -g -Wall -I ../include -o ../dumpword dumpword.o word.o cerr.o
176 make[1]: Leaving directory ‘/home/kazubito/yacasl2/src’
180 @section @command{casl2}の実行テスト
182 ビルドしたら、次のコマンドが正常に実行できるかを確認します。
183 正常に実行された場合は、「Hello, World!」と表示されます。
187 $ @command{./casl2 as/hello.casl}
194 次のコマンドを実行すると、正常にビルドできているかどうかを詳細にテストできます。
198 $ @command{make check}
199 194 / 194 tests passed. Details in /home/kazubito/yacasl2/test/integra
201 All tests are succeded.
202 149 / 149 tests passed. Details in /home/kazubito/yacasl2/test/integra
204 All tests are succeded.
205 4 / 4 tests passed. Details in /home/kazubito/yacasl2/test/integration
207 All tests are succeded.
211 @section 環境変数@var{PATH}の設定
213 環境変数@var{PATH}にYACASL2のディレクトリーを追加すると、どのディレクトリーでも@command{casl2}、@command{comet2}、@command{dumpword}を実行できます。
215 環境変数の設定方法は使っているシェルによって異なります。シェルは、次のコマンドで確認できます。
219 $ @command{echo $SHELL}
224 現在もっとも多く使われているシェルは、BASHでしょう。BASHでは、次のコマンドを実行すると環境変数@var{PATH}にYACASL2のディレクトリーが追加されます。
228 $ @command{PATH=$PATH:~/yacasl2 && export PATH}
232 シェルの初期設定ファイルに上記のコマンドを追加すれば、今後ログインした後は自動的にどのディレクトリーでも @command{casl2}、@command{comet2}、@command{dumpword}を実行できます。BASHではホームディレクトリーにある@file{.bashrc}が初期設定ファイルのため、次のコマンドで追加されます。
236 $ @command{echo ’PATH=$PATH:~/yacasl2 && export PATH’ >>~/.bashrc}
240 @node YACASL2の使い方,, YACASL2のインストール, Top
241 @chapter YACASL2 の使い方
242 YACASL2 は、テキストファイルに記述されたCASLプログラムを処理します。以下の例で用いられるCASLプログラムのファイルは、テキストエディタなどで作成してください。また、インストールしたディレクトリーの中にある@file{as}ディレクトリーからコピーして作成することもできます。
244 @section 実行結果の出力だけを表示
246 インストール時にコマンド実行の確認に使った@file{hello.casl}は、次のような内容です。CASL IIのマクロ命令OUTは、文字列を出力します。
250 $ @command{cat hello.casl}
254 OBUF DC ’Hello, World!’
260 次のコマンドを実行すると、CASL II のアセンブルと仮想マシン COMET II 上での実行が連続で行われ、文字列が出力されます。
264 $ @command{casl2 hello.casl}
269 @file{addl.casl}は、3と1の和を求めます。
273 $ @command{cat addl.casl}
285 このプログラムには出力命令がないため、オプションなしで実行した場合には結果が出力されません。
289 $ @command{casl2 addl.casl}
294 実行内容を確認するには、後述のようにCPU 内にあるレジスターやメモリーの内容を表示するか、結果を出力するための処理を追加する必要があります。
296 @file{sum_10.casl}は、1から10までの整数の和を求めます。
300 $ @command{cat sum_10.casl}
302 ;;; 出力 GR0: 1から10までの整数をすべて加算した値
306 LD GR1,FST ; GR1に初項を転送
307 LOOP ADDL GR0,GR1 ; ループ先頭
308 ADDL GR1,STEP ; GR1 <- GR1 + 公差
309 CPL GR1,LST ; GR1が末項より大きい場合は終了
321 このプログラムも、オプションなしで実行した場合には結果が出力されません。
324 $ @command{casl2 sum_10.casl}
330 casl2の処理途中で行われるアセンブルの結果を表示するには、オプション@option{-a}を指定します。また、ラベルとアドレスの対応表を表示するには、オプション@option{-l}を指定します。
332 次のコマンドでは@file{hello.casl}の、ラベルとアドレスの対応表と、アセンブル結果と、実行結果が表示されます。OUTはアセンブラ命令で複数の機械語命令で構成されているため、命令行1行に対して、複数行のコードが生成されます。
336 $ @command{casl2 -a -l hello.casl}
338 Assemble hello.casl (0)
345 Assemble hello.casl (1)
346 hello.casl: 1:MAIN START
347 hello.casl: 2: OUT OBUF,LEN
370 hello.casl: 4:OBUF DC 'Hello, World!'
384 hello.casl: 5:LEN DC 13
391 @file{addl.casl}の、ラベルとアドレスの対応表と、アセンブル結果は、次のようになります。
395 $ @command{casl2 -a -l addl.casl}
397 Assemble addl.casl (0)
404 Assemble addl.casl (1)
405 addl.casl: 1:;;; ADDL r,adr
406 addl.casl: 2:MAIN START
407 addl.casl: 3: LD GR1,A
410 addl.casl: 4: ADDL GR1,B
423 なお、オプション@option{-A}を指定すると、アセンブル結果が表示される時点で処理が終了します。仮想マシンCOMET II での実行は行われません。
425 @section 実行時のレジスターとメモリーを表示
426 YACASL2では実行中のCPUのレジスターとメモリーの内容をそれぞれ、@option{-t}と@option{-d}を指定することで表示できます。
428 また、@option{-M}で、仮想マシンCOMET II のメモリー容量を語(16 ビット)単位で指定できます。小さいプログラムを実行するときは、メモリー容量を小さくすれば結果が見やすくなります。
430 @file{addl.casl}に必要なメモリー容量は8語のため、次のようにCPUのレジスターとメモリーの内容を表示できます。
434 $ @command{casl2 -t -d -M8 addl.casl | less}
436 Assemble addl.casl (0)
438 Assemble addl.casl (1)
440 Executing machine codes
442 #0000: GR0: 0 = #0000 = 0000000000000000
443 #0000: GR1: 0 = #0000 = 0000000000000000
444 #0000: GR2: 0 = #0000 = 0000000000000000
445 #0000: GR3: 0 = #0000 = 0000000000000000
446 #0000: GR4: 0 = #0000 = 0000000000000000
447 #0000: GR5: 0 = #0000 = 0000000000000000
448 #0000: GR6: 0 = #0000 = 0000000000000000
449 #0000: GR7: 0 = #0000 = 0000000000000000
450 #0000: SP: 8 = #0008 = 0000000000001000
451 #0000: PR: 0 = #0000 = 0000000000000000
452 #0000: FR (OF SF ZF): 000
454 #0000: adr : 0000 0001 0002 0003 0004 0005 0006 0007
455 #0000: 0000: 1010 0005 2210 0006 8100 0003 0001 0000
457 #0002: GR0: 0 = #0000 = 0000000000000000
458 #0002: GR1: 3 = #0003 = 0000000000000011
459 #0002: GR2: 0 = #0000 = 0000000000000000
460 #0002: GR3: 0 = #0000 = 0000000000000000
461 #0002: GR4: 0 = #0000 = 0000000000000000
462 #0002: GR5: 0 = #0000 = 0000000000000000
463 #0002: GR6: 0 = #0000 = 0000000000000000
464 #0002: GR7: 0 = #0000 = 0000000000000000
465 #0002: SP: 8 = #0008 = 0000000000001000
466 #0002: PR: 2 = #0002 = 0000000000000010
467 #0002: FR (OF SF ZF): 000
469 #0002: adr : 0000 0001 0002 0003 0004 0005 0006 0007
470 #0002: 0000: 1010 0005 2210 0006 8100 0003 0001 0000
472 #0004: GR0: 0 = #0000 = 0000000000000000
473 #0004: GR1: 4 = #0004 = 0000000000000100
474 #0004: GR2: 0 = #0000 = 0000000000000000
475 #0004: GR3: 0 = #0000 = 0000000000000000
476 #0004: GR4: 0 = #0000 = 0000000000000000
477 #0004: GR5: 0 = #0000 = 0000000000000000
478 #0004: GR6: 0 = #0000 = 0000000000000000
479 #0004: GR7: 0 = #0000 = 0000000000000000
480 #0004: SP: 8 = #0008 = 0000000000001000
481 #0004: PR: 4 = #0004 = 0000000000000100
482 #0004: FR (OF SF ZF): 000
484 #0004: adr : 0000 0001 0002 0003 0004 0005 0006 0007
485 #0004: 0000: 1010 0005 2210 0006 8100 0003 0001 0000
489 @subsection 特定のレジスターを表示
491 @file{addl.casl}のレジスターやメモリーの中で、実行中に値が変化しているのはGR1だけです。こうした場合は、@command{grep}を使って表示される内容を絞り込むことで動作を検証しやすくなります。
495 $ @command{casl2 -t addl.casl | grep 'GR1:'}
496 #0000: GR1: 0 = #0000 = 0000000000000000
497 #0002: GR1: 3 = #0003 = 0000000000000011
498 #0004: GR1: 4 = #0004 = 0000000000000100
502 この内容を、先に出力したアセンブル結果と引き比べてください。
503 次の表のように、PRとGR1、命令行が対応していることがわかります。
505 @multitable @columnfractions .3 .3 .4
506 @item PR @tab GR1 @tab 命令行
514 @tab @code{ADDL GR1,B}
517 @subsection プログラム終了時の値を表示
519 @command{grep}と@command{tail}を組み合わせれば、プログラム終了時の値を表示できます。
523 $ @command{casl2 -t addl.casl | grep 'GR1:' | tail -1}
524 #0004: GR1: 4 = #0004 = 0000000000000100
530 $ @command{casl2 -t sum_10.casl | grep 'GR0:' | tail -1}
531 #0010: GR0: 55 = #0037 = 0000000000110111 = '7'
535 @subsection プログラムのステップ数を表示
537 @command{grep}と@command{wc}を組み合わせれば、プログラムのステップ数を表示できます。
541 $ @command{casl2 -t hello.casl | grep 'GR1:' | wc -l}
548 $ @command{casl2 -t addl.casl | grep 'GR1:' | wc -l}
553 @file{sum_10.casl}はプログラム内にループがあるため、ステップ数が大きくなります。
557 $ @command{casl2 -t sum_10.casl | grep 'GR0:' | wc -l}
562 @section アセンブルと実行を別に行う
564 @command{casl2}に@option{-O}@file{ファイル名}を指定すると、オブジェクトファイルを作成できます。
568 $ @command{casl2 -Ohello.o hello.casl}
572 作成されたオブジェクトファイルの内容は、@command{od}を使って確認できます。テキストファイルではないため、@command{cat}などでは確認できません。
576 $ @command{od -t x2 hello.o}
577 0000000 7001 0000 7002 0000 1210 0013 1220 0020
578 0000020 f000 0002 1210 0021 1220 0022 f000 0002
579 0000040 7120 7110 8100 0048 0065 006c 006c 006f
580 0000060 002c 0020 0057 006f 0072 006c 0064 0021
581 0000100 000d 000a 0001
586 オブジェクトファイルの実行には、@command{comet2}を使います。
590 $ @command{comet2 hello.o}
597 CASL2では、1語(16ビット)を単位としてデータが処理されます。
598 @command{dumpword}は、指定した1語を10進数、16進数、2進数で表示します。
602 $ @command{dumpword 72}
603 72: 72 = #0048 = 0000000001001000 = 'H'
611 $ @command{dumpword} @verb{|--|} @command{-72}
612 -72: -72 = #FFB8 = 1111111110111000
616 16進数で指定する場合は、次のように指定します。
620 $ @command{dumpword '#0048'}
621 #0048: 72 = #0048 = 0000000001001000 = 'H'