STM8

STM8S
STM8L152のダイ

STM8は、 STマイクロエレクトロニクス社製の8ビットマイクロコントローラファミリーです。STM8マイクロコントローラは、 ST7マイクロコントローラアーキテクチャの拡張版を採用しています。STM8マイクロコントローラは、フル機能を備えた8ビットマイクロコントローラとしては特に低価格です。[ 1 ]

建築

STM8は以前のST7と非常によく似ていますが、16ビットのインデックスレジスタとスタックポインタ相対アドレッシングモードを備えているため、 C言語のターゲットとしてより適しています。内部的にはハーバード・アーキテクチャですが、統一された24ビットのアドレス空間を作成する「メモリブリッジ」を備えており、RAMからコードを実行(フラッシュROMインシステムプログラミングに便利)し、ROMからデータ(ルックアップテーブルなど)にアクセスすることができます。アクセス時には、「メモリブリッジ」は必要に応じてCPUを停止させ、フラッシュROMへのRAMのような書き込みアクセスを可能にします。EEPROMからのコード実行は拒否され、リセットイベントが生成されます。64KBを超えるデータへのランダムアクセスは、特別な「load far」命令に制限されています。ほとんどの命令のメモリオペランドは、最大128KB(16ビットのベースアドレスと16ビットのオフセット)にアクセスできます。

デバイスの種類に応じて、RAM の容量は 1 ~ 6 KiB の範囲で、ROM の容量は 4 ~ 8 KiB (低密度)、16 ~ 32 KiB (中密度)、または 32 ~ 96 KiB (高密度) になります。

ST7と同じ6つのレジスタ(A、X、Y、SP、PC、CC)を備えていますが、インデックスレジスタXとYは16ビットに拡張され、プログラムカウンタは24ビットに拡張されています。アキュムレータAとスタックポインタはそれぞれ8ビットと16ビットのままです。[ 2 ]

条件コードレジスタにはさらに2つの定義済みビットがあり、合計7つになります。オーバーフローフラグと2つ目の割り込み有効化ビットがあり、4つの割り込み優先度レベルを設定できます。

亜科

  • STM8AF自動車
  • STM8AL 自動車用低消費電力
  • STM8L低消費電力
  • STM8S 汎用
  • STM8Tタッチセンシング
  • STLUX照明制御
  • STNRGパルス幅変調コントローラ

コンパイラサポート

STM8はオープンソースのSmall Device C Compilerによってサポートされており、Cの他にオープンソースのSTM8 eForth [ 3 ] 、 STM8用の対話型Forthシステムがあります。

ST7と比較した変更点

STM8 命令セットは主に ST7 のスーパーセットですが、完全なバイナリ互換性はありません。

XレジスタとYレジスタの演算は16ビットに拡張されました。そのため、ロードとストアは1バイトではなく2バイトのメモリにアクセスします。(また、ハーフキャリーフラグは、16ビットの結果のビット3からビット4へのキャリーではなく、ビット7からビット8へのキャリーを反映するように変更されました。)

割り込みは、ST7 の 5 バイトではなく 9 バイトの状態をプッシュします。

乗算命令は、16 ビットの積を X と A の間で割るのではなく、指定されたインデックス レジスタ (例: X) に格納します。

メモリから8ビットアドレスを取得する間接アドレッシングモード(オペコード92 2x92 3x92 Bx92 6x92 Ex、 )91 6x91 Ex削除されました。すべての間接アドレッシングモードは16ビットアドレスを取得します。新しいプレフィックスバイト72が追加され、16ビットアドレスから始まる間接アドレスをエンコードするために使用されます。

ビット操作命令は、16ビットアドレスを使用し、72プレフィックスバイトを必要とするように変更されました。プレフィックスのないオペコード0xと、1xそれらが以前占有していた領域は、スタックポインタ相対アドレス指定に使用されます。

めったに使用されない分岐命令の一部は、オペコードが90プレフィックスを必要とするように変更され、プレフィックスのないオペコードは V フラグに依存する符号付き分岐に再割り当てされました。

Xレジスタをターゲットとするロード命令と比較命令は、Xレジスタをインデックスとするアドレッシングモードを持つST7ではほとんど役に立ちません。STM8では、このような命令でXレジスタをインデックスとするメモリオペランドを指定すると、レジスタオペランドはYに変更されます。90プレフィックスを使用すると、レジスタは反転され、インデックスレジスタはY、オペランドレジスタはXになります。

大きなパフォーマンスの違いの一つは、STM8は1サイクルあたり32ビットをROMからフェッチし、多くの命令の実行に1サイクルかかることです。命令の長さと必要なサイクル数によっては、RAMからの実行はやや遅くなります。一方、ST7は1サイクルあたり8ビットをフェッチし、命令バイトごとに1サイクルかかります。

命令セット

STM8のオペコードバイトの大部分は、1ビットのタイプ(1オペランドまたは2オペランド)、3ビットのアドレッシングモード、および4ビットのオペコードで構成されます。6つのアドレッシングモードと12個の1オペランドオペコードのみが割り当てられているため、他の命令を配置するためのエンコーディングスペースが確保されています。

STM8命令の概要[ 2 ]
76543210説明
0モードオペコード1オペランド命令(モード≠1、2)
0001オペコード追加の2オペランド命令
0010オペコード条件分岐
0オペコード0001その他の算術命令(オペコード≠1、2)
0オペコード0010
0オペコード0101
0オペコード1011
1モードオペコード2オペランド命令(モード≠0, 1)
100オペコードその他の非算術命令

STM8命令は、オプションのプレフィックスバイト(、、、または)、オペコードバイト、および数バイト(最大4バイト、ただし2バイトを超えることは稀)のオペランドで構成されます。プレフィックスバイトは主にメモリオペランドを指定するためのアドレッシングモードを変更しますが、場合によってはプレフィックスとオペコードバイトの意味を完全に変更することもあります。 72169016911692167290

プレフィックスは90、後続の命令のXとYを入れ替えます。以下の表では、これらのバリエーションを「X/Y」と表記することで1行にまとめており、これは「X」または「Y」のいずれかを意味します。プレフィックスは、90BCPL命令とBCCM命令、および一部の分岐条件命令といった、新しいオペコードを導入する2つの場所でも使用されます。

プレフィックスは92、オフセットオペランド(addr16 ,X)を持つ命令を間接アドレッシング([ addr8 ],X)に変換します。オフセットは、メモリ内の16ビットオフセット値の8ビットアドレスに置き換えられます。プレフィックスは、この機能にのみ使用されます。

プレフィックスに91は前述の両方の効果があり、( addr16 ,X) アドレッシング モードを ([ addr8 ],Y) に変換します。

プレフィックスは72、あまり規則的ではないパターンで、様々な場所で使用されます。場合によっては、新しいアドレッシングモード(特に ([ addr16 ],X) 16ビット間接モード)が導入されるだけでなく、全く新しい操作も数多く導入されます。

STM8命令セット[ 2 ]
接頭辞76543210オペランドニモニック説明
0000オペコードアドレス8OP (アドレス8 ,SP)1オペランド命令(下記参照)
0001オペコードアドレス8OP A、(アドレス8、SP)スタックオペランドを持つ2オペランド命令
00010000アドレス8SUB A,(アドレス8 , SP )A := A − オペランド
00010001アドレス8CP A、(アドレス8、SP)A − オペランドを比較する
00010010アドレス8SBC A、(アドレス8、SP)A := A − オペランド − C 借用による減算
00010011アドレス8CPW X,(アドレス8 ,SP)X − オペランド(16ビット)を比較する
00010100アドレス8AND A,(アドレス8 , SP )A := A & オペランド、ビットごとのAND
00010101アドレス8BCP A、(アドレス8、SP)ビットテストA & オペランド
00010110アドレス8LDW Y、(アドレス8、SP)Y := オペランド ( LD A,( addr8 ,SP)がオペコード7Bに割り当てられる)
00010111アドレス8LDW (アドレス8 ,SP),Yオペランド := Y ( LD ( addr8 ,SP),A がオペコード6Bに割り当てられる)
00011000アドレス8XOR A,(アドレス8 , SP )A := A ^ オペランド、排他的論理和
00011001アドレス8ADC A、(アドレス8、SP)A := A + オペランド + C、キャリー付き加算
00011010アドレス8または A,(アドレス8 , SP )A := A | オペランド、包含的または
00011011アドレス8ADD A,(アドレス8 , SP )A := A + オペランド
00011100imm16ADDW X、#imm16X := X + 即値 (= JP ( addr8 ,SP) )
00011101imm16サブW X、#imm16X := X − 即値 (= CALL ( addr8 , SP) )
00011110アドレス8LDW X、(アドレス8、SP)X := オペランド
00011111アドレス8LDW (アドレス8 ,SP),Xオペランド := X
72/90000c少しvオペランドビット操作
720000少し0アドレス16 soff8BTJT  addr16、#ビットラベルソースビットが真(セット)の場合、PC + soff8 にジャンプします。
720000少し1アドレス16 soff8BTJF  addr16、#ビットラベルソースビットが偽(クリア)の場合、PC + soff8 にジャンプします。
720001少し0アドレス16BSET addr16、#ビット指定されたビットを1に設定する
720001少し1アドレス16BRESアドレス16、#ビット指定されたビットを0にリセット(クリア)する
900001少し0アドレス16BCPL addr16、#ビット選択したビットを補数(トグル)
900001少し1アドレス16BCCMアドレス16、#ビットメモリビットにキャリーフラグを書き込む
—/900010状態ソフ8条件分岐(8ビット符号付きオフセット)
00100000ソフ8JRAラベル常に分岐する(true)
00100001ソフ8JRFラベルブランチはなし(偽)
00100010ソフ8JRUGTラベル符号なしがより大きい場合分岐 (C=0 かつ Z=0)
00100011ソフ8JRULEラベル符号なし小さか等しい場合分岐(C=1 または Z=1)
00100100ソフ8JRNCラベルキャリーがない場合(C=0)分岐
00100101ソフ8JRCラベルキャリーの場合分岐(C=1)
00100110ソフ8JRNEラベル等しくない場合に分岐(Z=0)
00100111ソフ8JREQラベル等しい場合分岐(Z​​=1)
00101000ソフ8JRNVラベルオーバーフローしない場合は分岐(V=0)
9000101000ソフ8JRNHラベルハーフキャリーでない場合は分岐(H=0)
00101001ソフ8JRVラベルオーバーフローの場合分岐(V=1)
9000101001ソフ8JRHレーベルハーフキャリー(H=1)の場合は分岐
00101010ソフ8JRPLラベルプラスの場合に分岐 (N=0)
00101011ソフ8JRMIラベルマイナスの場合に分岐 (N=1)
00101100ソフ8JRSGTラベル符号付きでより大きい場合分岐 (S=0 かつ N=V)
9000101100ソフ8JRNMラベル割り込みマスクでない場合は分岐(I=0)
00101101ソフ8JRSLEラベル符号付きで小さいか等しい場合(S=1またはN≠V)に分​​岐
9000101101ソフ8JRMラベル割り込みがマスクされている場合に分岐する(I=1)
00101110ソフ8JRSGEラベル符号付きより大きいか等しい場合分岐(N=V)
9000101110ソフ8JRILレーベル割り込みラインが低い場合は分岐する
00101111ソフ8JRSLTラベル符号が小さい場合(N≠V)に分​​岐
9000101111ソフ8JRIHラベル割り込みラインがハイの場合に分岐する
接頭辞0モードオペコードオペランド1オペランド命令
0000オペコードアドレス8OP (アドレス8 ,SP)スタックポインタ相対
0001オペコード(スタック付きの2オペランド命令に再割り当てされます。上記を参照)
0010オペコード(条件分岐に再割り当てされます。上記を参照)
0011オペコードアドレス8OPアドレス88ビット絶対アドレス
720011オペコードアドレス16OP [アドレス16 ]16ビット間接アドレス
920011オペコードアドレス8OP [アドレス8 ]16ビットアドレスの8ビット間接アドレス
0100オペコードOP Aアキュムレータ
72/900100オペコードアドレス16OP (アドレス16 ,X/Y)16ビットオフセットでインデックス付け
—/900101オペコードOPW X/YX/Yレジスタ(16ビット演算)
720101オペコードアドレス16OP アドレス1616ビットアドレス
—/900110オペコードアドレス8OP (アドレス8 ,X/Y)8ビットアドレスとX/Y
720110オペコードアドレス16OP ([アドレス16 ],X)16ビット間接アドレスプラスX
92/910110オペコードアドレス8OP ([アドレス8 ],X/Y)8ビット間接アドレスとX/Y
—/900111オペコードOP(X/Y)オフセットなしでインデックス付け
接頭辞0モード0000オペランドNEGオペランド2の補数の否定
0モード0001(交換業務に再割り当て。次のセクションを参照)
0モード0010(他の操作に再割り当てされます。次のセクションを参照してください)
接頭辞0モード0011オペランドCPLオペランド一の補数、論理否定
接頭辞0モード0100オペランドSRLオペランド論理的に右にシフトし、msbit をクリアし、lsbit を繰り上げます: (オペランド:C) := (0:オペランド)
0モード0101(他の操作に再割り当てされます。次のセクションを参照してください)
接頭辞0モード0110オペランドRRCオペランドキャリーを介して右に回転、(オペランド:C) := (C:オペランド)
接頭辞0モード0111オペランドSRAオペランド右シフト算術、msbit は保持、lsbit は繰り上がり
接頭辞0モード1000オペランドSLLオペランド左シフト、msbitを繰り上げる: (C:オペランド) := (オペランド:0)
接頭辞0モード1001オペランドRLCオペランドキャリーで左回転、(C:オペランド) := (オペランド,C)
接頭辞0モード1010オペランドDECオペランドデクリメント; NとZはセット、キャリーは影響なし
0モード1011(他の操作に再割り当てされます。次のセクションを参照してください)
接頭辞0モード1100オペランドINCオペランドインクリメント; NとZはセット、キャリーは影響なし
接頭辞0モード1101オペランドTNZオペランド非ゼロテスト: オペランド値に基づいて N と Z を設定します
接頭辞0モード1110オペランドSWAPオペランドオペランドの半分をスワップする(4ビット回転、SWAPW XとSWAPW Yの場合は8ビット)
接頭辞0モード1111オペランドCLRオペランドオペランドを0に設定、Nをクリア、Zをセット
接頭辞0モードオペコードオペランド1オペランド範囲からオペコード[03-7][125B]を再割り当て
—/9000000001RRWA X/YA を通してワードを右に回転: X/Y と A の 24 ビット連結の 8 ビット右回転; (X:A) := (A:X)
00110001アドレス16EXG A、アドレス16メモリと交換A
01000001EXG A、XLAをXと交換(下半分)
01010001出口X、YXとYを交換(16ビット)
01100001EXG A、YLAをYと交換(下半分)
01110001(予約済み)
—/9000000010RLWA X/YA を通してワードを左に回転: X/Y と A の 24 ビット連結の 8 ビット左回転; (A:X) := (X:A)
00110010アドレス16POPアドレス16スタックからポップ
—/9001000010乗算 X/Y,AX/Y := XL/YL × A
01010010imm8SUBW SP、#immSP := SP − imm8
—/9001100010分割X/Y、AX/YをAで割る。X/Yに16ビットの商、Aに余りが入る。
01110010接頭辞命令プレフィックス72: 次のオペコードを変更する
00000101(予約済み)
00110101imm8 アドレス16MOVアドレス16、# imm8即値をメモリに移動(フラグは影響を受けません)
01000101アドレス8 アドレス8MOVアドレス8 ,アドレス8メモリをメモリに移動する(フラグは影響を受けません)
01010101アドレス16 アドレス16MOVアドレス16 ,アドレス16メモリをメモリに移動する(フラグは影響を受けません)
01100101分割X、YXをYで割る(16ビット);商をXに、余りをYに格納する
01110101(予約済み)
00001011(予約済み)
00111011アドレス16プッシュアドレス16スタックにプッシュ
01001011imm8#imm8 を押すスタックにプッシュ
01011011imm8ADDW SP、#imm8SP := SP + imm8
01101011アドレス8LD (アドレス8 ,SP),Aスタックを基準に保存
01111011アドレス8LD A、(アドレス8、SP)スタックに対する負荷
100オペコードその他の命令。いずれも暗黙的に条件コードを設定するものではありません。
10000000アイレット割り込みからの復帰(CC、A、X、Y、PCをポップ)
10000001RET16ビットの戻りアドレスをスタックからPCにポップする
10000010アドレス24INT割り込みベクターテーブルへの特殊ジャンプ
10000011トラップ強制トラップ割り込み
10000100ポップAスタックからAをポップする
—/9010000101ポップW X/YスタックからX/Yをポップ(16ビット)
10000110ポップCCスタックから条件コードをポップする
10000111RETF24ビットの戻りアドレスをスタックからPCにポップする
10001000押すAをスタックにプッシュする
—/9010001001プッシュX/YX/Yをスタックにプッシュ(16ビット)
10001010プッシュCC条件コードをスタックにプッシュする
10001011壊すデバッガがある場合は停止、ない場合は NOP
10001100CCF補数(トグル)キャリーフラグ
10001101アドレス24CALLFアドレス2424ビットPCをプッシュ; PC := addr24
9210001101アドレス16CALLF [アドレス16 ]間接ファーコール; アドレスは24ビットポインタ
10001110停止プロセッサとクロックを停止する
10001111WFI割り込みを待ち、プロセッサを停止するがクロックは停止しない
7210001111WFEイベント(コプロセッサ)を待機し、待機中に通常どおり割り込みを処理する
10010000PDY命令プレフィックス90: 次の命令でXとYを入れ替える
10010001PIY命令プレフィックス91: PDY プラス PIX
10010010ピックス命令プレフィックス92: オペランドに8ビットメモリ間接を使用する
—/9010010011LDW X/Y、Y/XX/Y := Y/X
—/9010010100LDW SP、X/YSP := X/Y
—/9010010101LD XH/YH、AXH/YH := A
—/9010010110LDW X/Y、SPX/Y := SP
—/9010010111LD XL/YL、AXL/YL := A
10011000RCFキャリーフラグをリセット(クリア)する
10011001SCFキャリーフラグを設定する
10011010リム割り込みマスクをリセットする(割り込みを有効にする)
10011011シム割り込みマスクを設定する(割り込みを無効にする)
10011100RVFオーバーフローフラグをリセット(クリア)する
10011101いいえ操作なし
—/9010011110LD A、XH/YHA := XH/YH
—/9010011111LD A、XL/YLA := XL/YL
接頭辞1モードオペコードオペランド2つのオペランド命令 A := A op operand
0000オペコードアドレス8OP A、(アドレス8、SP)(オペコード6、7、C、Dは異なります。上記を参照)
100オペコード(その他の指示に再割り当て。上記を参照)
1010オペコードimm8OP A、# imm88ビット即値オペランド(宛先としては禁止)
1011オペコードアドレス8OP A、アドレス88ビット絶対アドレス(ジャンプ/呼び出しでは禁止)
1100オペコードアドレス16OP A、アドレス1616ビット絶対アドレス
721100オペコードアドレス16OP A、[アドレス16 ]16ビット間接アドレス
921100オペコードアドレス8OP A、[アドレス8 ]16ビットアドレスの8ビット間接アドレス
—/901101オペコードアドレス16OP A、(アドレス16、X/Y)16ビットオフセットでインデックス付け
721101オペコードアドレス16OP A,([アドレス16 ],X)16ビット間接 + X
92/911101オペコードアドレス16OP A,([アドレス8 ],X/Y)8ビット間接 + X/Y
—/901110オペコードアドレス8OP A、(アドレス8、X/Y)8ビットオフセットでインデックス付け
—/901111オペコードOP A、(X/Y)オフセットなしでインデックス付け
接頭辞1モード0000オペランドSUB A、オペランドA := A − オペランド
接頭辞1モード0001オペランドCP A、オペランドA − オペランドを比較する
接頭辞1モード0010オペランドSBC A、オペランドA := A − オペランド − C 借用による減算
接頭辞1モード0011オペランドCPW X/Y、オペランドX/Y − オペランド(16ビット)を比較します。オペランドモードがX/Yでインデックスされている場合は、Y/Xを比較します(オペコードD3、E3、F3)。
接頭辞1モード0100オペランドAND A、オペランドA := A & オペランド、ビットごとのAND
接頭辞1モード0101オペランドBCP A、オペランドビットテストA & オペランド
接頭辞1モード0110オペランドLD A、オペランドA := オペランド
接頭辞1モード0111オペランドLDオペランド、Aオペランド := A (モード 2 LD #imm8,Aが再割り当てされます。下記参照)
接頭辞1モード1000オペランドXOR A、オペランドA := A ^ オペランド、排他的論理和
接頭辞1モード1001オペランドADC A、オペランドA := A + オペランド + C、キャリー付き加算
接頭辞1モード1010オペランドOR A、オペランドA := A | オペランド、包含的または
接頭辞1モード1011オペランドADD A、オペランドA := A + オペランド
接頭辞1モード1100オペランドJPオペランドPC の下位 16 ビット := オペランド、無条件ジャンプ (モード 2 JP #imm8と 3 JP addr8が再割り当てされます、下記参照)
接頭辞1モード1101オペランドCALLオペランド16ビットPCをプッシュ、PCの下位16ビット:=オペランド(モード2 CALL #imm8と3 CALL addr8の再割り当て、下記参照)
接頭辞1モード1110オペランドLDW X/Y、オペランドロード X/Y := オペランド; LDW Y,( addr8 ,SP) に 90 1E の代わりに 16 を使用します
接頭辞1モード1111オペランドLDWオペランド、X/Yオペランド:= X/Y (16ビット、モード2 LD #imm8,Xが再割り当てされます、下記参照); オペランドモードがX/Yでインデックスされている場合はY/Xを格納します(オペコードDF、EF、FF); LDW ( addr8 ,SP),Y には90 1Fの代わりに17を使用します
接頭辞1モードオペコードオペランド2つのオペランドの範囲からオペコードA7、AC、BC、AD、BD、AFを再割り当てしました
—/9010100111アドレス24LDF (アドレス24 ,X/Y),Aロードファー(= LD #imm8,A
92/9110100111アドレス16LDF ([アドレス16 ],X/Y),A24ビットポインタの16ビットアドレス
10101100アドレス24JPFアドレス24PC := addr24 (= JP #imm8 )
9210101100アドレス16JPF [アドレス16 ]間接ファージャンプ; アドレスは24ビットポインタ
10111100アドレス24LDF A、アドレス24ロード far (= JP addr8 )
9210111100アドレス16LDF A、[アドレス16 ]24ビットポインタの16ビットアドレスをロードする
10101101ソフ8CALLRラベル16ビットPCをプッシュ、PC := PC + オペランド (= CALL #imm8 )
10111101アドレス24LDFアドレス24、Aオペランド := A (= CALL addr8 )
9210111101アドレス16LDF [アドレス16 ],Aオペランド := A、24ビットポインタの16ビットアドレス
—/9010101111アドレス24LDF A、(アドレス24、X/Y)ロードファー(= LDW #imm8,X
92/9110101111アドレス16LDF A,([アドレス16 ],X/Y)24ビットポインタの16ビットアドレス
721モードオペコードオペランドインデックスレジスタ演算(16ビット)X/Y := X/Y ± オペランド
721010オペコードimm16OPW X/Y、# imm1616ビット即値
721011オペコードアドレス16OPW X/Y、アドレス1616ビット絶対
721111オペコードアドレス8OPW X/Y、(アドレス8、SP)スタック相対
721モード0000オペランドSUBW X、オペランドX := X − オペランド(SUBW X,# imm16の場合はオペコード1Dを推奨)
721モード0010オペランドSUBW Y、オペランドY := Y − オペランド
721モード1001オペランドADDW Y、オペランドY := Y + オペランド
721モード1011オペランドADDW X、オペランドX := X + オペランド (ADDW X,# imm16の場合はオペコード 1C を推奨)

オペランド アドレッシング モードが X でインデックスされる CPW および LDW 命令の場合、STM8 はデフォルトで X ではなく Y レジスタを使用します。90プレフィックスを適用すると、X と Y が交換され、レジスタは X になり、アドレッシング モードは Y でインデックスされます。

参考文献

  1. ^ Carlson, Jay (2017年9月15日). “ST STM8” . 2018年6月12日閲覧
  2. ^ a b c「PM0044: STM8 CPUプログラミングマニュアル」(PDF) . STMicroelectronics. 2011年9月. 文書13590 Rev 3. 2018年6月10日閲覧
  3. ^ 「STM8 eForth - ドキュメント付きのシンプルなµC向けのユーザーフレンドリーなForth」 GitHub 2022年11月18日。