Apr 3, 2020
ARM7TDMIはGBAで使われているCPUのコアだがあまり情報が出回っていない部分がある. 特に割り込みの動作については質の良い情報がなかなか得られないのでここで詳しく解説したい.
System/User | FIQ | Supervisor | Abort | IRQ | Undefined |
---|---|---|---|---|---|
R0 | R0 | R0 | R0 | R0 | R0 |
R1 | R1 | R1 | R1 | R1 | R1 |
R2 | R2 | R2 | R2 | R2 | R2 |
R3 | R3 | R3 | R3 | R3 | R3 |
R4 | R4 | R4 | R4 | R4 | R4 |
R5 | R5 | R5 | R5 | R5 | R5 |
R6 | R6 | R6 | R6 | R6 | R6 |
R7 | R7 | R7 | R7 | R7 | R7 |
R8 | R8_fiq | R8 | R8 | R8 | R8 |
R9 | R9_fiq | R9 | R9 | R9 | R9 |
R10 | R10_fiq | R10 | R10 | R10 | R10 |
R11 | R11_fiq | R11 | R11 | R11 | R11 |
R12 | R12_fiq | R12 | R12 | R12 | R12 |
R13 | R13_fiq | R13_svc | R13_abt | R13_irq | R13_und |
R14 | R14_fiq | R14_svc | R14_abt | R14_irq | R14_und |
R15 | R15 | R15 | R15 | R15 | R15 |
CPSR | CPSR | CPSR | CPSR | CPSR | CPSR |
-- | SPSR_fiq | SPSR_svc | SPSR_abt | SPSR_irq | SPSR_und |
R13はSP(スタックポインター)として使われる(Thumb state). ARM stateでは普通のレジスタとして使って良い. 例外処理時にはバンクレジスターのR13_xxxに値が入るので元のSPにアクセスできないことに注意. R14はリンクレジスターでBLを呼び出す時に変更される. R15はPC(プログラムカウンター)として使われる.
条件実行で使われる. 例, Zフラグが1の時のみbeqでジャンプ, 0の時のみbneでジャンプするなど. thumbではフラグはジャンプ命令でしか使わないはず.
Bit | Expl. | 説明 |
---|---|---|
31 | N : Sign Flag | Signedの時セット |
30 | Z : Zero Flag | 結果がZeroの時セット |
29 | C : Carry Flag | 繰り上がり時, 繰り下がりなし時にセット |
28 | V : Overflow Flag | オーバーフロー時にセット |
27 | Q : Sticky Overflow | ? ARMv5TE以降でしか使わない |
26-8 | Reserved | For future use |
7 | I : IRQ disable | IRQ禁止時にセット |
6 | F : FIQ disable | FIQ禁止時にセット |
5 | T : State Bit | 0=ARM, 1=Thumb |
4-0 | M4-M0 : Mode Bits | 下記を参照 |
privileged modeの時に値を操作しても良い. Tビットは値を勝手に操作してはいけず, bx命令を使って切り替えること. M4-M0の値に対応するテーブル
Hex | Expl. |
---|---|
10h | User |
11h | FIQ |
12h | IRQ |
13h | Supervisor (SWI) |
17h | Abort |
18h | Undefined |
1Fh | System |
そもそも割り込みとは例外処理の一つであるが他の例外も割り込みと呼ばれたりする. 例外が起きた時CPUはARMモードになりPCは例外に応じた例外ベクトルのアドレスを読み込む.
アドレス | 優先順位 | 例外 | モード | 割り込みフラグ |
---|---|---|---|---|
BASE+00h | 1 | Reset | Supervisor(_svc) | I=1, F=1 |
BASE+04h | 7 | Undefined Instruction | Undefined(_und) | I=1, F=unchanged |
BASE+08h | 6 | Software Interrupt(SWI) | SuperVisor(_svc) | I=1, F=unchanged |
BASE+0Ch | 5 | Prefetch Abort | Abort(_abt) | I=1, F=unchanged |
BASE+10h | 2 | Data Abort | Abort(_abt) | I=1, F=unchanged |
BASE+14h | ?? | Address Exceeds 26bit | Supervisor(_svc) | I=1, F=unchanged |
BASE+18h | 4 | IRQ | IRQ(_irq) | I=1, F=changed |
BASE+1Ch | 3 | FIQ | FIQ(_fiq) | I=1, F=1 |
R14_(new mode)=PC+nn ;save old PC, ie. return address
SPSR_(new mode)=CPSR ;save old flags
CPSR new T,M bits ;set to T=0 (ARM state), and M4-0=new mode
CPSR new I bit ;IRQs disabled (I=1), done by ALL exceptions
CPSR new F bit ;FIQs disabled (F=1), done by Reset and FIQ only
上のPC+nnは例外によって異なる.
レジスタR0からR14までの中で例外処理に使われたものを元に戻す. そして例外に応じたリターン処理を実行してPCとCPSRを元に戻す, この時CPU state(Thumb or ARM)やFIQ, IRQ disable フラグも戻される.
注意: リターンアドレスはARM-styleで記述される. ARM stateから入ったのかThumb stateから入ったのかによらずに処理するため.
一般のバンクレジスタ(R13_fiq, R14_fiq)の他に, さらに5つのバンクレジスタ(R8_fiq-R12_fiq)を持つ. バンクレジスタをもつレジスタは元の値をスタックに保存する処理が省ける. privileged mode (non-user mode)では, FIQはCPSRの F bit をセットすることで禁止できる.
FIQと違いIRQはバンクレジスタを持たない. FIQよりも優先順位が低く, FIQ例外が実行されているときはIRQは禁止されている. priviledged(non-user mode)では, IRQはCPSRの I bit をセットすることで禁止できる.
IRQからのリターン処理:
SUBS PC,R14,4 ;both PC=R14_irq-4, and CPSR=SPSR_irq
swi命令から呼び出される. swi処理は他の例外と同様ARM stateで実行される
リターン処理:
MOVS PC,R14 ;both PC=R14_svc, and CPSR=SPSR_svc
CPUが実行できない命令に当たった時に送られる.
リターン処理:
MOVS PC,R14 ;both PC=R14_und, and CPSR=SPSR_und
GBAでは使われないが仮想メモリシステムで使われる, 詳細略.