MikeAssembler リファレンス - GMC-4

アーキテクチャ名

nlp16

概要

NLP-16は、ちぇりーたくあん様が開発したNAND(74HC00)だけで作る16bitCPUである。

NAND(74HC00)だけで16bitCPUを作る[NLP-16]

レジスタ

NLP-16は、以下のレジスタを持つ。
「名前」はMikeAssemblerのオペランドで用いる名前であり、大文字・小文字は区別しない。

名前ID説明
ir10IR1
ir21IR2
ir33IR3
flag4Flag
a5RegA
b6RegB
c7RegC
d8RegD
e9RegE (Serial I/O)
serial9RegE (Serial I/O)
ram10RAM (Device)
device10RAM (Device)
ua11Upper Address
la12Lower Address
ip13Program pointer
sp14Stack pointer
zero15Zero register

出典

レジスタも即値も指定できるオペランドにおいてレジスタ名が指定された場合、レジスタとして扱う。
例えば識別子aの値を即値として用いたい場合は、+aなどとする。

命令セット

条件実行

命令の後ろに以下の接尾辞をつけることで、実行する条件(Flagフィールド)を指定できる。
大文字・小文字は区別しない。

接尾辞実行する条件
_nopNOP
_cCが立っているときに実行
_vVが立っているときに実行
_zZが立っているときに実行
_sSが立っているときに実行
(なし)常に実行
_ncCが立っていないときに実行
_nvVが立っていないときに実行
_nzZが立っていないときに実行
_nsSが立っていないときに実行

即値サイズ指定

MikeAssemblerは、通常は即値の大きさに応じて自動で8bitか16bitかを決定する。
命令の後ろに8をつけると、強制的に8bit即値を用いる。
命令の後ろに16をつけると、強制的に16bit即値を用いる。
これらは、実行する条件を表す接尾辞を用いる場合はその前に指定する。
例えば、16bit即値を用い、Cが立っているときに実行するADD命令は add16_c a, b, 10 のように書く。

即値を2個用いる場合、通常は8bit即値と16bit即値の両方を用いる。
この指定を行うと2個とも同じ即値を用い、値が違う場合はエラーとなる。

命令セット

MikeAssemblerでは、以下の命令に対応している。
命令の大文字・小文字は区別しない。

演算命令
命令意味
add 出力先, 入力A, 入力BADD
sub 出力先, 入力A, 入力BSUB
addc 出力先, 入力A, 入力BADD with carry
subc 出力先, 入力A, 入力BSUB with carry
or 出力先, 入力A, 入力BOR
not 出力先, 入力ANOT
xor 出力先, 入力A, 入力BXOR
and 出力先, 入力A, 入力BAND
inc 出力先, 入力AINC
dec 出力先, 入力ADEC
incc 出力先, 入力AINC with carry
decc 出力先, 入力ADEC with carry
slr 出力先, 入力ASLR
sll 出力先, 入力ASLL
sar 出力先, 入力ASAR
sal 出力先, 入力ASAL
ror 出力先, 入力AROR
rol 出力先, 入力AROL
転送命令
命令意味
mov 転送先, 転送元/即値MOV / 即値代入
JMP命令
命令意味
jmp レジスタ/即値8bit絶対番地 / 16bit絶対番地 / レジスタ間接
jmpr アドレス(即値)自己相対(加算/減算)
加算か減算かはアドレスに応じて自動で決定する。
レジスタや生の即値をオペランドとするには、jmpadd/jmpsubの入力Aをipにする。
jmpadd 入力A, 入力Bレジスタ同士で計算して指定(加算)
jmpsub 入力A, 入力Bレジスタ同士で計算して指定(減算)
スタック操作
命令意味
push PUSH元RegPUSH
pop POP先RegPOP
サブルーチン命令
命令意味
call レジスタ/即値CALL 8bit絶対番地 / 16bit絶対番地 / レジスタ間接
callr アドレス(即値)CALL 自己相対(加算/減算)
加算か減算かはアドレスに応じて自動で決定する。
レジスタや生の即値をオペランドとするには、calladd/callsubの入力Aをipにする。
calladd 入力A, 入力BCALL レジスタ同士で計算して指定(加算)
callsub 入力A, 入力BCALL レジスタ同士で計算して指定(減算)
retRET
iret割り込みRET
メモリ操作
命令意味
load LOAD先, レジスタ/即値LOAD 8bit絶対番地 / 16bit絶対番地 / レジスタ間接
loadr LOAD先, アドレス(即値)LOAD 自己相対(加算/減算)
加算か減算かはアドレスに応じて自動で決定する。
レジスタや生の即値をオペランドとするには、loadadd/loadsubの入力Aをipにする。
loadadd LOAD先, 入力A, 入力BLOAD レジスタ同士で計算して指定(加算)
loadsub LOAD先, 入力A, 入力BLOAD レジスタ同士で計算して指定(減算)
store STORE元, レジスタ/即値STORE 8bit絶対番地 / 16bit絶対番地 / レジスタ間接
storer STORE元, アドレス(即値)STORE 自己相対(加算/減算)
加算か減算かはアドレスに応じて自動で決定する。
レジスタや生の即値をオペランドとするには、storeadd/storesubの入力Aをipにする。
storeadd STORE元, 入力A, 入力BSTORE レジスタ同士で計算して指定(加算)
storesub STORE元, 入力A, 入力BSTORE レジスタ同士で計算して指定(減算)
比較命令
命令意味
cmp 入力A, 入力BCMP
疑似命令
命令意味
nop1ワードのNOP (ret_nop)
実行する条件の指定・即値サイズ指定には対応しない。
worddata 値 [, 値 [, ...]]指定の値を各2バイトで順に配置する。
実行する条件の指定・即値サイズ指定には対応しない。
文字列データの配置には対応しない。

命令のフォーマットやオペコードは、以下を参照のこと。

アドレスについて

NLP-16ではワード(2バイト)単位のアドレスを扱う一方、MikeAssemblerではバイト単位のアドレスを扱う。
そこで、NLP-16固有の命令においては、ラベルの値を自動的に2で割り、ワード単位に変換する。
ラベルの値が奇数の場合はエラーとなる。
なお、defineで定義した識別子は変換しない。

一方、orgdefinedata系などのMikeAssembler共通の疑似命令においては、この変換を行わない。
そのため、以下の対応が必要である。

なお、worddata 疑似命令はNLP-16固有であり、この明示的な変換は不要である。

サンプルプログラム

target nlp16

	; ラベルが自動でワード単位のアドレスに変換される
	load a, data_label

	; ラベルは自動で変換されるが、置かれているデータは変換されない
	load b, addr_label
	; bに格納したアドレス (data_label) から読み込む
	load c, b

addr_label:
	; ラベルを明示的に2で割ってワード単位のアドレスに変換する
	dataw data_label / 2

data_label:
	dataw 0

戻る