汇编写java模块_Java汇编命令大全

JVM内存模型

b73b13e28882e68887a1e4dd30bb2161.png

虚拟机栈

每个方法被执行的时候都会创建一个”栈帧”,用于存储局部变量表(包括参数)、操作数栈、返回地址等信息。每个方法被调用到执行完的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程

4cc38fe89aa777bd6a70381506a52b0a.png

执行javap -c *.class 获得汇编命令

Compiled from "Hello.java"

public classcom.sun.test.Hello {publiccom.sun.test.Hello();

Code:0: aload_01: invokespecial #1 //Method java/lang/Object."":()V

4: aload_05: iconst_06: putfield #2 //Field i:I

9: return

public voidmethod1();

Code:0: getstatic #3 //Field java/lang/System.out:Ljava/io/PrintStream;

3: ldc #4 //String ssss

5: invokevirtual #5 //Method java/io/PrintStream.println:(Ljava/lang/String;)V

8: return

public static voidmain(java.lang.String[]);

Code:0: getstatic #3 //Field java/lang/System.out:Ljava/io/PrintStream;

3: invokevirtual #6 //Method java/io/PrintStream.println:()V

6: return}

汇编构成

指令

操作数栈

局部变量区

构成解释

指令

不必多说顾名思义就是执行每一条的指令。

操作数栈

即每一个方法锁执行的内容了。也就是方法体中的一顿操作。

局部变量表

维护每一个操作数栈的变量表,因为要从局部变量表中拿到数据并进行入栈操作到最终弹出栈帧。

其中指令主要可以分为如下几类:

存储和加载类指令:主要包括load系列指令、store系列指令和ldc、push系列指令,主要用于在局部变量表、操作数栈和常量池三者之间进行数据调度;(关于常量池前面没有特别讲解,这个也很简单,顾名思义,就是这个池子里放着各种常量,好比片场的道具库)

对象操作指令(创建与读写访问):putfield和getfield就属于读写访问的指令,此外还有putstatic/getstatic,还有new系列指令,以及instanceof等指令。

操作数栈管理指令:如pop和dup,他们只对操作数栈进行操作。

类型转换指令和运算指令:如add/div/l2i等系列指令,实际上这类指令一般也只对操作数栈进行操作。

控制跳转指令:这类里包含常用的if系列指令以及goto类指令。

方法调用和返回指令:主要包括invoke系列指令和return系列指令。这类指令也意味这一个方法空间的开辟和结束,即invoke会唤醒一个新的java方法(新的栈和局部变量表),而return则意味着这个空间的结束回收。

栈操作相关

load和store

load 命令:用于将局部变量表的指定位置的相应类型变量加载到栈顶;

store命令:用于将栈顶的相应类型数据保入局部变量表的指定位置;

变量进栈含义变量保存含义

iload

第1个int型变量进栈

istore

栈顶int数值存入第1局部变量

iload_0

第1个int型变量进栈

istore_0

栈顶int数值存入第1局部变量

iload_1

第2个int型变量进栈

istore_1

栈顶int数值存入第2局部变量

iload_2

第3个int型变量进栈

istore_2

栈顶int数值存入第3局部变量

iload_3

第4个int型变量进栈

istore_3

栈顶int数值存入第4局部变量

-

-

-

-

lload

第1个long型变量进栈

lstore

栈顶long数值存入第1局部变量

fload

第1个float型变量进栈

fstore

栈顶float数值存入第1局部变量

dload

第1个double型变量进栈

dstore

栈顶double数值存入第1局部变量

aload

第1个ref型变量进栈

astore

栈顶ref对象存入第1局部变量

const、push和ldc

const、push:将相应类型的常量放入栈顶

ldc:则是从常量池中将常量

常量进栈含义

aconst_null

null进栈

iconst_m1

int型常量-1进栈

iconst_0

int型常量0进栈

iconst_1

int型常量1进栈

iconst_2

int型常量2进栈

iconst_3

int型常量3进栈

iconst_4

int型常量4进栈

iconst_5

int型常量5进栈

-

-

lconst_0

long型常量0进栈

fconst_0

float型常量0进栈

dconst_0

double型常量0进栈

-

-

bipush

byte型常量进栈

sipush

short型常量进栈

常量池操作含义

ldc

int、float或String型常量从常量池推送至栈顶

ldc_w

int、float或String型常量从常量池推送至栈顶(宽索引)

ldc2_w

long或double型常量从常量池推送至栈顶(宽索引)

pop和dup

pop用于栈顶数值出栈操作;

dup用于赋值栈顶的指定个数的数值,并将其压入栈顶指定次数;

栈顶操作含义

pop

栈顶数值出栈(不能是long/double)

pop2

栈顶数值出栈(long/double型1个,其他2个)

-

-

dup

复制栈顶数值,并压入栈顶

dup_x1

复制栈顶数值,并压入栈顶2次

dup_x2

复制栈顶数值,并压入栈顶3次

dup2

复制栈顶2个数值,并压入栈顶

dup2_x1

复制栈顶2个数值,并压入栈顶2次

dup2_x2

复制栈顶2个数值,并压入栈顶3次

-

-

swap

栈顶的两个数值互换,且不能是long/double

注意:dup2对于long、double类型的数据就是一个,对于其他类型的数据,才是真正的两个,这个的2代表的是2个slot的数据。

对象相关

字段调用

字段调用含义

getstatic

获取类的静态字段,将其值压入栈顶

putstatic

给类的静态字段赋值

getfield

获取对象的字段,将其值压入栈顶

putfield

给对象的字段赋值

方法调用

方法调用作用解释

invokevirtual

调用实例方法

虚方法分派

invokestatic

调用类方法

static方法

invokeinterface

调用接口方法

运行时搜索合适方法调用

invokespecial

调用特殊实例方法

包括实例初始化方法、父类方法

invokedynamic

由用户引导方法决定

运行时动态解析出调用点限定符所引用方法

方法返回

方法返回含义

ireturn

当前方法返回int

lreturn

当前方法返回long

freturn

当前方法返回float

dreturn

当前方法返回double

areturn

当前方法返回ref

对象和数组

创建类实例: new

创建数组:newarray、anewarray、multianewarray

数组元素 加载到 操作数栈:xaload (x可为b,c,s,i,l,f,d,a)

操作数栈的值 存储到数组元素: xastore (x可为b,c,s,i,l,f,d,a)

数组长度:arraylength

类实例类型:instanceof、checkcast

运算指令

运算指令是用于对操作数栈上的两个数值进行某种运算,并把结果重新存入到操作栈顶。Java虚拟机只支持整型和浮点型两类数据的运算指令,所有指令如下:

运算intlongfloatdouble

加法

iadd

ladd

fadd

dadd

减法

isub

lsub

fsub

dsub

乘法

imul

lmul

fmul

dmul

除法

idiv

ldiv

fdiv

ddiv

求余

irem

lrem

frem

drem

取反

ineg

lneg

fneg

dneg

其他运算:

位移:ishl,ishr,iushr,lshl,lshr,lushr

按位或: ior,lor

按位与: iand, land

按位异或: ixor, lxor

自增:iin

比较:dcmpg,dcmpl,fcmpg,fcmpl,lcmp

类型转换

类型转换用于将两种不同类型的数值进行转换。

(1) 对于宽化类型转换(小范围向大范围转换),无需显式的转换指令,并且是安全的操作。各种范围从小到大依次排序: int, long, float, double。

(2)对于窄化类型转换,必须显式地调用类型转换指令,并且该过程很可能导致精度丢失。转换规则中需要特别注意的是当浮点值为NaN, 则转换结果为int或long的0。虽然窄化运算可能会发生上/下限溢出和精度丢失等情况,但虚拟机规范明确规定窄化转换U不可能导致虚拟机抛出异常。

类型转换指令:i2b, i2c,f2i等等。

流程控制

控制指令是指有条件或无条件地修改PC寄存器的值,从而达到控制流程的目标

条件分支:ifeq、iflt、ifnull、ifnonnull等

复合分支:tableswitch、lookupswitch

无条件分支:goto、goto_w、jsr、jsr_w、ret

同步与异常

异常:

Java程序显式抛出异常: athrow指令。在Java虚拟机中,处理异常(catch语句)不是由字节码指令来实现,而是采用异常表来完成。

同步:

方法级的同步和方法内部分代码的同步,都是依靠管程(Monitor)来实现的。

Java语言使用synchronized语句块,那么Java虚拟机的指令集中通过monitorenter和monitorexit两条指令来完成synchronized的功能。为了保证monitorenter和monitorexit指令一定能成对的调用(不管方法正常结束还是异常结束),编译器会自动生成一个异常处理器,该异常处理器的主要目的是用于执行monitorexit指令。即monitorexit指令出现了两次,第1次为同步正常退出释放锁;第2次为发生异步退出释放锁;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值