目次
指図書
アセンブリ言語の基礎
単純なアセンブリ命令の形式 (コメントにはセミコロンを使用します):
操作码 操作数 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 += R1ADD R0, #0x12
; R0 += 12ADD.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 reg
register reg で指定されたアドレスにジャンプしますBL Label
ラベルに対応するアドレスにジャンプし、ジャンプ前の次の命令のアドレスをLRに保存します。BLX reg
レジスタ reg で指定されたアドレスにジャンプし、REG の LSB に従ってプロセッサの状態を切り替え、転送前に次の命令のアドレスを LR に保存します。
BLX を実行するときは、LSB=1 を設定する必要があります。そうしないとフォルトがトリガーされます。
フラグと条件分岐
アプリケーション プログラム ステータス レジスタ (APSR) には 5 つのフラグ ビットがあり、
プログラム実行時のステータス情報や演算結果の特性を示すために使用されます。
以下は、条件分岐命令で参照できる APSR の 4 つのフラグ ビットです。
- N (負): 最新の算術演算または論理演算の結果が負であることを示します。演算結果の符号を判定するために使用されます。
- Z (ゼロ): 最新の算術演算または論理演算の結果がゼロであったことを示します。演算の結果がゼロかどうかを検出するために使用されます。
- C (キャリー): 最新の符号なし算術演算によりキャリーまたはボローが生成されたことを示します。マルチバイト算術演算でキャリーまたはボローを処理するために使用されます。
- V (オーバーフロー): 最新の符号付き算術演算でオーバーフローが発生したことを示します。これは、符号付き算術演算におけるオーバーフロー条件を検出するために使用されます。
次の表は、利用可能なさまざまなジャンプ条件を示しており、対応するフラグがセットされると、ジャンプ処理に入ります。
上記の条件の組み合わせは、無条件転送命令 (B) と組み合わせてさまざまな条件付き転送命令にすることがよくあります。つまり、
BEQ label
z を 1 に設定すると、位置ラベルにジャンプします。
MOVGT R2, R1
条件付きジャンプの例:
CMP
2 つの数値の差を表し、差の結果に応じてフラグを設定します。- 上記 4 つのフラグ ビットにより、算術演算結果が 0 に等しい場合にトリガーが行われることがわかります。
z=1
- したがって、
R0==R1==0
がトリガーされるz=1
と、BEQ はフラグが設定されていることを検出し、ジャンプ プロセスに入り、ラベルでマークされた位置にジャンプします。
CMP R0, R1
BEQ label
命令分離命令
命令バリア命令は、命令の実行順序とメモリ アクセス順序を保証するために使用される特別な命令であり、通常はマルチコア プロセッサおよびマルチスレッド環境で使用されます。
CM3 に対応する隔離措置がないと、いわゆる「障害現象」が発生します。
以下は CM3 の 3 つの分離命令です。
- ISB (命令同期バリア): ISB 命令を実行すると、前の命令がすべて実行され、保留中の割り込みと例外がすべて処理されるまで、プロセッサは実行を一時停止します。これにより、ISB 命令に先行するすべての命令の実行が確実に完了し、命令の並べ替えが防止されます。
- DSB (データ同期バリア): DSB 命令を実行すると、前のデータ アクセス命令がすべて完了するまでプロセッサは実行を一時停止します。これにより、DSB 命令より前のすべてのデータ アクセス命令が確実に完了し、データ アクセスの並べ替えが防止されます。DSB 命令は、プロセッサと外部デバイス間のデータ同期を確実にするために使用することもできます。
- 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 つの状況でのみ使用できます。
- 特権的
- 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]