rasl

CASL Assembler / Simulator


Keywords
assembler, casl, casl2, language, simulator
License
MIT
Install
gem install rasl -v 0.0.1

Documentation

CASL Assembler / Simulator

require "rasl"

app = Rasl::Processor.new
app.assemble <<-SOURCE
MAIN    START
        LD      GR0,=1
        LD      GR1,=2
        ADDA    GR0,GR1
        ST      GR0,RESULT
        RET
RESULT  DS      1
        END
SOURCE
app.go
app.gr[:gr0].value                       # => 3
app.labels["MAIN"]                       # => {"RESULT"=>8}
app.memory[app.labels["MAIN"]["RESULT"]] # => 3
puts app.disassemble
# >> 0000 1000 0009    LD      GR0, #0009
# >> 0002 1010 000A    LD      GR1, #000A
# >> 0004 2401         ADDA    GR0, GR1
# >> 0005 1100 0008    ST      GR0, #0008
# >> 0007 8100         RET
# >> 0008 0003         DC      3
# >> 0009 0001         DC      1
# >> 000A 0002         DC      2

仕様

  • プロシージャ
    • START〜END は複数定義可
    • START に前置するラベルは必須ではない
    • START と END は省略可
    • 最初に登場した START の引数をブートアドレスにする
  • ラベル
    • STARTに前置したラベルはグローバルラベル
    • STARTのあとからENDまではローカルラベル
    • ラベルの文字数制限なし
    • ラベルの最後にコロンをつけてもよい (ラベルに含まない)
    • ラベルの最後にコロンをつけると必ずラベルになる (NOP: と書いたら NOP は命令ではなくラベルとみなす)
    • ラベルの先頭に $ や @ をつけてもよい (ラベルに含む)
    • $ で始まるラベルは必ずグローバルラベルになる
    • ラベルだけの行を書いてもよい
    • ラベルは大小文字を区別する
    • START〜ENDを書かなかった場合のラベルはすべてグローバルラベル
  • 構文
    • スペースを空けずに命令を書いてもよい (Rasl.config.bol_order = false で無効になる)
    • 引数のセパレーターはスペースでもいい
    • インライン即値の部分は “= 1” のようにスペースを空けてもよい
    • 文字列はダブルクォーテーションで囲んでもいい
    • 行頭からだけ # でコメントにできる。shebang 用
  • その他
    • CASL1 と CASL2 に対応
    • インライン即値はENDの直前に定義する。END がなければコードの最後に定義する
    • EXIT で終了してもよい
    • GRn を n とは書けない (CASL2ではアドレスとレジスタの区別がつかないため)
    • NOP は #00 にはしてない (データなのか命令なのかまぎらわしいので)
    • GRn の他に FR PC SP レジスタを指定できる (例: addl SP, 1 など)
    • Rasl.config.spec = 1 にすると GR4 が SP になる
  • 注意
    • 文字コードは UTF-8 なので DC ‘あ’ は DS 3 の領域を使う
    • 文字列リテラルの中だろうとセミコロン以降をぶっちぎる。 ‘a;b’ の場合 ‘a となるため \ でエスケープして ‘a\;b’ と書く

コマンドラインで使う例

–help

$ rasl --help
CASL Assembler / Simulator rasl 0.0.1
使い方: rasl [OPTIONS] [ファイル]
    -s, --simulator                  シミュレータ起動
    -p, --print-map                  MAP情報の標準出力
    -m, --output-map                 MAP情報のファイル出力。-g オプションがあるときは実行後に出力する
    -g, --go                         実行
    -e, --eval=CODE                  指定コードの評価。指定があると標準入力からは読み込まない
        --memory-size=SIZE           メモリサイズの指定(デフォルト:65536)
        --spec=NUMBER                1:レジスタ数5個でGR4==SP 2:レジスタ数8 GR4!=SP
        --ds-init-value=VAL          DSで領域確保したときの初期値(デフォルト:0)
        --memory-defval=VAL          メモリの初期値(デフォルト:0)
        --[no-]bol-order             命令の前に空白を書かなくてよいことにする(デフォルト:true)
    -i, --register                   実行後レジスタ一覧表示

MAP情報の標準出力 (-p)

$ rasl -p hello.csl
0000 7001 0000    PUSH    #0000, GR1
0002 7002 0000    PUSH    #0000, GR2
0004 1210 000D    LAD     GR1, #000D
0006 1220 0018    LAD     GR2, #0018
0008 F000 0001    SVC     #0001
000A 7120         POP     GR2
000B 7110         POP     GR1
000C 8100         RET
000D 0048         DC      72     ; 'H'
000E 0065         DC      101    ; 'e'
000F 006C         DC      108    ; 'l'
0010 006C         DC      108    ; 'l'
0011 006F         DC      111    ; 'o'
0012 000B         DC      5

MAP情報のファイル出力 (-m)

$ rasl -m hello.csl
$ cat hello.map
0000 7001 0000    PUSH    #0000, GR1
0002 7002 0000    PUSH    #0000, GR2
0004 1210 000D    LAD     GR1, #000D
0006 1220 0018    LAD     GR2, #0018
0008 F000 0001    SVC     #0001
000A 7120         POP     GR2
000B 7110         POP     GR1
000C 8100         RET
000D 0048         DC      72     ; 'H'
000E 0065         DC      101    ; 'e'
000F 006C         DC      108    ; 'l'
0010 006C         DC      108    ; 'l'
0011 006F         DC      111    ; 'o'
0012 000B         DC      5

指定コードの評価 (-e)

$ rasl -p -e 'LEA GR1,1,GR1'
0000 1F11 0001    LEA     GR1, #0001, GR1

標準入力から渡してもよい

$ echo 'LEA GR1,1,GR1' | rasl -p
0000 1F11 0001    LEA     GR1, #0001, GR1

実行 (-g)

$ rasl -g hello.csl
Hello

Simulator (-s)

$ rasl -s hello.csl
-?
D[address]    memory-dump
U[address]    unassemble
G[address]    go
T[address]    trace
R[reg=n]      register
? or H        usage
I             init
Q             quit
-r
GR0=0000 GR1=0000 GR2=0000 GR3=0000 GR4=0000 GR5=0000 GR6=0000 GR7=0000 PC=0000 SP=FFFF FR=___(+)
0000 7001 0000    PUSH    #0000, GR1
-t
GR0=0000 GR1=0000 GR2=0000 GR3=0000 GR4=0000 GR5=0000 GR6=0000 GR7=0000 PC=0002 SP=FFFE FR=___(+)
0002 7002 0000    PUSH    #0000, GR2
-t
GR0=0000 GR1=0000 GR2=0000 GR3=0000 GR4=0000 GR5=0000 GR6=0000 GR7=0000 PC=0004 SP=FFFD FR=___(+)
0004 1210 000D    LAD     GR1, #000D
-u
0000 7001 0000    PUSH    #0000, GR1
0002 7002 0000    PUSH    #0000, GR2
0004 1210 000D    LAD     GR1, #000D
0006 1220 0012    LAD     GR2, #0012
0008 F000 0001    SVC     #0001
000A 7120         POP     GR2
000B 7110         POP     GR1
000C 8100         RET
-g
Hello
-d0
0000: 7001 0000 7002 0000 1210 000D 1220 0012 ........
0008: F000 0001 7120 7110 8100 0048 0065 006C .....Hel
0010: 006C 006F 0005 0000 0000 0000 0000 0000 lo......
0018: 0000 0000 0000 0000 0000 0000 0000 0000 ........
-q

IN 命令時の __END__

デフォルトでは標準入力待ちになるが __END__ の指定があればその次の行からを入力データとして扱う

$ cat in_out.csl
        START
        IN      STR,LEN  ; STR="a" LEN=1
        OUT     STR,LEN  ; => "a"
        IN      STR,LEN  ; STR=""  LEN=0
        OUT     STR,LEN  ; => ""
        IN      STR,LEN  ; STR="b" LEN=1
        OUT     STR,LEN  ; => "b"
        IN      STR,LEN  ; STR=""  LEN=-1
        OUT     STR,LEN  ; => なし
        RET
STR     DS      4
LEN     DS      1
        END
__END__
a

b
$ rasl -g in_out.csl
a

b

とりあえずのEmacs設定

(add-to-list 'auto-mode-alist '("\\.\\([rc]asl?\\|csl\\)$" . asm-mode))

参考