我问一个问题,关于C型尺寸,我得到一个很好的答案,但我意识到,我可能不会制定这个问题非常好是我的目的.
我的背景来自计算机工程师,然后转到软件工程师,所以我喜欢计算机架构,并且总是考虑制作VM.我刚刚完成了一个有趣的Java项目,我很自豪.但是有些法律问题我现在无法开源,而且我现在有空闲时间.所以我想看看我是否可以在C上制作另一个VM(速度更快),只是为了娱乐和教育.
事情是,我上次写一篇非琐事C问题时,我不是一个C程序,这是10多年前的事了.我是Pascal,Delphi,现在是Java和PHP程序员.
我可以预见有很多障碍,我正试图解决一个问题,那就是访问现有的库(在Java中,反射解决了这个问题).
我计划通过拥有一个数据缓冲区(类似于堆栈)来解决这个问题.我的VM客户端可以编程将数据放入这些堆栈,然后再指向本机函数.
int main(void) {
// Prepare stack
int aStackSize = 1024*4;
char *aStackData = malloc(aStackSize);
// Initialise stack
VMStack aStack;
VMStack_Initialize(&aStack, (char *)aStackData, aStackSize);
// Push in the parameters
char *Params = VMStack_CurrentPointer(&aStack);
VMStack_Push_int (&aStack, 10 ); // Push an int
VMStack_Push_double(&aStack, 15.3); // Push a double
// Prepare space for the expected return
char *Result = VMStack_CurrentPointer(&aStack);
VMStack_Push_double(&aStack, 0.0); // Push an empty double for result
// Execute
void (*NativeFunction)(char*, char*) = &Plus; …Run Code Online (Sandbox Code Playgroud) c memory-management cross-platform low-level vm-implementation
我在C中编写了一个虚拟机作为业余爱好项目.此虚拟机执行的代码与Intel语法x86程序集非常相似.问题是这个虚拟机使用的寄存器只是名称中的寄存器.在我的VM代码中,寄存器与x86寄存器一样使用,但机器将它们存储在系统内存中.在VM代码中使用寄存器而非系统内存没有性能改进.(我认为只有地方才能提高性能,但在实践中,没有任何改变.)
在解释程序时,此虚拟机将指令的参数存储为指针.这允许虚拟指令获取内存地址,常量值,虚拟寄存器或几乎任何参数.
由于硬件寄存器没有地址,我想不出将VM寄存器实际存储在硬件寄存器中的方法.在我的虚拟寄存器类型上使用register关键字不起作用,因为我必须得到一个指向虚拟寄存器的指针才能将其用作参数.有没有办法让这些虚拟寄存器更像他们的原生对应物?
如果有必要的话,我很乐意钻研装配.我知道JIT编译这个VM代码可以让我使用硬件寄存器,但我希望能够将它们与我的解释代码一起使用.
我正处于制作3D"机器人编程"游戏的设计阶段.受到Colobot,Robot Odyssey,Cholo等游戏的启发.
我希望游戏中的每个机器人都拥有自己独立的环境/操作系统/虚拟机,就像在现实生活中一样.应该对每个环境进行沙盒处理,使其在机器人与游戏其余部分的交互方式方面是本地的.
最初我打算按照"计算系统元素"一书中的描述实现HACK VM,但后来对于这种游戏风格的性能方面是否有更好的解决方案感到好奇.
所以我的问题是:是否已经存在可以很好地满足我的目的的虚拟机架构?
Ps使用的语言和游戏引擎尚未确定,但可能是C#或smalltalk.
我正在研究一个我希望能够与C接口的虚拟机.走另一条路,将虚拟机功能暴露给C代码相当容易,我无法解决的问题是将C函数暴露给一台虚拟机.
我希望能够像虚拟机一样动态注册C函数:
vm_register(printf);
Run Code Online (Sandbox Code Playgroud)
然后在我的虚拟机中,将参数推送到堆栈,并且:
call printf
Run Code Online (Sandbox Code Playgroud)
问题是,在不知道函数需要多少个参数以及什么类型的情况下,我不确定可以使用函数指针.
是否存在可在此情况下使用的通用函数指针类型?有人能引导我朝着正确的方向前进吗?
我想更好地理解类文件和内部/嵌套类,我想知道以下事情:
InnerClasses使用的属性来指tothe内/嵌套类在'containing'类或它在内部/嵌套类用来指所述"容器"类?InnerClasses类文件中的属性是否足够?例如,内部/嵌套类必须遵循名称修改$或这只是一个约定吗?InnerClasses属性,这取决于JLM供应商?(我记得听说IBM的实现在某些部分的要求不那么严格.)我尝试在JVM规范中查找它,但没有找到实际机制的描述.
我只在与我的问题远程连接的" InnerClasses属性"中找到了这句话:
Java虚拟机当前不检查InnerClasses属性与实际表示属性引用的类或接口的任何类文件的一致性.
为什么基于寄存器的虚拟机比基于堆栈的虚拟机更好?
具体来说,在Parrot VM的文档中,设计师解释了注册机的好处:
[...]高级语言中的许多程序由嵌套的函数和方法调用组成,有时使用词法变量来保存中间结果.在非JIT设置下,基于堆栈的VM将弹出,然后多次推送相同的操作数,而基于寄存器的VM将简单地分配适当数量的寄存器并对其进行操作,这可以显着减少操作量和CPU时间.
但为什么同样的操作数被推多次?
我在哪里可以找到官方和非官方Visual Basic 6规范的列表,这些规范可以让我完全解释VB6 EXE文件的内容并进行分析,或者单独解释它们而不是使用MSVBVM60.DLL?
类似于虚拟机及其语言的规范.
诸如操作码,指令,助记符,是否使用一个或多个堆栈,堆栈指针,寄存器等等.
我目前正在从事宠物编程语言(用于学习目的),并且在过去一年中经历了大量研究,我认为现在是时候开始建模这种语言的概念了.首先,我希望它能够编译成某种中间形式,例如JVM或.NET字节码,目标是兼容多平台/架构.其次,我希望它快速(我还有许多其他的东西,但这不是讨论这些主题的目的).
我想到的最佳选择是:编译为JVM字节码并使用OpenJDK作为运行时环境,编译为.NET字节码并使用Mono作为运行时环境,编译为LLVM IR并使用LLVM作为运行时环境.
正如您可能想象的那样,我选择了LLVM.为什么?因为它的速度非常快.我使用C++ N-Body代码进行了一些基准测试,并在我的机器中使用lli jitted IR实现了7s,而使用了clang本地编译代码的27s(我知道clang首先使IR成为机器代码).
所以,这是我的问题:我可以使用LLVM基本工具集(我只需要lli)的任何可再发行版本吗?或者我必须自己编译?如果是后者,你能否提供一些关于如何做的提示?如果我真的必须这样做,我想是从我的机器(英特尔Mac)交叉编译它们,并生成一些安装程序(例如,Windows的.msi,流行的Linux发行版的.rpm和.deb以及.pkg Mac电脑).请记住,我只需要LLVM的最小子集,这样通过使用"lli",该子集就能够像VM一样工作.这里真正的问题是如何将LLVM用作典型的虚拟机.
platform-agnostic multiplatform llvm llvm-ir vm-implementation
我们目前正在研究自己的Java虚拟机实现的JIT编译部分.我们现在的想法是将给定的Java字节码简单地转换为操作码,将它们写入可执行内存并直接调用方法的开头.
假设给定的Java代码是:
int a = 13372338;
int b = 32 * a;
return b;
Run Code Online (Sandbox Code Playgroud)
现在,进行了以下方法(假设给定的内存从0x1000开始,并且在eax中预期返回值):
0x1000: first local variable - accessible via [eip - 8]
0x1004: second local variable - accessible via [eip - 4]
0x1008: start of the code - accessible via [eip]
Java bytecode | Assembler code (NASM syntax)
--------------|------------------------------------------------------------------
| // start
| mov edx, eip
| push ebx
|
| // method content
ldc | mov eax, 13372338
| push eax
istore_0 | pop eax
| …Run Code Online (Sandbox Code Playgroud) 我需要分配大块内存(由我的自定义分配器使用),它们位于虚拟地址空间的前32GB内.
我想如果我需要,比方说,1MB块,我可以从低地址开始使用mmap和MAP_FIXED_NOREPLACE(或VirtualAlloc)以1MB的增量进行迭代,直到调用成功.从最后一个成功的块继续下一个.
这听起来很笨拙,但至少它会对OS地址空间布局的变化和ASLR算法的变化有所增强.根据我对当前操作系统布局的理解,前32GB应该有足够的内存,但是我可能会遗漏一些东西?
Windows,Linux,OS X,iOS或Android中有什么东西会破坏这个方案吗?有没有更好的办法?
如果您想知道,这是为了实现编程语言的VM,在64位系统上将所有指针拟合为32位值可以提供巨大的内存使用优势甚至速度增益.由于所有对象至少为8字节对齐,因此较低的3位可以移出,将指针范围从4GB扩展到32GB.
c++ operating-system memory-management mmap vm-implementation