公開日:2026/04/11
title.png

38th Season


#38-9 週刊「スタックマシンを作る」付録

 このページは、本HPで作成したオリジナル極小CPUコアSamariumの命令セットマニュアルです。
 詳細については、以下リンクから本文を参照してください。

 本文へ戻る


Samarium Instruction Set Manual

Samarium CPUコア概要

 Samariumは、極小の16ビットCPUコアです。ハーバードアーキテクチャを採用したスタックマシンであり、命令コードを8ビットフェッチバスから読み込んで実行します。16ビットのメモリバスを通して、CPU外部のRAMやI/Oユニット(メモリマップドI/O)などのリソースにアクセスすることが出来ます。
 フェッチバス、メモリバス共、16ビットアドレスを持っており、従ってメモリ空間は最大64Kバイトです。

 Samariumは8ビットの命令コードを持ったスタックマシンです。
 Samariumと言う名称は、スタックマシン(Stack Machine)の頭文字Smを元素記号とするサマリウムに由来します。サマリウムは、原子番号62、希土類元素、ランタノイド、放射性物質、α崩壊でNd(Neodymium)になる、等の特長を持っています。

 スタックポインタsp並びにプログラムカウンタpcはリセット信号で0x0000に初期化されるので、Samariumリセット解除後、常に0x0000番地の命令から実行を開始します。

割り込み

 CPU最上位のIRQ信号がアサートされると、割り込みを受け付けることができます。
 CPU内部に割り込みベクタivと、割り込み許可IEビットを持っています。
 CPUのリセット解除後、Iv=0x0000、IE=0で初期化されていて、割り込みが禁止された状態なので、IRQがアサートされても、CPUが割り込みを受け付ける事はありません。

 ijal命令(別名setiv命令)を実行して、有効な割り込みサービスルーチン(ISR;Interrupt Service Routine)のエントリアドレスを設定すると、同時にIEビット=1となって、割り込みを受け付け可能な状態となります(※)。
 この状態の時にIRQがアサートされると、現在実行中の次の命令をフェッチするタイミングで割り込みが受け付けられ、ISRに制御が移ります。ISRへ分岐する時、フェッチ中だった次命令のアドレスがスタックへ積まれ、更にIEビット=0にクリアされて多重割り込みが禁止されます。

※ijal命令は、いかにも分岐しそうな名前ですが、実行しても直ちに分岐する事はありません。別名setiv命令が示す通り、割り込みベクタivにISRのエントリアドレスを設定する命令です。IRQ信号がアサートされるとISRへ分岐します。

 ISR内で割り込み処理の実行が終わったら、ijmp命令(別名rti命令)を実行すると、IEビット=1にセットしてから、スタックに退避されていた復帰先アドレスへ復帰します(※)。

 一時的に割り込みを禁止したい場合、ijal命令でIv=0x0000を設定すると、同時にIEビット=0へ設定されます。

※単なるjmp命令(別名rtn命令)では、IEビットをセットしないので、割り込みが禁止されたままとなる事に注意してください。ISRからの復帰にはijmp命令(別名rti命令)が適しています。

命令コード

 全命令は、スタックから取り出す(pop)データ数と、オペランドの種類(符号化即値または即値)によって分類して、以下表の様な命令コードを割り当てています。

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 Instruction
0 0 0 INST_0 other N pop instruction
0 0 1 INST_1 1 pop instruction
0 1 0 INST_2 2 pop instruction
0 1 1 EIMM5 Encoded immediate instruction
1 IMM7 Immediate instruction

 次節と合わせてご確認ください。

命令セット一覧

 以下に命令セットの形式順で一覧表を示します。

No. Inst b[7] b[6:5] b[4:0] Code Description Operation
1 nop 0 0 0 00 no operation none
2 pause 0 0 1 01 pause pause until IRQ=1
3 copr 0 0 2 02 co-processor call pop ccmd; pop Stk1; pop Stk2; push Stk2<ccmd>Stk1
4 not 0 1 0 20 bit wise not pop Stk1; push ~Stk1
5 cend 0 1 1 21 convert endian pop Stk1; push (Stk1<<8)+(Stk1>>>8)
6 lsl 0 1 2 22 logical shift left pop Stk1; push Stk1<<1
7 lsr 0 1 3 23 logical shift right pop Stk1; push Stk1>>>1
8 asr 0 1 4 24 arithmetic shift right pop Stk1; push Stk1>>1
9 neg 0 1 5 25 negate sign pop Stk1; push -Stk1
10 jal 0 1 20 34 jump and link pop Stk1; push PRG_CNT; jump to Stk1
11 jmp 0 1 21 35 jump pop Stk1; jump to Stk1
12 ijal 0 1 22 36 jump and link on interrupt pop Stk1; Iv=Stk1
13 ijmp 0 1 23 37 jump and interrupt enable pop Stk1; IE=1; jump to Stk1
14 ldb 0 1 24 39 load byte memory pop Stk1; push [read byte from Stk1]
15 ldw 0 1 25 38 load word memory pop Stk1; push [read word from Stk1]
16 dupl 0 1 28 3c duplicate pop Stk1; push Stk1; push Stk1
17 pop 0 1 29 3d pop and discard pop Stk1
18 and 0 2 0 40 bit wise and pop Stk1; pop Stk2; push Stk2&Stk1
19 or 0 2 1 41 bit wise or pop Stk1; pop Stk2; push Stk2|Stk1
20 eor 0 2 2 42 bit wise exclusive or pop Stk1; pop Stk2; push Stk2^Stk1
21 add 0 2 3 43 add pop Stk1; pop Stk2; push Stk2+Stk1
22 sub 0 2 4 44 subtract pop Stk1; pop Stk2; push Stk2-Stk1
23 cmp 0 2 5 45 compare pop Stk1; pop Stk2; push NCVZS(Stk2-Stk1)
24 cjmp 0 2 20 54 conditional jump pop Stk1; pop Stk2; jump to Stk1 if Stk2
25 njmp 0 2 21 55 negative conditional jump pop Stk1; pop Stk2; jump to Stk1 if !Stk2
26 stb 0 2 24 59 store byte memory pop Stk1; pop Stk2; [write byte to Stk1]=Stk2
27 stw 0 2 25 58 store word memory pop Stk1; pop Stk2; [write word to Stk1]=Stk2
28 swap 0 2 28 5c swap pop Stk1; pop Stk2; push Stk1; push Stk2
29 psei 0 3 EIMM5 60 push encoded immediate push EIMM5
30 sldi 1 IMM7 80 shift and load immediate pop Stk1; push (Stk1<<7)+IMM7

命令セット

 以下に、全30命令を処理内容別に分類しておきます。

※丸カッコ()内は、命令コードが等しい別名です。

 以降、各命令をアルファベット昇順で説明します。

add (add)

and (bit wise and)

asl (arithmetical shift left)

asr (arithmetical shift right)

cend (convert endian)

cjmp (conditional jump)

cmp (compare)

copr (co-processor call)

dupl (duplicate)

eor (bit wise exclusive or)

ijal (jump and link on interrupt)

ijmp (jump and interrupt enable)

jal (jump and link)

jmp (jump)

ldb (load byte memory)

ldw (load word memory)

lsl (logical shift left)

lsr (logical shift right)

neg (negate sign)

njmp (negative conditional jump)

nop (no operation)

not (bitwise not)

or (bit wise or)

pause (pause)

pop (pop and discard)

psei (push encoded immediate)

rti (return from interrupt)

rtn (return from subroutine)

setiv (set interrupt vector)

setpc (set program counter)

sldi (shift and load immediate)

stb (store byte memory)

stw (store word memory)

sub (subtract)

swap (swap)

アセンブラ

 SamariumアセンブラはOlive+のスクリプトで提供します。以下にリンクします。

  アセンブラスクリプト:asm_sama.olv

※スクリプト(.olv)を実行するには拙作Olive+をWindowsにインストールしてください。

アセンブラ文法

 具体的な例等を交えた解説は、こちらから本文を参照してください。

改訂履歴

日付 項目 備考
2026/04/11 Samarium命令セットマニュアル 作成。

btn_arduino.png btn_moscovium.png

home