ドキュメントの作成
[YACASL2.git] / doc / yacasl2.texi
1 \input texinfo   @c -*-texinfo-*-
2 @c %**start of header
3 @setfilename yacasl2
4 @settitle YACASL2 - Linux上のCASL2処理系
5 @c %**end of header
6
7 @copying
8 Copyright @copyright{} 2010 j8takagi
9 @end copying
10
11 @titlepage
12 @title
13 @end titlepage
14
15 @c Output the table of contents at the beginning.
16 @contents
17
18 @insertcopying
19
20 @chapter YACASL2の概要
21
22 @cindex chapter, first
23
24 YACASL2は、Linux上で動作するオープンソースのCASL II処理系です。CASL IIは情報処理試験で用いられるアセンブラ言語で、次の資料により仕様が公開されています。
25
26 @quotation
27 @uref{http://www.jitec.ipa.go.jp/1_00topic/topic_20081027_hani_yougo.pdf, 試験で使用する情報処理用語・プログラム言語など(2008年10月版)}[PDFファイル]
28 別紙 1 アセンブラ言語の仕様
29 @end quotation
30
31 YACASL2は、CASL IIアセンブラ言語で記述されたファイルをアセンブルし、仮想マシンCOMET II上で実行します。アセンブルと実行は、連続で行うことも別々に行うことも可能です。
32 YACASL2の動作はCASL IIの仕様に準拠しているため、情報処理試験の問題をはじめ各種参考書やサイトに記載されたCASL IIのプログラムをそのままアセンブルして実行できます。また、本パッケージ中にCASL IIのサンプルプログラムが多数収録されています。
33
34 YACASL2は、「ふつうの処理系」として動作します。ほかの多くのCASL IIエミュレーターと違い、デバッガーとして動作したり、コンピューター内部の模式図を表示したりすることはありません。そのかわり、YACASL2は、次のような動作内容をすべてテキストで出力します。
35
36 @itemize @bullet
37
38 @item
39 ラベルとアドレスの対応
40
41 @item
42 アセンブル結果
43
44 @item
45 実行時のレジスタの内容
46
47 @item
48 実行時のメモリの内容
49 @end itemize
50
51 出力された動作内容は、GNU/Linuxのさまざまなツール、たとえば@command{cat}、@command{less}、@command{grep}、@command{wc}などを使って解析できます。
52
53 @unnumberedsec 要件
54 YACASL2は、Linux上で動作します。現在動作を確認しているのは、次のディストリビューションです。
55
56 @itemize @bullet
57
58 @item
59 Ubuntu Linux 9.04 / 8.04
60
61 @item
62 Vine Linux 4.2
63 @end itemize
64
65 インストール時に、@command{tar}、@command{gcc}、@command{make}が必要です。
66
67 @chapter YACASL2のインストール
68
69 YACASL2をインストールするには、Linux上で次の作業をします。
70
71 @enumerate
72
73 @item
74 @file{yacasl2.tar.gz}のダウンロード
75
76 @item
77 @file{yacasl2.tar.gz}の検証
78
79 @item
80 @file{yacasl2.tar.gz}の展開
81
82 @item
83 @command{casl2}、@command{comet2}、@command{dumpword}のビルド
84
85 @item
86 @command{casl2}の実行テスト
87
88 @item
89 詳細なテスト
90
91 @item
92 環境設定@var{PATH}の設定
93 @end enumerate
94
95 以下の操作は、端末を開きコマンドを実行します。
96
97 @section @file{yacasl2.tar.gz}のダウンロード
98 (詳細未定)
99
100 @example
101 $ @b{cd}
102 $ @b{wget somewhere/yacasl2.tar.gz}
103 $ @b{wget somewhere/yacasl2.tar.gz.md5sum}
104 @end example
105
106 @section @file{yacasl2.tar.gz}の検証
107
108 (PGPを使った検証も導入予定)
109
110 ダウンロードが完了したら、@command{md5sum}と@command{diff}で正しくファイルがダウンロードができているかを検証します。
111
112 @example
113 $ @b{md5sum yacasl2.tar.gz | diff -s yacasl2.tar.gz.md5sum -}
114 Files yacasl2.tar.gz.md5sum and - are identical
115 @end example
116
117 @section @file{yacasl2.tar.gz}の展開
118
119 @file{yacasl2.tar.gz}をダウンロードしたら、次のコマンドで展開します。
120
121 @example
122 $ @b{tar xvzf yacasl2.tar.gz}
123 @end example
124
125 @section @command{casl2}、@command{comet2}、@command{dumpword}のビルド
126
127 展開したら、次のコマンドで@command{casl2}、@command{comet2}、@command{dumpword}をビルドします。
128
129 @example
130 $ @b{cd yacasl2}
131 $ @b{make}
132 make -C src
133 make[1]: Entering directory ‘/home/kazubito/yacasl2/src’
134 gcc -c -g -Wall -I ../include casl2.c
135 gcc -c -g -Wall -I ../include word.c
136 gcc -c -g -Wall -I ../include hash.c
137 gcc -c -g -Wall -I ../include cerr.c
138 gcc -c -g -Wall -I ../include struct.c
139 gcc -c -g -Wall -I ../include cmd.c
140 gcc -c -g -Wall -I ../include assemble.c
141 gcc -c -g -Wall -I ../include token.c
142 gcc -c -g -Wall -I ../include label.c
143 gcc -c -g -Wall -I ../include macro.c
144 gcc -c -g -Wall -I ../include exec.c
145 gcc -c -g -Wall -I ../include dump.c
146 gcc -g -Wall -I ../include -o ../casl2 casl2.o word.o hash.o cerr.o st
147 ruct.o cmd.o assemble.o token.o label.o macro.o exec.o dump.o
148 gcc -c -g -Wall -I ../include comet2.c
149 gcc -g -Wall -I ../include -o ../comet2 comet2.o word.o hash.o cerr.o
150 struct.ocmd.o exec.o dump.o
151 gcc -c -g -Wall -I ../include dumpword.c
152 gcc -g -Wall -I ../include -o ../dumpword dumpword.o word.o cerr.o
153 make[1]: Leaving directory ‘/home/kazubito/yacasl2/src’
154 @end example
155
156 @section @command{casl2}の実行テスト
157
158 ビルドしたら、次のコマンドが正常に実行できるかを確認します。
159 正常に実行された場合は、「Hello, World!」と表示されます。
160
161 @example
162 $ @b{./casl2 as/hello.casl}
163 Hello, World!
164 @end example
165
166 @section 詳細なテスト
167
168 次のコマンドを実行すると、正常にビルドできているかどうかを詳細にテストできます。
169
170 @example
171 $ @b{make check}
172 @end example
173
174 @section 環境設定@var{PATH}の設定
175
176 環境変数@var{PATH}にYACASL2のディレクトリーを追加すると、どのディレクトリーでも@command{casl2}、@command{comet2}、@command{dumpword}を実行できます。
177
178 環境変数の設定方法は使っているシェルによって異なります。シェルは、次のコマンドで確認できます。現在もっとも多く使われているのは、BASHでしょう。
179 @example
180 $ @b{echo $SHELL}
181 /bin/bash
182 @end example
183
184 シェルがBashの場合、次のコマンドを実行すると環境変数@var{PATH}にYACASL2のディレクトリーが追加されます。
185 @example
186 $ @b{PATH=$PATH:~/yacasl2 && export PATH}
187 @end example
188
189 シェルの初期設定ファイルに上記のコマンドを追加すれば、今後ログインした後は自動的にどのディレクトリーでも @command{casl2}、@command{comet2}、@command{dumpword}を実行できるようになります。BASHの場合はホームディレクトリーにある@file{.bashrc}が初期設定ファイルのため、コマンドは次のようになります。
190 @example
191 $ @b{echo ’PATH=$PATH:~/yacasl2 && export PATH’ >>~/.bashrc}
192 @end example
193
194 @chapter YACASL2 の使い方
195
196 YACASL2 は、テキストファイルに記述されたCASLプログラムを処理します。以下の例で用いられるCASLプログラムのファイルは、テキストエディタなどで作成してください。また、インストールしたディレクトリーの中にある@file{as}ディレクトリーからコピーして作成することもできます。
197
198 @section 実行結果の出力だけを表示
199
200 インストール時にコマンド実行の確認に使った@file{hello.casl}は、次のような内容です。CASL IIのマクロ命令OUTは、文字列を出力します。
201 @example
202 $ @b{cat hello.casl}
203 MAIN     START
204          OUT     OBUF,LEN
205          RET
206 OBUF     DC      ’Hello, World!’
207 LEN      DC      13
208          END
209 @end example
210
211 次のコマンドを実行すると、CASL II のアセンブルと仮想マシン COMET II 上での実行が連続で行われ、文字列が出力されます。
212 @example
213 $ @b{casl2 hello.casl}
214 Hello, World!
215 @end example
216
217 @file{addl.casl}は、3と1の和を求めます。
218
219 @example
220 $ @b{cat addl.casl}
221 ;;; ADDL r,adr
222 MAIN     START
223          LD      GR1,A
224          ADDL    GR1,B
225          RET
226 A        DC      3
227 B        DC      1
228          END
229 @end example
230
231 このプログラムには出力命令がないため、オプションなしで実行した場合には結果が出力されません。
232
233 @example
234 $ @b{casl2 addl.casl}
235 $
236 @end example
237
238 実行内容を確認するには、後述のようにCPU 内にあるレジスターやメモリーの内容を表示するか、結果を出力するための処理を追加する必要があります。
239
240 @file{sum_10.casl}は、1から10までの整数の和を求めます。
241
242 @example
243 $ @b{cat sum_10.casl}
244 ;;; sum_10.casl
245 ;;; 出力 GR0: 1から10までの整数をすべて加算した値
246 MAIN    START
247         PUSH    0,GR1
248         LAD     GR0,0           ; GR0を初期化
249         LD      GR1,FST         ; GR1に初項を転送
250 LOOP    ADDL    GR0,GR1         ; ループ先頭
251         ADDL    GR1,STEP        ; GR1 <- GR1 + 公差
252         CPL     GR1,LST         ; GR1が末項より大きい場合は終了
253         JPL     FIN             ; ↓
254         JUMP    LOOP            ; ループ終端
255 FIN     POP     GR1
256         RET
257 FST     DC      1               ; 初項
258 LST     DC      10              ; 末項
259 STEP    DC      1               ; 公差
260         END
261 @end example
262
263 このプログラムも、オプションなしで実行した場合には結果が出力されません。
264 @example
265 $ @b{casl2 sum_10.casl}
266 $
267 @end example
268
269 @section アセンブル結果の確認
270 casl2の処理途中で行われるアセンブルの結果を表示するには、オプション@option{-a}を指定します。また、ラベルとアドレスの対応表を表示するには、オプション@option{-l}を指定します。
271
272 次のコマンドでは、@file{hello.casl}のラベルとアドレスの対応表と、アセンブル結果と、実行結果が表示されます。OUTはアセンブラ命令で複数の機械語命令で構成されているため、命令行1行に対して、複数行のコードが生成されます。
273
274 @example
275 $ @b{casl2 -a -l hello.casl}
276
277 Assemble hello.casl (0)
278
279 Label::::
280 MAIN.LEN ---> #0020
281 MAIN ---> #0000
282 MAIN.OBUF ---> #0013
283
284 Assemble hello.casl (1)
285 hello.casl:    1:MAIN    START
286 hello.casl:    2:        OUT     OBUF,LEN
287     #0000   #7001
288     #0001   #0000
289     #0002   #7002
290     #0003   #0000
291     #0004   #1210
292     #0005   #0013
293     #0006   #1220
294     #0007   #0020
295     #0008   #F000
296     #0009   #0002
297     #000A   #1210
298     #000B   #0021
299     #0021   #000A
300     #000C   #1220
301     #000D   #0022
302     #0022   #0001
303     #000E   #F000
304     #000F   #0002
305     #0010   #7120
306     #0011   #7110
307 hello.casl:    3:        RET
308     #0012   #8100
309 hello.casl:    4:OBUF    DC      'Hello, World!'
310     #0013   #0048
311     #0014   #0065
312     #0015   #006C
313     #0016   #006C
314     #0017   #006F
315     #0018   #002C
316     #0019   #0020
317     #001A   #0057
318     #001B   #006F
319     #001C   #0072
320     #001D   #006C
321     #001E   #0064
322     #001F   #0021
323 hello.casl:    5:LEN     DC      13
324     #0020   #000D
325 hello.casl:    6:        END
326 Hello, World!
327 @end example
328
329 @file{addl.casl}のラベルとアドレスの対応表と、アセンブル結果は、次のようになります。
330
331 @example
332 $ @b{casl2 -a -l addl.casl}
333
334 Assemble addl.casl (0)
335
336 Label::::
337 MAIN.A ---> #0005
338 MAIN.B ---> #0006
339 MAIN ---> #0000
340
341 Assemble addl.casl (1)
342 addl.casl:    1:;;; ADDL r,adr
343 addl.casl:    2:MAIN    START
344 addl.casl:    3:        LD      GR1,A
345     #0000   #1010
346     #0001   #0005
347 addl.casl:    4:        ADDL    GR1,B
348     #0002   #2210
349     #0003   #0006
350 addl.casl:    5:        RET
351     #0004   #8100
352 addl.casl:    6:A       DC      3
353     #0005   #0003
354 addl.casl:    7:B       DC      1
355     #0006   #0001
356 addl.casl:    8:        END
357 @end example
358
359 なお、オプション@option{-A}を指定すると、アセンブル結果だけが表示され、仮想マシンCOMET II での実行は行われません。
360
361 @section 実行時のレジスターとメモリーを表示
362 YACASL2では実行中のCPUのレジスターとメモリーの内容をそれぞれ、@option{-t}と@option{-d}を指定することで表示できます。
363
364 また、@option{-M}で、仮想マシンCOMET II のメモリー容量を語(16 ビット)単位で指定できます。小さいプログラムを実行するときは、メモリー容量を小さくすれば結果が見やすくなります。
365
366 @file{addl.casl}に必要なメモリー容量は8語のため、次のようにCPUのレジスターとメモリーの内容を表示できます。
367
368 @example
369 $ @b{casl2 -t -d -M8 addl.casl | less}
370
371 Assemble addl.casl (0)
372
373 Assemble addl.casl (1)
374
375 Executing machine codes
376 #0000: Register::::
377 #0000: GR0:      0 = #0000 = 0000000000000000
378 #0000: GR1:      0 = #0000 = 0000000000000000
379 #0000: GR2:      0 = #0000 = 0000000000000000
380 #0000: GR3:      0 = #0000 = 0000000000000000
381 #0000: GR4:      0 = #0000 = 0000000000000000
382 #0000: GR5:      0 = #0000 = 0000000000000000
383 #0000: GR6:      0 = #0000 = 0000000000000000
384 #0000: GR7:      0 = #0000 = 0000000000000000
385 #0000: SP:       8 = #0008 = 0000000000001000
386 #0000: PR:       0 = #0000 = 0000000000000000
387 #0000: FR (OF SF ZF): 000
388 #0000: Memory::::
389 #0000: adr : 0000 0001 0002 0003 0004 0005 0006 0007
390 #0000: 0000: 1010 0005 2210 0006 8100 0003 0001 0000 
391 #0002: Register::::
392 #0002: GR0:      0 = #0000 = 0000000000000000
393 #0002: GR1:      3 = #0003 = 0000000000000011
394 #0002: GR2:      0 = #0000 = 0000000000000000
395 #0002: GR3:      0 = #0000 = 0000000000000000
396 #0002: GR4:      0 = #0000 = 0000000000000000
397 #0002: GR5:      0 = #0000 = 0000000000000000
398 #0002: GR6:      0 = #0000 = 0000000000000000
399 #0002: GR7:      0 = #0000 = 0000000000000000
400 #0002: SP:       8 = #0008 = 0000000000001000
401 #0002: PR:       2 = #0002 = 0000000000000010
402 #0002: FR (OF SF ZF): 000
403 #0002: Memory::::
404 #0002: adr : 0000 0001 0002 0003 0004 0005 0006 0007
405 #0002: 0000: 1010 0005 2210 0006 8100 0003 0001 0000 
406 #0004: Register::::
407 #0004: GR0:      0 = #0000 = 0000000000000000
408 #0004: GR1:      4 = #0004 = 0000000000000100
409 #0004: GR2:      0 = #0000 = 0000000000000000
410 #0004: GR3:      0 = #0000 = 0000000000000000
411 #0004: GR4:      0 = #0000 = 0000000000000000
412 #0004: GR5:      0 = #0000 = 0000000000000000
413 #0004: GR6:      0 = #0000 = 0000000000000000
414 #0004: GR7:      0 = #0000 = 0000000000000000
415 #0004: SP:       8 = #0008 = 0000000000001000
416 #0004: PR:       4 = #0004 = 0000000000000100
417 #0004: FR (OF SF ZF): 000
418 #0004: Memory::::
419 #0004: adr : 0000 0001 0002 0003 0004 0005 0006 0007
420 #0004: 0000: 1010 0005 2210 0006 8100 0003 0001 0000 
421 @end example
422
423 @subsection 特定のレジスターを表示
424
425 @file{addl.casl}のレジスターやメモリーの中で、実行中に値が変化しているのはGR1だけです。こうした場合は、@command{grep}を使って表示される内容を絞り込むことで動作を検証しやすくなります。
426
427 @example
428 $ @b{casl2 -t addl.casl | grep 'GR1:'}
429 #0000: GR1:      0 = #0000 = 0000000000000000
430 #0002: GR1:      3 = #0003 = 0000000000000011
431 #0004: GR1:      4 = #0004 = 0000000000000100
432 @end example
433
434 ここで、先に実行した@file{addl.casl}のアセンブル結果をもう一度見てください。
435 次の表のように、PRとGR1、命令行が対応していることがわかります。
436
437 @multitable @columnfractions .3 .3 .4
438 @item PR @tab GR1 @tab 命令行
439 @item #0000
440 @tab #0000
441 @item #0002
442 @tab #0003
443 @tab @code{LD GR1,A}
444 @item #0004
445 @tab #0004
446 @tab @code{ADDL GR1,B}
447 @end multitable
448
449 @subsection プログラム終了時の値を表示
450
451 @command{grep}と@command{tail}を組み合わせれば、プログラム終了時の値を表示できます。
452
453 @example
454 $ @b{casl2 -t addl.casl | grep 'GR1:' | tail -1}
455 #0004: GR1:      4 = #0004 = 0000000000000100
456 @end example
457
458 @example
459 $ @b{casl2 -t sum_10.casl | grep 'GR0:' | tail -1}
460 #0010: GR0:     55 = #0037 = 0000000000110111 = '7'
461 @end example
462
463 @subsection プログラムのステップ数を表示
464
465 @command{grep}と@command{wc}を組み合わせれば、プログラムのステップ数を表示できます。
466
467 @example
468 $ @b{casl2 -t hello.casl | grep 'GR1:' | wc -l}
469 11
470 @end example
471
472 @example
473 $ @b{casl2 -t addl.casl | grep 'GR1:' | wc -l}
474 3
475 @end example
476
477 @file{sum_10.casl}はプログラム内にループがあるため、ステップ数が大きくなります。
478
479 @example
480 $ @b{casl2 -t sum_10.casl | grep 'GR0:' | wc -l}
481 54
482 @end example
483
484 @section アセンブルと実行を別に行う
485
486 @bye