c7d1bff1e27d821532cec01849fb0f375a7e9874
[YACASL2.git] / doc / yacasl2.texi
1 \input texinfo   @c -*-texinfo-*-
2 @c %**start of header
3 @setfilename yacasl2.info
4 @settitle YACASL2 - Linux上のCASL II処理系
5 @c %**end of header
6
7 @copying
8 Copyright @copyright{} 2010 j8takagi
9 @end copying
10
11 @exampleindent 2
12
13 @dircategory Basics
14 @direntry
15 * YACASL2: (yacasl2).
16 @end direntry
17
18 @titlepage
19 @title YACASL2
20 @subtitle Linux上のCASL II処理系
21 @author j8takagi
22 @insertcopying
23 @end titlepage
24
25 @ifnottex
26 @node Top
27 @end ifnottex
28
29 @menu
30 * YACASL2の概要::
31 * YACASL2のインストール::
32 * YACASL2の使い方::
33 @end menu
34
35 @contents
36
37 @node YACASL2の概要, YACASL2のインストール, Top, Top
38 @chapter YACASL2の概要
39
40 YACASL2は、Linux上で動作するオープンソースのCASL II処理系です。CASL IIは情報処理試験で用いられるアセンブラ言語で、次の資料により仕様が公開されています。
41
42 @quotation
43 @uref{http://www.jitec.ipa.go.jp/1_00topic/topic_20081027_hani_yougo.pdf, 試験で使用する情報処理用語・プログラム言語など(2008年10月版)}[PDFファイル]
44 別紙 1 アセンブラ言語の仕様
45 @end quotation
46
47 YACASL2は、CASL IIアセンブラ言語で記述されたファイルをアセンブルし、仮想マシンCOMET II上で実行します。アセンブルと実行は、連続で行うことも別々に行うことも可能です。
48 YACASL2の動作はCASL IIの仕様に準拠しているため、情報処理試験の問題をはじめ各種参考書やサイトに記載されたCASL IIのプログラムをそのままアセンブルして実行できます。また、本パッケージ中にCASL IIのサンプルプログラムが多数収録されています。
49
50 YACASL2は、「ふつうの処理系」として動作します。ほかの多くのCASL IIエミュレーターと違い、デバッガーとして動作したり、コンピューター内部の模式図を表示したりすることはありません。そのかわり、YACASL2は、次のような動作内容をすべてテキストで出力します。
51
52 @itemize @bullet
53
54 @item
55 ラベルとアドレスの対応
56
57 @item
58 アセンブル結果
59
60 @item
61 実行時のレジスタの内容
62
63 @item
64 実行時のメモリの内容
65 @end itemize
66
67 出力された動作内容は、GNU/Linuxのさまざまなツール、たとえば@command{cat}、@command{less}、@command{grep}、@command{wc}などを使って解析できます。
68
69 @unnumberedsec 要件
70 YACASL2は、Linux上で動作します。現在動作を確認しているのは、次のディストリビューションです。
71
72 @itemize @bullet
73
74 @item
75 Ubuntu Linux 9.04 / 8.04
76
77 @item
78 Vine Linux 4.2
79 @end itemize
80
81 インストール時に、@command{tar}、@command{gcc}、@command{make}が必要です。
82
83 @node YACASL2のインストール, YACASL2の使い方, YACASL2の概要, Top
84 @chapter YACASL2のインストール
85 YACASL2をインストールするには、Linux上で次の作業をします。
86
87 @enumerate
88
89 @item
90 @file{yacasl2.tar.gz}のダウンロード
91
92 @item
93 @file{yacasl2.tar.gz}の検証
94
95 @item
96 @file{yacasl2.tar.gz}の展開
97
98 @item
99 @command{casl2}、@command{comet2}、@command{dumpword}のビルド
100
101 @item
102 @command{casl2}の実行テスト
103
104 @item
105 詳細なテスト
106
107 @item
108 環境変数@var{PATH}の設定
109 @end enumerate
110
111 以下の操作は、端末を開きコマンドを実行します。
112
113 @section @file{yacasl2.tar.gz}のダウンロード
114 (詳細未定)
115
116 @cartouche
117 @example
118 $ @command{cd}
119 $ @command{wget somewhere/yacasl2.tar.gz}
120 $ @command{wget somewhere/yacasl2.tar.gz.md5sum}
121 @end example
122 @end cartouche
123
124 @section @file{yacasl2.tar.gz}の検証
125
126 (PGPを使った検証も導入予定)
127
128 ダウンロードが完了したら、@command{md5sum}と@command{diff}で正しくファイルがダウンロードができているかを検証します。
129
130 @cartouche
131 @example
132 $ @command{md5sum yacasl2.tar.gz | diff -s yacasl2.tar.gz.md5sum -}
133 Files yacasl2.tar.gz.md5sum and - are identical
134 @end example
135 @end cartouche
136
137 @section @file{yacasl2.tar.gz}の展開
138
139 @file{yacasl2.tar.gz}をダウンロードしたら、次のコマンドで展開します。
140
141 @cartouche
142 @example
143 $ @command{tar xvzf yacasl2.tar.gz}
144 @end example
145 @end cartouche
146
147 @section @command{casl2}、@command{comet2}、@command{dumpword}のビルド
148
149 展開したら、次のコマンドで@command{casl2}、@command{comet2}、@command{dumpword}をビルドします。
150
151 @cartouche
152 @example
153 $ @command{cd yacasl2}
154 $ @command{make}
155 make -C src
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’
177 @end example
178 @end cartouche
179
180 @section @command{casl2}の実行テスト
181
182 ビルドしたら、次のコマンドが正常に実行できるかを確認します。
183 正常に実行された場合は、「Hello, World!」と表示されます。
184
185 @cartouche
186 @example
187 $ @command{./casl2 as/hello.casl}
188 Hello, World!
189 @end example
190 @end cartouche
191
192 @section 詳細なテスト
193
194 次のコマンドを実行すると、正常にビルドできているかどうかを詳細にテストできます。
195
196 @cartouche
197 @example
198 $ @command{make check}
199 194 / 194 tests passed. Details in /home/kazubito/yacasl2/test/integra
200 tion/casl2/Test.log
201 All tests are succeded.
202 149 / 149 tests passed. Details in /home/kazubito/yacasl2/test/integra
203 tion/comet2/Test.log
204 All tests are succeded.
205 4 / 4 tests passed. Details in /home/kazubito/yacasl2/test/integration
206 /dumpword/Test.log
207 All tests are succeded.
208 @end example
209 @end cartouche
210
211 @section 環境変数@var{PATH}の設定
212
213 環境変数@var{PATH}にYACASL2のディレクトリーを追加すると、どのディレクトリーでも@command{casl2}、@command{comet2}、@command{dumpword}を実行できます。
214
215 環境変数の設定方法は使っているシェルによって異なります。シェルは、次のコマンドで確認できます。
216
217 @cartouche
218 @example
219 $ @command{echo $SHELL}
220 /bin/bash
221 @end example
222 @end cartouche
223
224 現在もっとも多く使われているシェルは、BASHでしょう。BASHでは、次のコマンドを実行すると環境変数@var{PATH}にYACASL2のディレクトリーが追加されます。
225
226 @cartouche
227 @example
228 $ @command{PATH=$PATH:~/yacasl2 && export PATH}
229 @end example
230 @end cartouche
231
232 シェルの初期設定ファイルに上記のコマンドを追加すれば、今後ログインした後は自動的にどのディレクトリーでも @command{casl2}、@command{comet2}、@command{dumpword}を実行できます。BASHではホームディレクトリーにある@file{.bashrc}が初期設定ファイルのため、次のコマンドで追加されます。
233
234 @cartouche
235 @example
236 $ @command{echo ’PATH=$PATH:~/yacasl2 && export PATH’ >>~/.bashrc}
237 @end example
238 @end cartouche
239
240 @node YACASL2の使い方,, YACASL2のインストール, Top
241 @chapter YACASL2 の使い方
242 YACASL2 は、テキストファイルに記述されたCASLプログラムを処理します。以下の例で用いられるCASLプログラムのファイルは、テキストエディタなどで作成してください。また、インストールしたディレクトリーの中にある@file{as}ディレクトリーからコピーして作成することもできます。
243
244 @section 実行結果の出力だけを表示
245
246 インストール時にコマンド実行の確認に使った@file{hello.casl}は、次のような内容です。CASL IIのマクロ命令OUTは、文字列を出力します。
247
248 @cartouche
249 @example
250 $ @command{cat hello.casl}
251 MAIN     START
252          OUT     OBUF,LEN
253          RET
254 OBUF     DC      ’Hello, World!’
255 LEN      DC      13
256          END
257 @end example
258 @end cartouche
259
260 次のコマンドを実行すると、CASL II のアセンブルと仮想マシン COMET II 上での実行が連続で行われ、文字列が出力されます。
261
262 @cartouche
263 @example
264 $ @command{casl2 hello.casl}
265 Hello, World!
266 @end example
267 @end cartouche
268
269 @file{addl.casl}は、3と1の和を求めます。
270
271 @cartouche
272 @example
273 $ @command{cat addl.casl}
274 ;;; ADDL r,adr
275 MAIN     START
276          LD      GR1,A
277          ADDL    GR1,B
278          RET
279 A        DC      3
280 B        DC      1
281          END
282 @end example
283 @end cartouche
284
285 このプログラムには出力命令がないため、オプションなしで実行した場合には結果が出力されません。
286
287 @cartouche
288 @example
289 $ @command{casl2 addl.casl}
290 $
291 @end example
292 @end cartouche
293
294 実行内容を確認するには、後述のようにCPU 内にあるレジスターやメモリーの内容を表示するか、結果を出力するための処理を追加する必要があります。
295
296 @file{sum_10.casl}は、1から10までの整数の和を求めます。
297
298 @cartouche
299 @example
300 $ @command{cat sum_10.casl}
301 ;;; sum_10.casl
302 ;;; 出力 GR0: 1から10までの整数をすべて加算した値
303 MAIN    START
304         PUSH    0,GR1
305         LAD     GR0,0           ; GR0を初期化
306         LD      GR1,FST         ; GR1に初項を転送
307 LOOP    ADDL    GR0,GR1         ; ループ先頭
308         ADDL    GR1,STEP        ; GR1 <- GR1 + 公差
309         CPL     GR1,LST         ; GR1が末項より大きい場合は終了
310         JPL     FIN             ; ↓
311         JUMP    LOOP            ; ループ終端
312 FIN     POP     GR1
313         RET
314 FST     DC      1               ; 初項
315 LST     DC      10              ; 末項
316 STEP    DC      1               ; 公差
317         END
318 @end example
319 @end cartouche
320
321 このプログラムも、オプションなしで実行した場合には結果が出力されません。
322 @cartouche
323 @example
324 $ @command{casl2 sum_10.casl}
325 $
326 @end example
327 @end cartouche
328
329 @section アセンブル結果の確認
330 casl2の処理途中で行われるアセンブルの結果を表示するには、オプション@option{-a}を指定します。また、ラベルとアドレスの対応表を表示するには、オプション@option{-l}を指定します。
331
332 次のコマンドでは@file{hello.casl}の、ラベルとアドレスの対応表と、アセンブル結果と、実行結果が表示されます。OUTはアセンブラ命令で複数の機械語命令で構成されているため、命令行1行に対して、複数行のコードが生成されます。
333
334 @cartouche
335 @example
336 $ @command{casl2 -a -l hello.casl}
337
338 Assemble hello.casl (0)
339
340 Label::::
341 MAIN.LEN ---> #0020
342 MAIN ---> #0000
343 MAIN.OBUF ---> #0013
344
345 Assemble hello.casl (1)
346 hello.casl:    1:MAIN    START
347 hello.casl:    2:        OUT     OBUF,LEN
348     #0000   #7001
349     #0001   #0000
350     #0002   #7002
351     #0003   #0000
352     #0004   #1210
353     #0005   #0013
354     #0006   #1220
355     #0007   #0020
356     #0008   #F000
357     #0009   #0002
358     #000A   #1210
359     #000B   #0021
360     #0021   #000A
361     #000C   #1220
362     #000D   #0022
363     #0022   #0001
364     #000E   #F000
365     #000F   #0002
366     #0010   #7120
367     #0011   #7110
368 hello.casl:    3:        RET
369     #0012   #8100
370 hello.casl:    4:OBUF    DC      'Hello, World!'
371     #0013   #0048
372     #0014   #0065
373     #0015   #006C
374     #0016   #006C
375     #0017   #006F
376     #0018   #002C
377     #0019   #0020
378     #001A   #0057
379     #001B   #006F
380     #001C   #0072
381     #001D   #006C
382     #001E   #0064
383     #001F   #0021
384 hello.casl:    5:LEN     DC      13
385     #0020   #000D
386 hello.casl:    6:        END
387 Hello, World!
388 @end example
389 @end cartouche
390
391 @file{addl.casl}の、ラベルとアドレスの対応表と、アセンブル結果は、次のようになります。
392
393 @cartouche
394 @example
395 $ @command{casl2 -a -l addl.casl}
396
397 Assemble addl.casl (0)
398
399 Label::::
400 MAIN.A ---> #0005
401 MAIN.B ---> #0006
402 MAIN ---> #0000
403
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
408     #0000   #1010
409     #0001   #0005
410 addl.casl:    4:        ADDL    GR1,B
411     #0002   #2210
412     #0003   #0006
413 addl.casl:    5:        RET
414     #0004   #8100
415 addl.casl:    6:A       DC      3
416     #0005   #0003
417 addl.casl:    7:B       DC      1
418     #0006   #0001
419 addl.casl:    8:        END
420 @end example
421 @end cartouche
422
423 なお、オプション@option{-A}を指定すると、アセンブル結果が表示される時点で処理が終了します。仮想マシンCOMET II での実行は行われません。
424
425 @section 実行時のレジスターとメモリーを表示
426 YACASL2では実行中のCPUのレジスターとメモリーの内容をそれぞれ、@option{-t}と@option{-d}を指定することで表示できます。
427
428 また、@option{-M}で、仮想マシンCOMET II のメモリー容量を語(16 ビット)単位で指定できます。小さいプログラムを実行するときは、メモリー容量を小さくすれば結果が見やすくなります。
429
430 @file{addl.casl}に必要なメモリー容量は8語のため、次のようにCPUのレジスターとメモリーの内容を表示できます。
431
432 @cartouche
433 @example
434 $ @command{casl2 -t -d -M8 addl.casl | less}
435
436 Assemble addl.casl (0)
437
438 Assemble addl.casl (1)
439
440 Executing machine codes
441 #0000: Register::::
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
453 #0000: Memory::::
454 #0000: adr : 0000 0001 0002 0003 0004 0005 0006 0007
455 #0000: 0000: 1010 0005 2210 0006 8100 0003 0001 0000 
456 #0002: Register::::
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
468 #0002: Memory::::
469 #0002: adr : 0000 0001 0002 0003 0004 0005 0006 0007
470 #0002: 0000: 1010 0005 2210 0006 8100 0003 0001 0000 
471 #0004: Register::::
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
483 #0004: Memory::::
484 #0004: adr : 0000 0001 0002 0003 0004 0005 0006 0007
485 #0004: 0000: 1010 0005 2210 0006 8100 0003 0001 0000 
486 @end example
487 @end cartouche
488
489 @subsection 特定のレジスターを表示
490
491 @file{addl.casl}のレジスターやメモリーの中で、実行中に値が変化しているのはGR1だけです。こうした場合は、@command{grep}を使って表示される内容を絞り込むことで動作を検証しやすくなります。
492
493 @cartouche
494 @example
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
499 @end example
500 @end cartouche
501
502 この内容を、先に出力したアセンブル結果と引き比べてください。
503 次の表のように、PRとGR1、命令行が対応していることがわかります。
504
505 @multitable @columnfractions .3 .3 .4
506 @item PR @tab GR1 @tab 命令行
507 @item #0000
508 @tab #0000
509 @item #0002
510 @tab #0003
511 @tab @code{LD GR1,A}
512 @item #0004
513 @tab #0004
514 @tab @code{ADDL GR1,B}
515 @end multitable
516
517 @subsection プログラム終了時の値を表示
518
519 @command{grep}と@command{tail}を組み合わせれば、プログラム終了時の値を表示できます。
520
521 @cartouche
522 @example
523 $ @command{casl2 -t addl.casl | grep 'GR1:' | tail -1}
524 #0004: GR1:      4 = #0004 = 0000000000000100
525 @end example
526 @end cartouche
527
528 @cartouche
529 @example
530 $ @command{casl2 -t sum_10.casl | grep 'GR0:' | tail -1}
531 #0010: GR0:     55 = #0037 = 0000000000110111 = '7'
532 @end example
533 @end cartouche
534
535 @subsection プログラムのステップ数を表示
536
537 @command{grep}と@command{wc}を組み合わせれば、プログラムのステップ数を表示できます。
538
539 @cartouche
540 @example
541 $ @command{casl2 -t hello.casl | grep 'GR1:' | wc -l}
542 11
543 @end example
544 @end cartouche
545
546 @cartouche
547 @example
548 $ @command{casl2 -t addl.casl | grep 'GR1:' | wc -l}
549 3
550 @end example
551 @end cartouche
552
553 @file{sum_10.casl}はプログラム内にループがあるため、ステップ数が大きくなります。
554
555 @cartouche
556 @example
557 $ @command{casl2 -t sum_10.casl | grep 'GR0:' | wc -l}
558 54
559 @end example
560 @end cartouche
561
562 @section アセンブルと実行を別に行う
563
564 @command{casl2}に@option{-O}@file{ファイル名}を指定すると、オブジェクトファイルを作成できます。
565
566 @cartouche
567 @example
568 $ @command{casl2 -Ohello.o hello.casl}
569 @end example
570 @end cartouche
571
572 作成されたオブジェクトファイルの内容は、@command{od}を使って確認できます。テキストファイルではないため、@command{cat}などでは確認できません。
573
574 @cartouche
575 @example
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
582 0000106
583 @end example
584 @end cartouche
585
586 オブジェクトファイルの実行には、@command{comet2}を使います。
587
588 @cartouche
589 @example
590 $ @command{comet2 hello.o}
591 Hello, World!
592 @end example
593 @end cartouche
594
595 @section 1語を解析する
596
597 CASL2では、1語(16ビット)を単位としてデータが処理されます。
598 @command{dumpword}は、指定した1語を10進数、16進数、2進数で表示します。
599
600 @cartouche
601 @example
602 $ @command{dumpword 72}
603     72:     72 = #0048 = 0000000001001000 = 'H'
604 @end example
605 @end cartouche
606
607 マイナスの数は、次のように指定します。
608
609 @cartouche
610 @example
611 $ @command{dumpword} @verb{|--|} @command{-72}
612    -72:    -72 = #FFB8 = 1111111110111000
613 @end example
614 @end cartouche
615
616 16進数で指定する場合は、次のように指定します。
617
618 @cartouche
619 @example
620 $ @command{dumpword '#0048'}
621  #0048:     72 = #0048 = 0000000001001000 = 'H'
622 @end example
623 @end cartouche
624 @bye