Skip to content

Latest commit

 

History

History
176 lines (127 loc) · 5.27 KB

register.md

File metadata and controls

176 lines (127 loc) · 5.27 KB

レジスタ操作

算術、分岐命令など

THUMB.1: ビットシフト

bit 内容
13-15 0b000
11-12 オペコード
6-10 オフセット (0-31)
3-5 Rs - ソースレジスタ (R0..R7)
0-2 Rd - ターゲットレジスタ (R0..R7)

オペコード(bit11-12):

0: LSL{S} Rd,Rs,#Offset     ; 左シフト  Rd = Rs << nn
1: LSR{S} Rd,Rs,#Offset     ; 論理右シフト Rd = Rs >> nn
2: ASR{S} Rd,Rs,#Offset     ; 算術右シフト Rd = Rs >> nn
3: 未使用
  • 論理右シフト: 右に溢れたbitは捨てられ、左に空いたbitは0埋めされる
  • 算術右シフト: 右に溢れたbitは捨てられ、左に空いたbitは元の符号(0 or 1)で埋められる

ARMモードと同様、シフト量0のときは特殊な処理になります。

  • LSL#0: シフトは行われません。キャリーの値は不変です。
  • LSR/ASR#0 は LSR/ASR#32 として解釈されます。
  • ソースコードで LSR/ASR#0 を指定しようとすると、自動的に LSL#0 としてリダイレクトされます。同様に LSR/ASR#32 は LSR/ASR#0 としてリダイレクトされます。

フラグ: NZC (LSL#0のときはCは不変)

実行時間: 1S

THUMB.2: 加算/減算

bit 内容
11-15 0b00011
9-10 オペコード
6-8 足し引きする値(0..7 オペコードによってRnかnnかどうか変わる)
3-5 Rs - ソースレジスタ (R0..R7)
0-2 Rd - ターゲットレジスタ (R0..R7)

オペコード(bit9-10):

0: ADD{S} Rd,Rs,Rn   ; Rd=Rs+Rn
1: SUB{S} Rd,Rs,Rn   ; Rd=Rs-Rn
2: ADD{S} Rd,Rs,#nn  ; Rd=Rs+nn
3: SUB{S} Rd,Rs,#nn  ; Rd=Rs-nn

フラグ: NZCV (LSL#0のときはCは不変)

実行時間: 1S

THUMB.3: 即値の演算

bit 内容
13-15 0b001
11-12 オペコード
8-10 Rd - ターゲットレジスタ (R0..R7)
0-7 nn - 符号無しオフセット (0-255)

オペコード(bit11-12):

0: MOV{S} Rd,#nn      ; Rd   = #nn
1: CMP{S} Rd,#nn      ; Void = Rd - #nn
2: ADD{S} Rd,#nn      ; Rd   = Rd + #nn
3: SUB{S} Rd,#nn      ; Rd   = Rd - #nn

フラグ:

  • NZ: MOV
  • NZCV: それ以外

実行時間: 1S

THUMB.4: 算術演算

bit 内容
10-15 010000
6-9 オペコード
3-5 Rs - ソースレジスタ (R0..R7)
0-2 Rd - ターゲットレジスタ (R0..R7)

オペコード(bit6-9):

命令 処理内容
0 AND{S} Rd,Rs AND Rd = Rd AND Rs
1 EOR{S} Rd,Rs XOR Rd = Rd XOR Rs
2 LSL{S} Rd,Rs 論理左シフト Rd = Rd << (Rs AND 0FFh)
3 LSR{S} Rd,Rs 論理右シフト Rd = Rd >> (Rs AND 0FFh)
4 ASR{S} Rd,Rs 算術右シフト Rd = Rd SAR (Rs AND 0FFh)
5 ADC{S} Rd,Rs 足し算(+キャリー) Rd = Rd + Rs + Carry
6 SBC{S} Rd,Rs 引き算(+キャリー) Rd = Rd - Rs - NOT Carry
7 ROR{S} Rd,Rs ROR Rd = Rd ROR (Rs AND 0FFh)
8 TST Rd,Rs bitチェック Void = Rd AND Rs
9 NEG{S} Rd,Rs 反転 Rd = 0 - Rs
A CMP Rd,Rs 比較 Void = Rd - Rs
B CMN Rd,Rs 比較(反転) Void = Rd + Rs
C ORR{S} Rd,Rs OR Rd = Rd OR Rs
D MUL{S} Rd,Rs 乗算 Rd = Rd * Rs
E BIC{S} Rd,Rs bitクリア Rd = Rd AND NOT Rs
F MVN{S} Rd,Rs 否定 Rd = NOT Rs

フラグ:

  • NZCV: ADC,SBC,NEG,CMP,CMN
  • NZC: LSL,LSR,ASR,ROR (シフト量が0のときはCは不変)
  • NZC: MUL (Cは必ずクリア)
  • NZ: AND,EOR,TST,ORR,BIC,MVN

実行時間:

  • AND,EOR,ADC,SBC,TST,NEG,CMP,CMN,ORR,BIC,MVN: 1S
  • LSL,LSR,ASR,ROR: 1S+1I
  • MUL: 1S+mI (m=1..4; 入力Rd値の最上位bitに依存)

THUMB.5: R8-15レジスタ操作/BX命令

THUMBモードで通常操作できないR8-R15を操作する命令です。

bit 内容
10-15 0b010001
8-9 オペコード
7 MSBd - ターゲットレジスタのMSB
6 MSBs - ソースレジスタのMSB
3-5 Rs - ソースレジスタ (MSBsと合わせて R0..R15)
0-2 Rd - ターゲットレジスタ (MSBdと合わせて R0..R15)

オペコード(bit8-9):

0: ADD Rd,Rs   ; add        Rd = Rd+Rs
1: CMP Rd,Rs   ; compare    Void = Rd-Rs  ; CPSR affected
2: MOV Rd,Rs   ; move       Rd = Rs
2: NOP         ; nop        R8 = R8
3: BX  Rs      ; jump       PC = Rs

ADD, CMP, MOVの場合、MSBsかMSBdのどちらかがセットされている、つまりソースレジスタかターゲットレジスタのどちらか(または両方)がR8-R15の必要があります。

R15がオペランドのとき、R15に入っているのは($+4)であることに注意してください。

BX

BXにはいくつか注意点があります

まずMSBdは必ずクリアされている必要があります。Rdは使用されません。

またRsレジスタに格納されている値(つまりジャンプ先)のbit0が0の場合、ARMモードに切り替わり、(アラインメントのため)Rsのbit1はクリアされます。そのためBX R15は必ずワードでアラインメントされたアドレスで行う必要があり、ジャンプ先は上述の通りPC+4となります。

その他

THUMBモードにおいてMOV R8,R8NOPとして扱われます。

フラグ:

  • NZCV: CMP
  • 不変: それ以外

実行時間:

  • ADD,MOV,CMP: 1S
  • ADD(Rd=R15), MOV(Rd=R15), BX: 2S+1N