第5章 指令集和解释器

Java虚拟机顾名思义,就是一台虚拟的机器,而字节码(bytecode)就是运行在这台虚拟机器上的机器码
每一个类或者接口都会被Java编译器编译成一个class文件,类或接口的方法信息就放在class文件的method_info结构中 。
如果方法不是抽象的,也不是本地方法,方法的Java代码就会被编译器编译成字节码(即使方法是空的,编译器也会生成一条return语句),存放在method_info结构的Code属性中。

package jvmgo.book.ch03;

public class ClassFileTest {
    
    public static final boolean FLAG = true;
    public static final byte BYTE = 123;
    public static final char X = 'X';
    public static final short SHORT = 12345;
    public static final int INT = 123456789;
    public static final long LONG = 12345678901L;
    public static final float PI = 3.14f;
    public static final double E = 2.71828;
    
    public static void main(String[] args) throws RuntimeException {
        System.out.println("Hello, World!");
    }
}

方法信息就放在class文件的method_info结构中,方法的Java代码编译成字节码存method_info的Code属性的code子属性中

字节码中存放编码后的Java虚拟机指令。每条指令都以一个单字节的操作码(opcode)开头,这就是字节码名称的由来。由于只使用一字节表示操作码,显而易见,Java虚拟机最多只能支持256(2^8 )条指令。
到第八版为止,Java虚拟机规范已经定义了205条指令,操作码分别是0(0x00)到202(0xCA)、254(0xFE)和255(0xFF)。
这205条指令构成了Java虚拟机的指令集(instruction set)。

和汇编语言类似,为了便于记忆,Java虚拟机规范给每个操作码都指定了一个助记符(mnemonic)。比如操作码是0x00这条指令,因为它什么也不做,所以它的助记符是nop(no operation)。

Java虚拟机使用的是变长指令,操作码后面可以跟零字节或多字节的操作数(operand)。如果把指令想象成函数的话,操作数就是它的参数。为了让编码后的字节码更加紧凑,很多操作码本身就隐含了操作数,比如把常数0推入操作数栈的指令是iconst_0。

0xB2

可以看到,该指令的操作码是0xB2,助记符是getstatic。

它的操作数是0x0002,代表常量池里的第二个常量。


0x0002

在第4章中讨论过,操作数栈和局部变量表只存放数据的值,并不记录数据类型。
结果就是:指令必须知道自己在操作什么类型的数据。这一点也直接反映在了操作码的助记符上。
例如,
iadd指令就是对int值进行加法操作;
dstore指令把操作数栈顶的double值弹出,存储到局部变量表中;
areturn从方法中返回引用值。
也就是说,如果某类指令可以操作不同类型的变量,则助记符的第一个字母表示变量类型。

Java虚拟机规范把已经定义的205条指令按用途分成了11类:

  • 常量(constants)指令:
    把常量推入操作数栈顶。常量可以来自三个地方:隐含在操作码里、操作数运行时常量池。常量指令共有21条

加载(loads)指令、
存储(stores)指令、
操作数栈(stack)指令、
数学(math)指令、
转换(conversions)指令、
比较(comparisons)指令、
控制(control)指令、
引用(references)指令、
扩展(extended)指令
保留(reserved)指令。

保留指令一共有3条。其中一条是留给调试器的,用于实现断点,操作码是202(0xCA),助记符是breakpoint
另外两条留给Java虚拟机实现内部使用,操作码分别是254(0xFE)和266(0xFF),助记符是impdep1impdep2
这三条指令不允许出现在class文件中。

5.2 指令和指令解码

Java虚拟机规范的2.11节介绍了Java虚拟机解释器的大致逻

do {
  atomically calculate pc and fetch opcode at pc;
  if (operands) fetch operands;
  execute the action for the opcode;
} while (there is more to do);

每次循环都包含三个部分:
计算pc、指令解码、指令执行。
go伪代码

for {
  pc := calculatePC()
  opcode := bytecode[pc]
  inst := createInst(opcode)
  inst.fetchOperands(bytecode)
  inst.execute()
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,783评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,360评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,942评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,507评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,324评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,299评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,685评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,358评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,652评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,704评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,465评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,318评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,711评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,991评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,265评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,661评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,864评论 2 335

推荐阅读更多精彩内容

  • 第6章类文件结构 6.1 概述 6.2 无关性基石 6.3 Class类文件的结构 java虚拟机不和包括java...
    kennethan阅读 903评论 0 2
  • Java 虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至...
    好好学习Sun阅读 536评论 0 0
  • 银东县城有位刘大妈,她可是位在方圆百里小有名气的接生婆。 刘大妈从二十几岁便开始为人接生,到五十多岁,经她接生的孩...
    无为山人阅读 486评论 0 0
  • 一 再几日 可夭夭 可灼灼 冠名的潭水 吟为美酒千盅 嫣红轻浅 寻作城南的优柔 我打马驰过 以笔作鞭 谁是我的汪伦...
    张纲阅读 171评论 0 1
  • 成了成年人,终于知道了成年人的焦虑。我妈发烧住院的几天,我要照顾妈妈又要照顾女朋友,感觉哪一点做不好就心里对不起她...
    A01琪公子阅读 182评论 0 0