Android自动化埋点(二) - JVM基本操作指令

JVM基本操作指令

一. 概要

JVM操作指令是字节码插桩必须要掌握的知识点,后面我们操作字节码,几乎每一行代码都离不开我们对操作指令的运用。

本篇将介绍常用的JVM操作指令,或者我们后期实际Demo中,我们会用到的指令。

二. 操作指令

同类型的指令,可以针对不同数据类型,我们定义了一个变量x,x可以是以下变量:

  • a: 对象类型
  • i: int
  • l: long
  • f: float
  • d: double
  • b: byte
  • c: char
  • s: short
  1. 有些时候没有针对于byte和short的专用字节码,因为在JVM中,byte和short在被计算时会被强制拉长为int,所以它们使用的和int一样。
  2. char和int能互相转换,boolean类似,它们也需要使用int的字节码,而且boolean值的false就是int值0,而true就是int值1。
  3. 在局部变量表中,32位以内的类型只占有一个slot(包括引用数据类型),64位的类型(long和double)占有两个slot,后面Demo会举例。
1. xload n

从局部变量表取出下标为n的元素压入到操作数栈 栈顶

iload 1 
2. xstore n

从操作数栈 栈顶弹出 放入局部变量表下标为n的位置

istore 1
3. xreturn

返回操作数栈顶int类型的元素

ireturn
4. dup

复制栈顶元素压入操作数栈

_new 'com/baidu/asmtest/TestByteCode'
dup // 将上一步new的对象栈顶复制一份
5. ldc 常量

读取常量池中的常量压入操作数栈

LDC "hello world"
6. xconst_n

将一个数字类型的常量压入操作数栈
x可以取值为 i/l/f/d

n可以取值为 m1,0,1,2,3,4,5

iconst_1 // 1
iconst_m1 // -1
lconst_1 // long类型1
dconst_1 // double类型1
7. bipush n, sipush n

将一个byte或者short类型的数字常量值压入操作数栈

对于bipush,n属于byte范围(-128~127)

对于sipush,n属于short范围(-32768~32767)

bipush 126
sipush 32766
8. 运算符
  • xadd: 加法运算符
  • xsub: 减法运算符
  • xmul: 乘法运算符
  • xdiv: 除法运算符

将栈顶的两个元素弹出并进行运算

iload 3 // 入栈
iload 0 // 入栈
iadd // 弹出栈顶两个元素,相加,将结果压入栈
9. 类型转换
  • x2d: 转换为double类型,x可以取值为 i/l/f
  • x2i: 转换为int类型, x可以取值为 d/l/f
  • x2l: 转换为long类型,x可以取值为 i/d/f
  • i2x: int转换为其它类型 x可以取值为 b/c/s
iload 3 // 将局部变量表中一个int类型的数字压入栈
i2d // 弹出栈顶元素,类型转换,将结果压入栈

三. Demo

定义一个方法,传入两个参数,两个参数分别相乘后再相加

public static double test2(long num1, int num2) {
    return num1 * num1 + num2 * num2;
}

编译后的字节码

  // 默认局部变量表中有两个元素,index为0,1存放long类型的a,index为2存放int类型的b
  public static double test2(long a,int b) {
    lload 0 // 将局部变量表index为0的元素压入栈
    lload 0 // 将局部变量表index为0的元素压入栈
    lmul // 弹出操作数栈 栈顶的两个元素,并进行乘法运算 num1 * num1, 将结果压入栈中
    iload 2 // 将局部变量表index为2的元素压入栈, 为什么是2,因为第一个参数为long类型,局部变量表中占用两个slot,故第二个参数在局部变量表的index为2的位置
    iload 2 // 同上
    imul //弹出操作数栈 栈顶的两个元素,并进行乘法运算 num2 * num2, 将结果压入栈中
    i2l // 将上一步的结果,转为long类型,并压入栈
    ladd // 此时栈顶 为两个long类型的元素,进行相加
    l2d // 返回值为double类型
    dreturn
  }

为了方便读者能够理解,我将注释写的非常详细,建议初学者仔细研读并且理解。

四. 总结

JVM操作指令有很多,本篇只讲常用的,后续无痕埋点Demo中会用到这些指令,务必理解。

下一篇我们会讲调用方法相关的操作指令。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小强冲冲冲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值