我正在编写一个字节码编译器和一个虚拟机。我可以通过将任何非整数值放入常量池并将 4 字节整数地址推入堆栈来使用常量。那部分很好。
但现在我添加了全局变量,这些变量存储在我称之为“Ram”的虚拟内存区域中。当然,我存储在那里的值也会像常量一样按地址索引。因此,假设我将两个地址压入操作数堆栈,然后运行我的 FADD(浮动加法) - 当指令将两个地址从堆栈中弹出以执行加法时,它如何知道这些地址是否来自全局内存而不是到常量池?标准方法是什么?
我正在编写一个字节码编译器和一个虚拟机。我可以通过将任何非整数值放入常量池并将 4 字节整数地址推入堆栈来使用常量。那部分很好。
但现在我添加了全局变量,这些变量存储在我称之为“Ram”的虚拟内存区域中。当然,我存储在那里的值也会像常量一样按地址索引。因此,假设我将两个地址压入操作数堆栈,然后运行我的 FADD(浮动加法) - 当指令将两个地址从堆栈中弹出以执行加法时,它如何知道这些地址是否来自全局内存而不是到常量池?标准方法是什么?
FADD
不应该弹出堆栈的地址,它应该弹出值。
您应该有关于常量和读取内存的说明。这些指令应该将结果值压入堆栈——而不是常量表中的索引或地址。常量的索引不应该被压入堆栈 - 常量本身的值应该。
FADD
然后应该简单地从堆栈中弹出两个值并添加它们 - 它不需要在常量表或内存中查找任何内容,因为这应该已经由专门的指令处理。
例如,给定常量 table [0: 1.0, 1: 0x10]
,添加1.0
到存储在地址0x10
(假设为 4.2)的任何值的指令可能如下所示(假设CONST
指令将常量表中给定索引处的值压入堆栈和LOAD
指令弹出堆栈的地址并将该地址的值压入堆栈):
FCONST 0 // Stack: [1.0]
ICONST 1 // Stack: [1.0, 0x10]
FLOAD // Stack: [1.0, 4.2]
FADD // Stack: [5.2]