JVM摘要--指令集介绍02

[color=brown]【题外话】由于有大牛在论坛里贴出翻译的《Java虚拟机规范》,我也就不用写那么详细了,哈哈,觉得那里需要写就写一下吧[/color]

Java代码的字节码可以通过 javap 命令生成

JVM的指令通用格式为:

<index> <opcode> [<operand1> [<operand2>...]] [<comment>]

可以认为,方法的JVM字节码存放在一个Code[]数组中,
• <index>就是该数组中存放的操作码的索引,
• <opcode>是操作码的助记符号
• <operandN>是指令的操作数
• <comment>是行尾的语法注释


下面看一个例子

void spin() {
int i;
for (i = 0; i < 100; i++) {
; [color=green]// Loop body is empty [/color]
}
}

编译后的代码如下 (与《Java虚拟机规范(java SE 7)》上看到的不一样,不知道是不是JDK版本的问题)

void spin();
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 100
5: if_icmpge 14
8: iinc 1, 1
11: goto 2
14: return

调用一个新的方法,就产生一个新的帧栈(Frame),如下图,在一个帧栈中,含有操作数栈(Operand Stack)和局部变量表(Local Variables),注意,此图只是用来表示在此期间发生的操作,并不直观的表示内存中的实际状态。

[b]STEP1--> 0: iconst_0 [/b]
[img]http://glutinit.iteye.com/upload/picture/pic/102422/9d7fab24-a78b-3ad4-bcd3-5dd65b09da3c.jpg[/img]

Code[]数组的第0行,表示把int型的0值压入操作数栈,注意,在局部变量表中,索引为0的位置存放的局部变量是指向调用当前方法的类实例的指针,即this指针
指令iconst_<i> 中的i表示的int 常量 −1、0、1、2、3、4、5


[b]STEP2--> 1: istore_1 [/b]
[img]http://glutinit.iteye.com/upload/picture/pic/102424/43fe90af-da72-3438-ba37-e6bc80c08919.jpg[/img]

从操作数栈中弹出一个int型的操作数(即常量0),然后将其放置在局部变量1号位置(0号位置已被this占据)

[b]STEP3--> 2: iload_1 [/b]
[img]http://glutinit.iteye.com/upload/picture/pic/102426/fb5c0834-6eab-3bab-8972-584bd368b20e.jpg[/img]

从局部变量表中获得1号位置变量的值,将其压入操作数栈

[b]STEP4--> 3: bipush 100 [/b]
[img]http://glutinit.iteye.com/upload/picture/pic/102428/28f85d85-e5a1-372c-8a23-f31226897e5a.jpg[/img]

在操作数栈中加入int型的常量100

[b]STEP5--> 5: if_icmpge 14 [/b]
[img]http://glutinit.iteye.com/upload/picture/pic/102430/3a75dd13-1cb2-3bf1-8697-3f1264f1e5e8.jpg[/img]

该命令和《Java虚拟机规范》得到的不太一样,但起到的功能是一样的,可以查一下JVM 的在线文档,发现此命令的介绍如下:

if_icmpge pops the top two ints off the stack and compares them. If value2 is greater than or equal to value1, execution branches to the address (pc + branchoffset), where pc is the address of the if_icmpge opcode in the bytecode and branchoffset is a 16-bit signed integer parameter following the if_icmpge opcode in the bytecode. If value2 is less than value1, execution continues at the next instruction.

即将操作数栈中的两个int值弹出栈,然后比较它们,如果value2(即这里的0)大于或等于value1(即这里的100),则跳转至14行执行,否则就继续执行。很显然,这里0<100,所以继续执行下面的代码。


[b]STEP6--> 8: iinc 1, 1 [/b]
[img]http://glutinit.iteye.com/upload/picture/pic/102432/275e0d7d-9761-3e27-942f-3fe5c5418268.jpg[/img]

该命令给局部变量表的1号位置的int值增加1,如图,原来的0变成了1

[b]STEP7--> 11: goto 2 [/b]
很显然,这一条的命令就是让下一条执行语句跳至2,即 iload_1,然后便继
续执行…


[b]STEP8--> 14: return [/b]
当局部变量1号位置的值(即程序中的i)大于100后,便满足了[i]5: if_icmpge 14[/i]这条语句的条件,程序跳到14,遇到了return命令,该方法完成
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值