一 简单介绍
TBB和TBH两个表格跳转指令通常用于实现C代码中switch语句。
这里只做简述,详细的信息可以查看文档:
The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors, 3rd Edition.pdf
1)TBB
跳转的最大偏移地址2*2^8=512字节
语法格式:
TBB [Rn, Rm]
流程:
2)TBH
跳转的最大偏移地址2*2^16=128k字节
语法格式:
TBH [Rn, Rm, LSL #1]
流程:
二 TBB简单跳转
R0=0,跳转到Dest0
R0=1,跳转到Dest1
R0=2,跳转到Dest2
R0=3,跳转到Dest3
LDR R0, =1
TBB [PC, R0]
Table_start
DCB ((Dest0-Table_start)/2)
DCB ((Dest1-Table_start)/2)
DCB ((Dest2-Table_start)/2)
DCB ((Dest3-Table_start)/2)
Dest0
LDR R1, =0
B Table_end
Dest1
LDR R1, =1
B Table_end
Dest2
LDR R1, =2
B Table_end
Dest3
LDR R1, =3
Table_end
三 TBH简单跳转
R0=0,跳转到Dest0
R0=1,跳转到Dest1
R0=2,跳转到Dest2
R0=3,跳转到Dest3
LDR R0, =3
TBH [PC, R0, LSL #1]
Table_start
DCI ((Dest0-Table_start)/2)
DCI ((Dest1-Table_start)/2)
DCI ((Dest2-Table_start)/2)
DCI ((Dest3-Table_start)/2)
Dest0
LDR R1, =0;
B Table_end
Dest1
LDR R1, =1
B Table_end
Dest2
LDR R1, =2
B Table_end
Dest3
LDR R1, =3
Table_end
四 复杂表格跳转
条件 | 跳转目标标号 |
---|---|
R0[7:6]=00 | Dest0 |
R0[7:6]=01,R0[5:4]=00 | Dest1 |
R0[7:6]=01,R0[5:4]=01 | Dest2 |
R0[7:6]=01,R0[5:4]=10 | Dest3 |
R0[7:6]=01,R0[5:4]=11 | Dest4 |
R0[7:6]=10,R0[1]=0 | Dest5 |
R0[7:6]=10,R0[1]=1 | Dest6 |
R0[7:6]=11,R0[3:2]=00/01 | Dest7 |
R0[7:6]=11,R0[3:2]=10/11 | Dest8 |
LDR R0, =0x60
;; 提取R0[7:6]到R1
;; R1=(R0 & 0xC) >> 6
UBFX R1, R0, #6, #2
TBB [PC, R1]
;; R1=0 Dest0
;; R1=1 Sub_table0
;; R1=2 Sub_table1
;; R1=3 Sub_table2
Table_start
DCB ((Dest0 - Table_start) / 2)
DCB ((Sub_table0 - Table_start) / 2)
DCB ((Sub_table1 - Table_start) / 2)
DCB ((Sub_table2 - Table_start) / 2)
Sub_table0
UBFX R1, R0, #4, #2
TBB [PC, R1]
Sub_table0_start
DCB ((Dest1 - Sub_table0_start) / 2)
DCB ((Dest2 - Sub_table0_start) / 2)
DCB ((Dest3 - Sub_table0_start) / 2)
DCB ((Dest4 - Sub_table0_start) / 2)
Sub_table1
;; TST R0&2,结果为0,则Z=1,EQ成立
;; R0[1]=0 Dest5
;; R0[1]=1 Dest6
TST R0, #2
BEQ Dest5
B Dest6
Sub_table2
UBFX R1, R0, #2, #2
TBB [PC, R1]
;; R1=0/1 Dest7
;; R1=2/3 Dest8
Sub_table2_start
DCB ((Dest7 - Sub_table2_start) / 2)
DCB ((Dest7 - Sub_table2_start) / 2)
DCB ((Dest8 - Sub_table2_start) / 2)
DCB ((Dest8 - Sub_table2_start) / 2)
;;///表格主体
Dest0
LDR R5, =0xFFFF0000
B Table_end
Dest1
LDR R5, =0xFFFF1111
B Table_end
Dest2
LDR R5, =0xFFFF2222
B Table_end
Dest3
LDR R5, =0xFFFF3333
B Table_end
Dest4
LDR R5, =0xFFFF4444
B Table_end
Dest5
LDR R5, =0xFFFF5555
B Table_end
Dest6
LDR R5, =0xFFFF6666
B Table_end
Dest7
LDR R5, =0xFFFF7777
B Table_end
Dest8
LDR R5, =0xFFFF8888
B Table_end
Table_end