跳至主要內容

7、指令集

引领潮流大约 1 分钟手动编写jvm虚拟机jvmgo

知识扩展

method_info[]

找到属性为code代码,二进制进行解析

魔法数是0x OPCODE

java虚拟机指令 以opcode开头

java虚拟机256条指令

定义205条指令 0~202 (0x00~0xCA)、0xFE、0xFF

定义助记符

例如 0x00 助记符 nop

指令集方法

普通计算压栈出栈

控制访问偏移量

指令集做两件事

1、读取操作码

2、执行操作数栈

type Instruction interface {
	FetchOperands(reader *BytecodeReader) //读取操作码
	Execute(frame *rtda.Frame) //执行操作数栈
}

// 1. 没有操作数的指令
type NoOperandsInstruction struct{}

func (self *NoOperandsInstruction) FetchOperands(reader *ByteCodeReader) {
	// nothing to do
}

// 2. 跳转指令 ->用于跳转下一个方法
type BranchInstruction struct {
	Offset int // 跳转偏移量
}

func (self *BranchInstruction) FetchOperands(reader *ByteCodeReader) {
	self.Offset = int(reader.ReadInt16()) // 从字节码中读取一个两字节的数,作为偏移量
}

branch.go

func Branch(frame *rtda.Frame, offset int) {
	pc := frame.Thread().PC()
	nextpc := pc + offset
	frame.SetNextPC(nextpc)
}

add指令

压栈出栈做计算

type IADD struct{ base.NoOperandsInstruction }

func (self *IADD) Execute(frame *rtda.Frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	result := v1 + v2
	stack.PushInt(result)
}

goto指令

偏移量offset做控制

type GOTO struct {
	base.BranchInstruction
}

func (self *GOTO) Execute(frame *rtda.Frame) {
	base.Branch(frame, self.Offset)
}

实战项目地址

https://gitee.com/yinlingchaoliu/jvmgo.git