标签: vm-implementation

编译器如何在少数寄存器中存储数百个变量?

假设你有一个只有 4 个寄存器 A、B、C 和 D 的虚拟机。编译器如何用有限的空间存储如此多的变量?

是否有多种方法可以做到这一点,或者是否有一种可靠的方法可以实现这一点?这个奇特的科学术语是什么?它被认为是一个复杂的问题吗?

compiler-construction register-allocation cpu-registers vm-implementation

2
推荐指数
1
解决办法
509
查看次数

以字节码格式存储值

我已经用 Java 创建了一个原型 VM(因为它是我最熟悉的语言),并且我尝试以字节码格式存储指令。我想知道如何在字节码中存储值,因为byte只能是 0 到 255。

举个例子:

push 4752
Run Code Online (Sandbox Code Playgroud)

Push 的操作码值为 0。但是我如何存储 4752?它不适合单个字节。我可以将值存储在 4 个字节中,因此允许它们是 32 位整数,但随后我必须决定是加载操作码(1 个字节)还是一个值(4 个字节)。目前,我将程序作为整数数组传递,VM 循环遍历该数组并执行操作码。如果操作码需要一个值,它会从数组中获取该值,然后增加程序计数器以跳过该值,以便它不会被执行。

我试图弄清楚像 JVM 这样的虚拟机是如何做到这一点的,但我无法找到答案。

bytecode vm-implementation

2
推荐指数
1
解决办法
450
查看次数

在JIT编译器中使用ebp + 6而不是+8

我正在VM中实现一个简单的JIT编译器,我正在为了好玩而写作(主要是为了更多地了解语言设计)而且我得到了一些奇怪的行为,也许有人可以告诉我为什么.

首先,我为C和C++定义了一个JIT"原型":

#ifdef __cplusplus 
    typedef void* (*_JIT_METHOD) (...);
#else
    typedef (*_JIT_METHOD) ();
#endif
Run Code Online (Sandbox Code Playgroud)

我有一个compile()函数,可以将东西编译成ASM并将其粘贴到内存中:

void* compile (void* something)
{
    // grab some memory
    unsigned char* buffer = (unsigned char*) malloc (1024);

    // xor eax, eax
    // inc eax
    // inc eax
    // inc eax
    // ret -> eax should be 3
    /* WORKS!
    buffer[0] = 0x67;
    buffer[1] = 0x31;
    buffer[2] = 0xC0;
    buffer[3] = 0x67;
    buffer[4] = 0x40;
    buffer[5] = 0x67;
    buffer[6] = 0x40;
    buffer[7] = 0x67;
    buffer[8] …
Run Code Online (Sandbox Code Playgroud)

c c++ assembly jit vm-implementation

1
推荐指数
2
解决办法
402
查看次数

python vm每次编译方法吗?

如果我有一个在我的模块中的几个地方调用的函数,虚拟机是否仅在第一次执行函数时将其编译为本机代码,而不是在其他调用中使用兑现代码?(比如.NET jit编译器)

python vm-implementation

1
推荐指数
1
解决办法
238
查看次数

如何将不同的原始数据加载到操作数堆栈

JVM有两条指令:( bipush操作数值应介于Byte.MIN_VALUE和之间Byte.MAX_VALUE.)和sipush(操作数值应介于Short.MIN_VALUE和之间Short.MAX_VALUE).相应地,MethodVisitorASM中提供API来操作这两个指令:

      public void visitIntInsn(int opcode, int operand)
Run Code Online (Sandbox Code Playgroud)

因此,如何访问ASM中的其他非字节(短)基元?例如,原语long,double,int,boolean,和float数据?这看起来很奇怪,这些数据被封装为Long,Double,Integer.

jvm bytecode java-bytecode-asm vm-implementation

1
推荐指数
1
解决办法
612
查看次数

在C中,确保为多个代码段修复了汇编指令的数量

在我正在编写的虚拟机中,我希望能够以类似于以下伪代码的方式调度命令.

add: reg[memory[pc+1]] =  reg[memory[pc+1]] + reg[memory[pc+2]]; pc += 2; goto done;
sub: reg[memory[pc+1]] =  reg[memory[pc+1]] - reg[memory[pc+2]]; pc += 2; goto done;
cmp: /* Would take more space than simply x = x + y; */ goto done;

for(int pc = 0; memory[pc] != END; pc++) {
    goto currentPositionInMemorySomehow + (memory[pc] * lengthOfInstruction);
    done:
}
Run Code Online (Sandbox Code Playgroud)

其中memory是包含字节码的数组,pc是程序计数器.但要做到这一点,我们要求跳转到的每个位置在下一个块之前具有完全相同的指令数.除非有一个很棒的平台无关的汇编代码,否则不能选择下载到汇编代码,这样就可以使用相同的代码并编译到Linux,Mac和Windows.无论每个处理器都坐在上面.任何和所有的帮助将不胜感激.

c assembly goto dispatch vm-implementation

0
推荐指数
1
解决办法
132
查看次数

静态变量加载过程

最近,我研究虚拟机如何加载静态变量,但是我遇到的问题如下:

public class Example{

    static{
        num = 3;
        System.out.print(num);
    }
    public static int num;
}
Run Code Online (Sandbox Code Playgroud)

编译器报告错误.我认为num有记忆区和价值.为什么我不能访问num变量?

java jvm compiler-errors vm-implementation

0
推荐指数
1
解决办法
105
查看次数

cpu指令如何工作?

在我理解的32位处理器中,每条指令都是32位.那么,对于汇编中的MOV指令,如何仅将32位用于操作码加参数?因此对于:

MOV register, [address]
Run Code Online (Sandbox Code Playgroud)

地址本身不占用32位吗?那么这不会占用整个指令吗?也许我错了,但我正在尝试用C/C++实现一个VM.救命?

c++ assembly vm-implementation

0
推荐指数
2
解决办法
1024
查看次数