7、指令集
大约 1 分钟
知识扩展
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