现在大部分手机cpu架构是ARM v7-A和ARMV8-A,,在ARM-v7A中常使用32位ARM指令集并且支持thumb指令集与arm的切换,而在ARMV8中使用的是64位ARM指令集且不再有thumb指令集状态的切换了。在调用函数时,会有常用的调用方式:BL和B,且分三种情况arm, thumb, aarch64,而对于BLX在arm64指令集中不再有。下面对这三种情况进行讨论。

ARM:



常见跳转指令机器码:

B:0xEA

BL:0xEB

偏移地址计算过程:

(目标地址 - 指令地址 - 8)/ 4 = 偏移

// 减8,指令流水造成。

// 除4,因为指令定长,存储指令个数差,而不是地址差。

完整指令:

.text:0000D11C D9 51 00 EB                             BL              __set_tls

.text:00021888                         __set_tls

计算偏移:

(21888-D11C - 8) /4 = 0x51D9

EB000000 | 0x51D9 =  EB0051D9

thumb:

thumb指令都是2字节。BL看起来像四字节指令,其实是个误解,因为长跳转是由两条跳转指令组成的。

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,代表向前跳转,需要-1然后取反,得到数值为FFFFFFFFFF819F34,取19F34,

2E3C8+ 4 - 19F34 = 14498

若计算出来的数符号位为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向前跳转,0x14向后跳转

BL:0x97向前跳转  0x94向后跳转

偏移地址计算过程:

(目标地址 - 指令地址)/ 4 = 偏移

// 减8,指令流水造成。

// 除4,因为指令定长,存储指令个数差,而不是地址差。

完整指令:

.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机器码计算相关推荐

  1. ARM指令B BL BLX BX区别

    1.B: 跳转. B 指令的格式为: B{条件} 目标地址 B 指令是最简单的跳转指令.一旦遇到一个B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继续执行.注意存储在跳转指令中的实际值是相 ...

  2. ARM中LDR B BX BL BLX指令的研究

    原来的文章有点乱,所以稍微整理了一下有用的要点: (1)  LDR作为伪指令的格式:LDR 寄存器, = 数字常量/Label 如:LDR   R2,=0x55aa ; 表示将0x55aa送入寄存器R ...

  3. ARM汇编指令(B/BL/BX)

    跳转指令用于实现程序流程的跳转,在 ARM 程序中有两种方法可以实现程序流程的跳转: (1) 使用专门的跳转指令. (2) 直接向程序计数器 PC 写入跳转地址值. 通过向程序计数器 PC 写入跳转地 ...

  4. ARM指令集--B BL BLX BX

    B 指令的格式为: B{条件} 目标地址 B 指令是最简单的跳转指令.一旦遇到一个 B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继 续执行 B Label :程序无条件跳转到标号 Lab ...

  5. 4. 从0开始学ARM-ARM指令,移位、数据处理、BL、机器码

    <到底什么是Cortex.ARMv8.arm架构.ARM指令集.soc?一文帮你梳理基础概念[科普]> 关于ARM指令用到的IDE开发环境可以参考下面这篇文章 <1. 从0开始学AR ...

  6. mo汇编指令_moshell常用指令描述

    1. moshell 常用指令描述.  lt : lt 指令是最常用的指令,进入 moshell 之后,首先用 lt 从库中取 mo, 要不然你 就看不到啥东西.通过在 lt 后面配置不同的过滤器可 ...

  7. B BL BLX BX详解

    B.BL.BX.BLX 和 BXJ 跳转.带链接跳转.跳转并切换指令集.带链接跳转并切换指令集.跳转并转换到 Jazelle 状态. 语法 op1{cond}{.W} label op2{cond}  ...

  8. 纯干货!Dockerfile常用指令清单

    Dockerfile常用指令 一.Dockerfile Docker可以通过Dockerfile自动构建镜像,Dockerfile是一个包含多个指令的文档.如下 # syntax=docker/doc ...

  9. Debug常用指令和DOSBox使用步骤

    Debug是Dos系统中著名的调试程序,也可以运行在Windows系统实模下. 优点: 使用Debug程序,可以查看CPU各种寄存器的内容,内存的情况,并且在机器指令级跟踪程序的运行. DosBox: ...

最新文章

  1. uniapp 的使用
  2. C++网络包截取开发
  3. c++primer plus 第13章 编程题第2题
  4. SDNU 1093.DNA排序(水题)
  5. 史诗级pg脚本,亲测好使
  6. [Linux]NIS: 集中化认证服务
  7. oSIP开发者手册 (四)
  8. java 双循环是如何执行的_java – 双循环赛
  9. ActiveMQ常见操作
  10. Linux下vi替换字符命令操作实例
  11. 虚拟机体验NAS私人云(第四篇):虚拟机安装群晖DSM7.01系统(附赠新版DS918+和DS3615xs启动映像)
  12. 【CV】ShuffleNet:通过 GroupConv 和 ChannelShuffle 实现轻量化 CNN 架构
  13. 雅虎搜索架构_雅虎! 想要推动您的网站搜索
  14. 修改php fpm监听端口,怎样修正php fpm监听端口_后端开发
  15. 心理学中的催眠术怎么学[为本教育]
  16. WPS中按条件拆分子表格(WPS更新了版本,为2019)
  17. 开源一个健身学习相关的APP,类似Keep
  18. 近视眼怎么慢慢恢复视力 近视眼怎么恢复视力自然恢复
  19. 「WGCLOUD」支持监测Android(安卓)终端手机的状态吗
  20. 因特网MySQL服务器_因特网服务器的主要功能

热门文章

  1. makefile编译erlang
  2. MikroTik RouterOS x86最大内存只能支持2G
  3. (数据科学学习手札45)Scala基础知识
  4. Openstack入门篇(十一)之neutron服务(控制节点)的部署与测试
  5. LinkedList源码详解
  6. [LeetCode] Minimum Depth of Binary Tree
  7. WCF技术实现基于角色的访问控制
  8. sql中的并、交、差
  9. 计算机网络——因特网的接入技术
  10. Leetcode--56. 合并区间