本篇指令码表,参考自ASM文档手册,如果你对asm感兴趣,可到ASM官网下载手册学习。

一、本地变量操作指令(I,L,F,D,A这些前缀表示对int,long,float,double,引用进行操作)

本地变量指令集

指令

意义

ILOAD_n(0~3), LLOAD_n(0~3), FLOAD_n(0~3), DLOAD_n(0~3)

超过三的 直接 xLoad n,如ILOAD 4,LLOAD 5

将局部变量表中第n个槽的(int|long|float|double)类型变量推送到操作数栈

ALOAD_n(0~3)

超过3的 ALOAD n,如:ALOAD 5

将引用类型的局部变量第n个槽的推送到操作数栈

ISTORE_n(0~3), LSTORE_n(0~3), FSTORE_n(0~3), DSTORE_n(0~3)

超过三的xSTORE n

将操作数栈顶的(int|long|float|double)类型值弹出存到局部变量表的第n个槽中

ASTORE_n(0~3)

超过3的 ASTORE n

将栈顶引用类型的值存到局部变量表中的第n个槽中

             IINC var incr                                                            将局部变量表中的第var个变量增加incr,并把新值存到局部变量表

本地变量操作表对应的下标是从0开始的,比如下面一段程序

public void print(int age) {

  int a = age;

  a++;

}

对应的字节码文件

stack=1, locals=3, args_size=2//这里的参数为什么是2,因为参数里面有个this,这个this是隐藏的,在JVM中是以参数的形式传递进去的
 iload_1//将局部变量表中的第1个槽,也就是age这个值,0是this,压入操作数栈栈顶

istore_2//将操作数栈顶的值,这里就是age,存到局部变量表的第二个槽,也就是a

iinc 2, 1//将局部变量表中的第二个槽的a加1

return//方法返回

注意,如果局部变量中有long或者double类型的值,那么会占用局部变量两个槽,如有局部变量int age,long l, double d, short s, byte b,那么对应的槽应该是1,2,4,6,7

byte,short,char,int,boolean类型的操作指令统一使用ILOAD或者ISTORE这些指令

二、栈操作指令

                 指令              栈操作前                  栈操作后

POP

...  , v

...                                                   (v被弹出)

POP2

...  , v1  , v2

...                                            (v1和v2被弹出)

...  , w

...                     (w表示占用两个槽的变量,如long,double之类)

DUP

...  , v

...  , v , v            (复制一份)

DUP2

...  , v1  , v2

...  , v1  , v2  , v1 , v2         (复制栈中的两个值)

...  , w

...  , w, w                             (复制一个long,double型的)

SWAP

...  , v1  , v2

...  , v2  , v1                           交换

DUP_X1

...  , v1  , v2

...  , v2 , v1  , v2      复制栈顶值v2,并弹出v1,v2,然后压入v1,v2

DUP_X2

...  , v1  , v2  , v3

...  , v3 , v1  , v2  ,  v3   复制v3,并将弹出的3个值入栈

...  , w ,  v

...  ,  v  , w  , v           复制v,并将复制的两个值入栈(W占两槽)

DUP2_X1

...  , v1  , v2  , v3

...  , v2 , v3 , v1  , v2  ,  v3  复制两个值,并将弹出的3个值入栈

...  , v ,  w

...  , w  , v ,  w   复制2个值,并将弹出的两个值入栈,w占两个槽

DUP2_X2

...  , v1  , v2  , v3  , v4

...  , v3 , v4 , v1  , v2  , v3  ,   v4 复制2值,将弹出的4个值入栈

...  , w , v1  ,  v2

...  , v1  v2  , w , v1  ,  v2   复制2值,将弹出的三个值入栈

....  , v1  , v2  ,  w

...  , w  , v1  , v2  ,  w    复制1个值,将弹出的3个值入栈

...  , w1  , w2

...  , w2  , w1  , w2   复制1个值,将弹出的1个值入栈

举个例子

public void print(int age, String name) {

  this.age = age;

  this.name = name;

}

对应的字节码指令

aload_0   //将this入栈

dup       //复制一个this

aload_1  //将age入栈

putfield #n  //给age复制,这里的n表示一个数字,#n表示索引,对应常量池中的常量

aload_2 //将name入栈

putfield #n //给name复制

三、常量操作

ICONST_n ( n  5)

...

...  , n         将整型常量n入栈

LCONST_n (0  n  1)

...

...  , nL    将长整型常量n入栈 

FCONST_n (0  n  2)

...

...  , nF      将float常量入栈

DCONST_n (0  n  1)

...

...  , nD     将double常量入栈

BIPUSH b128  b < 127

...

...  , b        将byte常量入栈

SIPUSH s32768  s < 32767

...

...  , s        将短整型入栈

LDC cst  (int, float, long, double, String or Type)

...

...  , cst     将常量池中值入栈

ACONST_NULL

...

... , null    将null值入栈

如:public void print(){

  int a1 = 1;              //ICONST_1将1入栈

             //ISTORE_1 将1存入局部变量表1中,即a1

  int a2 = 10;           //BIPUSH 10

             //ISTORE 2

  int a3 = 100;       // SIPUSH 100

            //ISTORE 3

  float a4 = 123f;   //LDC #4这个#4是引用了常量池里的值,123

            //FLOAD 4

  

}

四、算术和逻辑操作指令

IADD, LADD, FADD, DADD

...  , a ,  b

...  , a + b               将栈顶的两个值相加,并把结果入栈

ISUB, LSUB, FSUB, DSUB

...  , a ,  b

...  , a - b

IMUL, LMUL, FMUL, DMUL

...  , a ,  b

...  , a * b

IDIV, LDIV, FDIV, DDIV

...  , a ,  b

...  , a / b

IREM, LREM, FREM, DREM

...  , a ,  b

...  , a   b

INEG, LNEG, FNEG, DNEG

...  , a

...  , -a

ISHL, LSHL

...  , a ,  n

...  , a << n

ISHR, LSHR

...  , a ,  n

...  , a >> n

IUSHR, LUSHR

...  , a ,  n

...  , a >>> n

IAND, LAND

...  , a ,  b

...  , a & b

IOR, LOR

...  , a ,  b

...  , a | b

IXOR, LXOR

...  , a ,  b

...  , a ^ b

LCMP

...  , a ,  b

...  , a == b ? 0 : (a < b ? -1 : 1)

FCMPL, FCMPG

...  , a ,  b

...  , a == b ? 0 : (a < b ? -1 : 1)

DCMPL, DCMPG

...  , a ,  b

...  , a == b ? 0 : (a < b ? -1 : 1)

五、转换

I2B

...  , i

... , (byte) i

I2C

...  , i

... , (char) i

I2S

...  , i

... , (short) i

L2I, F2I, D2I

...  , a

... , (int) a

I2L, F2L, D2L

...  , a

... , (long) a

I2F, L2F, D2F

...  , a

... , (float) a

I2D, L2D, F2D

...  , a

... , (double) a

CHECKCAST class

...  , o

... , (class) o

六、对象,字段,方法操作

NEW class

...

... , new class

GETFIELD c f t

...  , o

...  , o.f

PUTFIELD c f t                    

...  , o ,  v

...

GETSTATIC c f t

...

...  , c.f

PUTSTATIC c f t

...  , v

...

INVOKEVIRTUAL c m t

...  , o , v1  , ...  , vn

... , o.m(v1, ... vn)

INVOKESPECIAL c m t

...  , o , v1  , ...  , vn

... , o.m(v1, ... vn)

INVOKESTATIC c m t

...  , v1  , ...  , vn

... , c.m(v1, ... vn)

INVOKEINTERFACE c m t

...  , o , v1  , ...  , vn

... , o.m(v1, ... vn)

INVOKEDYNAMIC m t bsm

...  , o , v1  , ...  , vn

... , o.m(v1, ... vn)

INSTANCEOF class

...  , o

... , o instanceof class

MONITORENTER

...  , o

...

MONITOREXIT

...  , o

...

七、数组操作

NEWARRAY type (for any primitive type)       new基本类型的数组

...  , n     数组长度

... , new type[n]     new出来的数组引用

ANEWARRAY class                                        new引用类型的数组

...  , n     数组长度

... , new class[n]

MULTIANEWARRAY [...[t n                            多维数组

...  , i1  , ...  , in 各维长度

...  ,  new t[i1]...[in]...

BALOAD, CALOAD, SALOAD                        将指定下标的值入栈

...  , o ,  i      i下标,o数组

... , o[i]

IALOAD, LALOAD, FALOAD, DALOAD

...  , o ,  i

... , o[i]

AALOAD

...  , o ,  i

... , o[i]

BASTORE, CASTORE, SASTORE

...  , o , i ,  j

...

IASTORE, LASTORE, FASTORE, DASTORE

...  , o , i ,  a

...

AASTORE

...  , o , i ,  p

...

ARRAYLENGTH

...  , o

... , o.length

八、跳转语句

IFEQ

...  , i

...

jump if i == 0

IFNE

...  , i

...

jump if i != 0

IFLT

...  , i

...

jump if i < 0

IFGE

...  , i

...

jump if i >= 0

IFGT

...  , i

...

jump if i > 0

IFLE

...  , i

...

jump if i <= 0

IF_ICMPEQ

...  , i ,  j

...

jump if i == j

IF_ICMPNE

...  , i ,  j

...

jump if i != j

IF_ICMPLT

...  , i ,  j

...

jump if i < j

IF_ICMPGE

...  , i ,  j

...

jump if i >= j

IF_ICMPGT

...  , i ,  j

...

jump if i > j

IF_ICMPLE

...  , i ,  j

...

jump if i <= j

IF_ACMPEQ

...  , o ,  p

...

jump if o == p

IF_ACMPNE

...  , o ,  p

...

jump if o != p

IFNULL

...  , o

...

jump if o == null

IFNONNULL

...  , o

...

jump if o != null

GOTO

...

...

jump always

TABLESWITCH

...  , i

...

jump always

LOOKUPSWITCH

...  , i

...

jump always

九、return

IRETURN, LRETURN, FRETURN, DRETURN

...  , a

ARETURN

...  , o

RETURN

...

ATHROW

...  , o

十、泛型

如:public class Test<T> ==> <T:Ljava/lang/Object;>

public class Test<T> extends ArrayList<E> ==> <T:Ljava/lang/Object;>Ljava/util/ArrayList<TE;>;

static <T> Class<? extends T> m (int n) ==> <T:Ljava/lang/Object;>(I)Ljava/lang/Class<+TT;>;

List<E> ==> Ljava/util/List<TE;>;

List<?> ==> Ljava/util/List<*>;

List<? extends Number> ==> Ljava/util/List<+Ljava/lang/Number;>;

List<? super Integer> ==> Ljava/util/List<-Ljava/lang/Integer;>;

List<List<String>[]> ==> Ljava/util/List<[Ljava/util/List<Ljava/lang/String;>;>;

HashMap<K, V>.HashIterator<K> ==> Ljava/util/HashMap<TK;TV;>.HashIterator<TK;>;

注意:如果是定义定义泛型,比如class Test<T>,方法中的<T>这类T,在写泛型签名的时候应当写成T:Ljava/lang/Object;而不是TT;在其他非定义泛型的位置,写成TT;

十一、描述符表

java类型 类型描述符
boolean Z
char  C
byte B
short S
int I
long J
float F
double D
Object Ljava/lang/Object;
int[] [I
Object[][] [[Ljava/lang/Object;

十二、方法描述符

方法 方法描述符
void m(int i, float f) (IF)V
int m(Object o) (Ljava/lang/Object;)I
int[] m(int i, String s) (ILjava/lang/String;)I
Object m(int[] i) ([I)Ljava/lang/Object;

JVM指令的更多相关文章

  1. [转]JVM指令详解(上)

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 本文主要记录一些JVM指令,便于记忆与查阅. 一.未归类系列A 此系列暂未归类. 指令码    助记符      ...

  2. Java并发编程(五)JVM指令重排

    我是不是学了一门假的java...... 引言:在Java中看似顺序的代码在JVM中,可能会出现编译器或者CPU对这些操作指令进行了重新排序:在特定情况下,指令重排将会给我们的程序带来不确定的结果.. ...

  3. JVM 指令讲解

    挺有意思的  转载记录下 转载自 https://www.cnblogs.com/f1194361820/p/8524666.html    原作者: 房继诺 JVM 指令 1.Demo 2.Clas ...

  4. JVM指令助记符

    以下只是JVM指令助记符,关于JVM指令的详细内容请阅读<JVM指令详解> 变量到操作数栈:iload,iload_,lload,lload_,fload,fload_,dload,dlo ...

  5. JVM指令手册

    JVM指令大全 常量入栈指令 指令码 操作码(助记符) 操作数 描述(栈指操作数栈) 0x01 aconst_null null值入栈. 0x02 iconst_m1 -1(int)值入栈. 0x03 ...

  6. Javap与JVM指令

    一.javap命令简述 javap是jdk自带的反解析工具.它的作用就是根据class字节码文件,反解析出当前类对应的code区(汇编指令).本地变量表.异常表和代码行偏移量映射表.常量池等等信息.当 ...

  7. jvm指令手册查看

    00-JVM指令手册 栈和局部变量操作 将常量压入栈的指令 aconst_null 将null对象引用压入栈 iconst_m1 将int类型常量-1压入栈 iconst_0 将int类型常量0压入栈 ...

  8. 深入JVM(一)JVM指令手册

    本文按照如下思维导图组织 1. 栈和局部变量操作 1.1 将常量压入栈的指令 aconst_null 将null对象引用压入栈iconst_m1 将int类型常量-1压入栈iconst_0 将int类 ...

  9. 2.1 附录--JVM指令手册

    栈和局部变量操作 将常量压入栈的指令 aconst_null 将null对象引用压入栈 iconst_m1 将int类型常量-1压入栈 iconst_0 将int类型常量0压入栈 iconst_1 将 ...

  10. JVM 指令

    1.Demo 2.Class 文件说明 2.1 Class文件结构 2.2 jvm type, method signature 2.3 泛型表示 3.方法说明 3.1 方法结构 3.1.1 Thre ...

随机推荐

  1. Java动态规划

    1. 介绍 动态规划典型的被用于优化递归算法,因为它们倾向于以指数的方式进行扩展.动态规划主要思想是将复杂问题(带有许多递归调用)分解为更小的子问题,然后将它们保存到内存中,这样我们就不必在每次使用它 ...

  2. 简单学习js

    由于是个前端小白,通过这一两天的学习html,css,js和jquery等,基本上前端会用了,而且熟悉我博客的人来说,没错,我把自己的博客给优化了一下(一些大佬都是禁用模板的所有样式,然后自己设计页面 ...

  3. 基于Common.Logging + Log4Net实现的日志管理

    前言 Common.Logging 是Commons-Logging(apache最早提供的日志门面接口,提供了简单的日志实现以及日志解耦功能) 项目的.net版本.其目的是为 "所有的.n ...

  4. bitmap-如何判断某个整数是否存在40亿个整数中?

    有这样一道面试题:现有40亿个整数,如果再给定一个新的整数,怎么判断这个整数是否在这40亿个整数中? 你可能首先会想到用一个set存储,那个新数只需判断是否在set中.但是如果用set存储的话,如果一 ...

  5. 并发容器之阻塞队列DelayQueue的使用案例及源码分析

    原文连接:(http://www.studyshare.cn/blog-front//blog/details/1167/0 ) 一.队列及阻塞队列概念 1.队列:是一种特殊线性表,特殊之处在于操作是 ...

  6. Windows 10使用Tesseract-OCR出现WindowsError: [Error 2]

    Tesseract-OCR安装时默认安装在x86的目录下,手动添加环境变量此电脑-->属性-->高级系统设置-->环境变量,点击系统变量里的Path, 点击编辑,在编辑环境变量界面中 ...

  7. Redis 学习笔记(篇四):整数集合和压缩列表

    整数集合 Redis 中当一个集合(set)中只包含整数,并且元素不多时,底层使用整数集合实现,否则使用字典实现. 那么: 为什么会出现整数集合呢?都使用字典存储不行吗? 整数集合在 Redis 中的 ...

  8. 从Spring的几个阶段理解其工作过程

      Spring框架非常强大,想要彻底弄懂Spring是非常困难的. 为了便于了解Spring的工作原理,我们来研究一下,Spring是怎么加载的,Spring会经过几个阶段. 我们站在Javaweb ...

  9. Codeforces 758C:Unfair Poll(思维+模拟)

    http://codeforces.com/problemset/problem/758/C 题意:教室里有n列m排,老师上课点名从第一列第一排开始往后点,直到点到第一列第m排,就从第二列第一排开始点 ...

  10. django基础知识之ORM简介:

    ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...