[Cortex-M3 公認ガイド] 学習ノート 2 - 命令セット

指図書


アセンブリ言語の基礎

単純なアセンブリ命令の形式 (コメントにはセミコロンを使用します):
操作码 操作数 1, 操作数 2, … ;注释

以下にレジスタシフトの格納方法を示します。即値は#で始まる必要があります。

MOV R0, #0x12 ; R0 -> 0x12
MOV R1, #’A’ ; R1 -> 字母 A 的 ASCII 码

定数を定義する EQU ディレクティブ
一部のアセンブラが認識できない特殊な命令を表す DCI コンパイラ ディレクティブ ニーモニック
DCB バイト定数の文字列を定義する
DCD 32 ビット整数の文字列を定義する

DCI 0xBE00 ; 用于指代断点BKPT

DCD 0x123 ; 定义整数

DCB "heloworld",0 ; 定义字符串

UAL

統一アセンブリ言語 (UAL)、Thumb-2 をサポートするために使用される構文ルール

従来のサム構文も引き続き使用できますが、ここでは紹介しません。

ADD R0, R0, R1  ;等效R0=RO+R1

ANDS R0, R0, R1

ADDS.N R0, #1 ;指定使用 16 位指令(N=Narrow)
ADDS.W R0, #1 ;指定使用 32 位指令(W=Wide)

ビューを閉じるコマンド

データ送信

CM3 でのデータ送信タイプは次のとおりです。

  • 2 つのレジスタ間でデータを転送する
  • レジスタとメモリ間でデータを転送する
  • レジスタと特殊機能レジスタ間のデータ転送
  • 即値をレジスタにロードする

よく使われるメモリアクセス命令
(LDRロード命令、STRストア命令)

LDRB Rd, [Rn, #offset]アドレス Rn+offset からバイトを読み取り、Rd に送信します。

LDRD Rd1, Rd2, [Rn, #offset]アドレス Rn+offset からダブルワード (64 ビット整数) を読み取り、Rd1 (下位 32 ビット) と Rd2 (上位 32 ビット) に送信します。

STR Rd, [Rn, #offset]Rd の下位ワードをアドレス Rn+offset に格納します。


一般的に使用される複数のメモリ アクセス方法
ここに画像の説明を挿入

感嘆符は次のとおりです。

STMIA.W R8!, {r0-R3} ; R8 值变为 0x8010,每存一次增一次,先存储后自增
)。增/减单位:字(4 字节)。例如,记R8=0x8000,则下面两
条指令:
STMDB.W R8, {R0-R3} ; R8 值的“一个内部复本”先自减后再存储数据,但 R8 的值不变```

事前インデックス付きの LDR および STR

LDR.W R0, [R1, #20]!この命令は、まずアドレス R1+オフセットの値を R0 にロードし、次に R1 <- R1+ 20 をロードします。


ポストインデックス: ポストインデックスでは、ベースレジスタは感嘆符を省略して無条件に更新されます。

STR.W R0 [R1], #-12この命令は、R0 の値をアドレス R1 に保存します。保存後、R1 ← R1+(-12)

注: LDR および STR を使用する場合、即時データをバッキングする代わりにレジスタをオフセット値として使用できますが、
レジスタをオフセット値として使用する場合は、pre-index および post-index を使用してはなりません


LDR ディレクティブと ADR ディレクティブ

LDR r0, =address1: アドレスaddress1の即値をレジスタr0にロードします。

ADR r0, address1: ラベル address1 のアドレスをレジスタ r0 にロードします。


情報処理

ADD 命令には次のような用途があります。

  • ADD R0, R1; R0 += R1
  • ADD R0, #0x12; R0 += 12
  • ADD.W R0, R1, R2; R0 = R1+R2

CM3にはADD命令の他にSUB, MUL, UDIV/SDIV四則演算の なども含まれています。

SUB Rd, Rm従来の減算、Rd -=
SBC Rd, Rm位置ずれのある Rn 減算、Rd -= Rm+C
RSB.W Rd, Rn, #imm12逆減算、Rd = imm12-Rn
MUL Rd, Rm従来の乗算、Rd *= Rm


通常の論理演算
ここに画像の説明を挿入


シフトと回転の命令

LSL Rd, Rn, #imm5 ; Rd = Rn<<imm5論理左シフト
LSR Rd, Rn, #imm5 ; Rd = Rn>>imm5論理右シフト
ASR Rd, Rn, #imm5 ; Rd = Rn>>imm5算術右シフト

その他の指示の頻度は非常に少なく、面接も細分化されず、要点と簡単な内容をマスターするだけで大​​丈夫です。


サブルーチンコールと無条件ジャンプ命令

最も基本的な 2 つの無条件ジャンプ命令:

  • B Labelラベルに対応するアドレスへジャンプ
  • BX regregister reg で指定されたアドレスにジャンプします
  • BL Labelラベルに対応するアドレスにジャンプし、ジャンプ前の次の命令のアドレスをLRに保存します。
  • BLX regレジスタ reg で指定されたアドレスにジャンプし、REG の LSB に従ってプロセッサの状態を切り替え、転送前に次の命令のアドレスを LR に保存します。

BLX を実行するときは、LSB=1 を設定する必要があります。そうしないとフォルトがトリガーされます。


フラグと条件分岐

アプリケーション プログラム ステータス レジスタ (APSR) には 5 つのフラグ ビットがあり、
プログラム実行時のステータス情報や演算結果の特性を示すために使用されます。

以下は、条件分岐命令で参照できる APSR の 4 つのフラグ ビットです。

  1. N (負): 最新の算術演算または論理演算の結果が負であることを示します。演算結果の符号を判定するために使用されます。
  2. Z (ゼロ): 最新の算術演算または論理演算の結果がゼロであったことを示します。演算の結果がゼロかどうかを検出するために使用されます。
  3. C (キャリー): 最新の符号なし算術演算によりキャリーまたはボローが生成されたことを示します。マルチバイト算術演算でキャリーまたはボローを処理するために使用されます。
  4. V (オーバーフロー): 最新の符号付き算術演算でオーバーフローが発生したことを示します。これは、符号付き算術演算におけるオーバーフロー条件を検出するために使用されます。

次の表は、利用可能なさまざまなジャンプ条件を示しており、対応するフラグがセットされると、ジャンプ処理に入ります。

ここに画像の説明を挿入

上記の条件の組み合わせは、無条件転送命令 (B) と組み合わせてさまざまな条件付き転送命令にすることがよくあります。つまり、
BEQ labelz を 1 に設定すると、位置ラベルにジャンプします。
MOVGT R2, R1


条件付きジャンプの例:

  • CMP2 つの数値の差を表し、差の結果に応じてフラグを設定します。
  • 上記 4 つのフラグ ビットにより、算術演算結果が 0 に等しい場合にトリガーが行われることがわかります。z=1
  • したがって、R0==R1==0がトリガーされるz=1と、BEQ はフラグが設定されていることを検出し、ジャンプ プロセスに入り、ラベルでマークされた位置にジャンプします。
CMP R0, R1
BEQ label

命令分離命令

命令バリア命令は、命令の実行順序とメモリ アクセス順序を保証するために使用される特別な命令であり、通常はマルチコア プロセッサおよびマルチスレッド環境で使用されます。

CM3 に対応する隔離措置がないと、いわゆる「障害現象」が発生します。

以下は CM3 の 3 つの分離命令です。

  1. ISB (命令同期バリア): ISB 命令を実行すると、前の命令がすべて実行され、保留中の割り込みと例外がすべて処理されるまで、プロセッサは実行を一時停止します。これにより、ISB 命令に先行するすべての命令の実行が確実に完了し、命令の並べ替えが防止されます。
  2. DSB (データ同期バリア): DSB 命令を実行すると、前のデータ アクセス命令がすべて完了するまでプロセッサは実行を一時停止します。これにより、DSB 命令より前のすべてのデータ アクセス命令が確実に完了し、データ アクセスの並べ替えが防止されます。DSB 命令は、プロセッサと外部デバイス間のデータ同期を確実にするために使用することもできます。
  3. DMB (データ メモリ バリア): DMB 命令を実行すると、前のデータ アクセス命令とメモリ アクセス命令がすべて完了するまで、プロセッサは実行を一時停止します。これにより、DMB 命令に先行するすべてのデータおよびメモリ アクセスが確実に完了し、データおよびメモリ アクセスの並べ替えが防止されます。DMB 命令は、プロセッサと外部デバイス間のデータ同期を確実にするために使用することもできます。

飽和動作

飽和動作はアナログ回路のクリッピング歪みと似ています。つまり、SSAT 命令を使用することにより、大きなデータ (32 ビット) が小さなデータ (16 ビット) に切り詰められます。

SSAT.W Rd, #imm5, Rn, {,shift}

  • Rd: 宛先レジスタ。切り捨てられた結果を格納するために使用されます。
  • #imm5: 切り捨てられる桁数を表す即値。値の範囲は 1 ~ 32 です。
  • Rn: 切り捨てられる元のデータを含むソース レジスタ。
  • {,shift}: オプションのパラメータ。オプションのシフト演算を指定するために使用されます。LSL (論理左シフト)、LSR (論理右シフト)、ASR (算術右シフト)、または ROR (回転右シフト) を指定できます。

CM3 で新しく導入されたコマンド

これらの命令は ARMv6 および ARMv7 でのみサポートされます。

MRS\MSR

これら 2 つの命令は、次の 2 つの状況でのみ使用できます。

  1. 特権的
  2. APSR でのユーザー レベル

コマンド構文
MRS <Rn>, <SReg>特殊機能レジスタの値を Rn にロード
MSR <Sreg>,<Rn> Rn の値を特殊機能レジスタにストア

ここに画像の説明を挿入


もし、そのとき

IF-THEN(IT)命令は、内部に最大 4 つの命令を含むブロックを囲みます。

このうち、T は条件が真の場合に実行される文、E は条件が真でない場合に実行される文を表しており、E に対応する命令は
T! に対応する命令の逆でなければなりません。

対応する疑似コードと使用法を以下に示します。

ここに画像の説明を挿入


CBZ/CBNZ

CBZ (Compare and Branch if Zero): CBZ 命令は、レジスタの値がゼロかどうかを比較し、ゼロの場合は、指定されたターゲット アドレスへのジャンプ操作を実行するために使用されます。

CBNZはCBZの反対の意味です

フォーマット:

CBZ <寄存器>, <目标地址>    ; 如果寄存器的值为零,则跳转到目标地址
CBNZ <寄存器>, <目标地址>   ; 如果寄存器的值不为零,则跳转到目标地址

SDIV/UDIV

32ビットハードウェア除算命令

SDIV.W Rd, Rn, Rm
UDIV.W Rd, Rn, Rm

レブバインディング

REV は 32 ビット整数でエンディアンを反転し、REVH はハーフワードで反転し、下位ハーフワードのみを反転します。

REV Rd, Rm
REVH Rd, Rm
REV16 Rd, Rm
REVSH Rd, Rm

RBIT は以前の REV ストリームよりも洗練されており、ビット単位で反転されています。これは、32 ビット整数のバイナリ表現を水平方向に
180 度回転することに相当します。

RBIT.W Rd, Rn

SXTB

データ幅を符号付き 32 ビット整数長に変換するために使用されます

U プレフィックスが付いた場合は、上位ビットがクリアされることを意味します

SXTB Rd, Rn
SXTH Rd, Rn
UXTB Rd, Rn
UXTH Rd, Rn

未定、未定

TBB(Table Branch Byte): TBB 命令は、ルックアップ テーブルをジャンプするために使用されます。バイト サイズのオフセットをベース アドレス レジスタに追加し、結果のターゲット アドレスにジャンプします。

TBB [<基地址寄存器> + <偏移量寄存器>]

TBH(Table Branch Halfword):該当処理はハーフワードデータ

TBH [<基地址寄存器> + <偏移量寄存器> * 2]

おすすめ

転載: blog.csdn.net/delete_you/article/details/132490100