arm32和arm64常用指令B BL BLX机器码计算
現(xiàn)在大部分手機cpu架構是ARM v7-A和ARMV8-A,,在ARM-v7A中常使用32位ARM指令集并且支持thumb指令集與arm的切換,而在ARMV8中使用的是64位ARM指令集且不再有thumb指令集狀態(tài)的切換了。在調(diào)用函數(shù)時,會有常用的調(diào)用方式:BL和B,且分三種情況arm, thumb, aarch64,而對于BLX在arm64指令集中不再有。下面對這三種情況進行討論。
ARM:
常見跳轉(zhuǎn)指令機器碼:
B:0xEA
BL:0xEB
偏移地址計算過程:
(目標地址 - 指令地址 - 8)/ 4 = 偏移
// 減8,指令流水造成。
// 除4,因為指令定長,存儲指令個數(shù)差,而不是地址差。
完整指令:
.text:0000D11C D9 51 00 EB ? ? ? ? ? ? ? ? ? ? ? ? ? ? BL ? ? ? ? ? ? ?__set_tls
.text:00021888 ? ? ? ? ? ? ? ? ? ? ? ? __set_tls
計算偏移:
(21888-D11C - 8) /4 = 0x51D9
EB000000 | 0x51D9 = ?EB0051D9
thumb:
thumb指令都是2字節(jié)。BL看起來像四字節(jié)指令,其實是個誤解,因為長跳轉(zhuǎn)是由兩條跳轉(zhuǎn)指令組成的。
0-11位表示11位地址,具體含義如下:
第11位為0,代表偏移高位
第11位為1,代表偏移低位
完整指令:
.text:0002E3C2 F2 F7 A2 ED BLX nanosleep .text:0002E3C6 38 B1 CBZ R0, locret_2E3D8 .text:0002E3C8 E6 F7 66 F8 BL __errno .text:0002E3CC 01 68 LDR R1, [R0].text:00020F08 nanosleep .text:00014498 __errno
先講BL指令:
0002E3C8 E6 F7 66 F8 ? ? ? ? ? ? ? ? ? ? ? ? ? ? BL ? ? ? ? ? ? ?__errno
00014498 ? ? ? ? ? ? ? ? ? ? ? ? __errno
如何得到目標地址的呢,計算方式如下:
解析偏移
F7E6(1111011111100110) 第11位為0,所以代表高位偏移
F866(1111100001100110)第11位為1,所以代表低位偏移
最高位:F7E6 取后11位 7E6
最低位:F866 取后11位 66
7E6 << 12(十進制) = 7E6000
66 ?<< 1 = ?CC
7E6000 | CC = 7E60CC
計算出來7E60CC最高位符號位為1,代表向前跳轉(zhuǎn),需要-1然后取反,得到數(shù)值為FFFFFFFFFF819F34,取19F34,
2E3C8+ 4 - 19F34 = 14498
若計算出來的數(shù)符號位為0,則直接保留該值,然后后面相加而不是減。
那偏移0xF866F7E6又該如何計算出來呢,計算方式如下:
offset = (目標地址- 源地址 -4) & 0x007fffff =?7E60CC
high = offset >> 12(十進制) = 7E6
low = ( offset & 0x00000fff )>>1 ?= 66
machineCode = ((0xF800 | low) << 16) | (0xF000 | high)
=F8660000 | F7E6 = 0xF866F7E6
注意F800相當于高偏移取第11位到第15位, F0000相當于取低偏移第11位到第15位。
再講BLX指令:
0002E3C2 F2 F7 A2 ED ? ? ? ? ? ? ? ? ? ? ? ? ? ? BLX ? ? ? ? ? ? nanosleep
00020F08 ? ? ? ? ? ? ? ? ? ? ? ? nanosleep
那偏移0xEDA2 F7F2 如何得到的呢,跟BL算法稍微不同:
offset = (目標地址- 源地址 -4) &?0x007fffff =?7F2B42
high =?offset?>> 12 = 7F2
low = (?offset?& 0x00000fff )>>1 ?=?5A1
if(low % 2 != 0) {
low++;
}//low=5A2
machineCode = ((0xE800 | low) << 16) | (0xF000 | high);
=EDA20000 | F7F2 = EDA2 F7F2
ARM64:
B:0x17向前跳轉(zhuǎn),0x14向后跳轉(zhuǎn)
BL:0x97向前跳轉(zhuǎn) ?0x94向后跳轉(zhuǎn)
偏移地址計算過程:
(目標地址 - 指令地址)/ 4 = 偏移
// 減8,指令流水造成。
// 除4,因為指令定長,存儲指令個數(shù)差,而不是地址差。
完整指令:
.text:000000000008CC84 8D B3 FF 97 ? ? ? ? ? ? ? ? ? ? ? ? ? ? BL ? ? ? ? ? ? ?je_arena_malloc_hard
.text:0000000000079AB8 ? ? ? ? ? ? ? ? ? ? ? ? je_arena_malloc_hard
計算偏移:
(79AB8-8CC84) / 4 = FFFFFFFFFFFFB38D
FFB38D | 0x97000000 = 97FFB38D
總結
以上是生活随笔為你收集整理的arm32和arm64常用指令B BL BLX机器码计算的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 风机桨叶故障诊断(二) 获取图像几何主方
- 下一篇: leetcode No.2 两数相加