标签: vm-implementation

什么是Smali Code Android

我将学习一些关于Dalvik VM,dex和Smali的知识.

我读过关于smali的内容,但仍然无法清楚地了解它在编译器链中的位置.它的目的是什么.
这里有一些问题:

  1. 据我所知,dalvik作为其他虚拟机运行字节码,在Android的情况下它是dex字节码.
  2. 什么是小?Android OS或Dalvik Vm是否直接使用它,或者它只是相同的dex字节码,但对人类更具可读性?
  3. 它是像Windows的dissasembler(如OllyDbg)程序可执行程序由不同的机器代码(例如D3,5F)组成,并且每个机器代码都有适当的汇编命令,但Dalvik Vm也是软件,因此smali是字节码的可读表示
  4. 有新的ART环境.它仍然使用字节码或直接执行本机代码吗?

先感谢您.

android dalvik dex smali vm-implementation

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

什么阻止了有效的Haskell虚拟机(如JVM)?

我一直想知道,是什么阻碍了像JVM或PyPy for Haskell这样的高效虚拟机的开发(除了可能的开发工作)?是语言结构吗?我认为难以有效解释的语言(如Python,非常动态)已经拥有了不错的虚拟机.

另外,如果没有什么阻碍这样的实现,那么STG是否是一个很好的目标"字节码",因为所有优化都是在Core上完成的?

是否有讨论此主题的文章或博客文章?

编辑:

  • 我知道HaLVM,但我认为这不是我的意思.
  • 我也知道runhaskell,但它根本没有效率.

haskell jvm vm-implementation

27
推荐指数
4
解决办法
4620
查看次数

为什么需要虚拟机?

我正在阅读这个问题,以找出Java虚拟机和.NET CLR之间的差异,Benji的回答让我想知道为什么虚拟机首先是必要的.

根据我对Benji的解释的理解,虚拟机的JIT编译器将中间代码解释为在CPU上运行的实际汇编代码.它必须这样做的原因是因为CPU通常具有不同数量的寄存器,并且根据Benji的说法,"一些寄存器是特殊用途的,并且每个指令都要求其操作数在不同的寄存器中." 这是有道理的,因此需要像虚拟机这样的中间解释器,以便可以在任何CPU上运行相同的代码.

但是,如果是这种情况,那么我不明白为什么编译成机器代码的C或C++代码能够在任何计算机上运行,​​只要它是正确的操作系统.那么为什么我在使用Pentium的Windows机器上编译的C程序能够在我使用AMD的其他Windows机器上运行?

如果C代码可以在任何CPU上运行,那么虚拟机的目的是什么?是否可以在任何操作系统上运行相同的代码?我知道Java在几乎任何操作系统上都有VM版本但除了Windows之外还有其他操作系统的CLR吗?

或者还有其他我想念的东西?操作系统是否对其运行的汇编代码做了一些其他解释,以使其适应特定的CPU或其他东西?

我很好奇这一切是如何运作的,所以我们将非常感谢一个明确的解释.

注意:我之所以不在JVM与CLR问题中发表我的查询作为评论的原因是因为我没有足够的积分发表评论但= b.

编辑:感谢所有的好答案!所以我似乎缺少的是,虽然所有处理器都有差异,但是有一个共同的标准化,主要是X86架构,它提供了足够大的通用功能集,因此在一个X86处理器上编译的C代码将在大多数情况下工作在另一个X86处理器上.这进一步推动了虚拟机的正当性,更不用说我忘记了垃圾收集的重要性.

compiler-construction vm-implementation

26
推荐指数
4
解决办法
3949
查看次数

口译员与编译器与虚拟机

我有一个关于口译员,编译器和VM的问题

现在我知道解释器和编译器之间的差异但是前两个虚拟机有什么不同?VM在口译员和编译器上的优缺点是什么?

非常感谢

compiler-construction vm-implementation

26
推荐指数
3
解决办法
1万
查看次数

究竟是什么鹦鹉?

我知道Parrot是一个虚拟机,但我觉得我并没有完全理解它背后的想法.

据我所知,它是一个虚拟机,可以处理多种语言.它是否正确?

使用虚拟机而不仅仅是解释器有什么好处?

Parrot做的具体是什么让它变得如此重要?

perl jit parrot vm-implementation

24
推荐指数
4
解决办法
2389
查看次数

我将如何编写虚拟机

我对编程虚拟机很感兴趣,没有像虚拟机或vmware那样华丽,但可以模仿一个简单的架构,无论是cisc还是risc,比如Zilog,SPARC,MIPS或80686架构模型.

我想通过这样做,制作一个相同类型的模拟器会相对简单,我只是对使用它来获得经验感兴趣(作为我的第一个C项目,我宁愿在C中做这个比在还要别的吗).

vm-implementation

23
推荐指数
5
解决办法
2万
查看次数

任何汇编语言被认为有用所需的最小指令集是什么?

我正在研究汇编编程,所以我决定尝试用软件实现一个"虚拟微处理器",它有寄存器,标志和RAM来处理,用变量和数组实现.但是,由于我只想模拟任何微处理器的最基本行为,我想创建一个只有基本指令的汇编语言,只有那些没有它就没用的指令.我的意思是,有汇编语言可以执行乘法和交换寄存器值等,但这些操作不是基本的,因为您可以使用更简单的指令来实现它们.我不想实现那些指令.

我可以想象一些指令(我相信)必须始终以任何汇编语言存在,例如MOV移动字节和JP将指令指针发送到另一个地址.

你能否提出一套最基本和最基本的装配说明?谢谢!

assembly instruction-set microprocessors vm-implementation

23
推荐指数
4
解决办法
1万
查看次数

什么是VM,为什么动态语言需要一个?

因此,例如,Python和Java有VM,C和Haskell没有.(如我错了请纠正我)

考虑到线路两侧有哪些语言,我找不到原因.Java在很多方面都是静态的,而Haskell提供了许多动态功能.

c python java haskell vm-implementation

22
推荐指数
2
解决办法
4240
查看次数

VM设计:更多操作码或更少的操作码?什么是更好的?

不要被震惊.这是很多文字,但我害怕没有提供一些详细的信息,我无法真正展示这是什么(并可能得到很多答案,并没有真正解决我的问题).而这绝对不是一项任务(正如他的评论中有人可笑地声称的那样).

先决条件

由于除非至少设置了一些先决条件,否则根本无法回答此问题,以下是先决条件:

  • 应解释虚拟机代码.不禁止有JIT编译器,但设计应该以解释器为目标.
  • VM应基于寄存器,而不是基于堆栈.
  • 答案可能既没有假设有一组固定的寄存器,也没有无限数量的寄存器,或者可能是这种情况.

此外,我们需要更好地定义"更好".必须考虑几个属性:

  1. 磁盘上VM代码的存储空间.当然,您可以在此处废弃所有优化并仅压缩代码,但这会对(2)产生负面影响.
  2. 解码速度.如果将代码转换为可以直接执行的东西需要很长时间,那么存储代码的最佳方法是无用的.
  3. 内存中的存储空间.该代码必须可以在有或没有进一步解码的情况下直接执行,但是如果涉及进一步的解码,则在执行期间和每次执行指令时完成该编码(在将代码计数加载到项目2时仅解码一次).
  4. 代码的执行速度(考虑常见的解释器技术).
  5. 虚拟机的复杂性以及为其编写解释器的难度.
  6. VM自身需要的资源量.(如果VM运行的代码大小为2 KB并且执行速度比眨眼快,那么这不是一个好的设计,但它需要150 MB才能完成此操作并且其启动时间远远高于代码的运行时间它执行)

现在通过或多或少的操作码实际意味着我的例子.它可能看起来实际上设置了操作码的数量,因为每个操作需要一个操作码.然而,它并不那么容易.

用于相同操作的多个操作码

你可以进行类似的操作

ADD R1, R2, R3
Run Code Online (Sandbox Code Playgroud)

添加R1和R2的值,将结果写入R3.现在考虑以下特殊情况:

ADD R1, R2, R2
ADD R1, 1, R1
Run Code Online (Sandbox Code Playgroud)

这些是您在许多应用程序中可以找到的常见操作.您可以使用现有的操作码来表达它们(除非您需要不同的操作码,因为最后一个操作码具有int值而不是寄存器).但是,您也可以为这些创建特殊的操作码:

ADD2 R1, R2
INC R1
Run Code Online (Sandbox Code Playgroud)

和之前一样.优势在哪里?ADD2只需要两个参数,而不是3个,INC甚至只需要一个参数.因此,这可以在磁盘和/或内存中更紧凑地编码.由于将任何一种形式转换为另一种形式也很容易,因此解码步骤可以在两种方式之间转换以表达这些语句.不过,我不确定这两种形式会影响执行速度.

将两个操作码组合成一个操作码

现在让我们假设您有一个ADD_RRR(R表示寄存器)和一个LOAD来将数据加载到寄存器中.

LOAD value, R2
ADD_RRR R1, R2, R3
Run Code Online (Sandbox Code Playgroud)

您可以拥有这两个操作码并始终在整个代码中使用这样的构造...或者您可以将它们组合成一个名为ADD_RMR(M代表内存)的新操作码

ADD_RMR R1, value, R3
Run Code Online (Sandbox Code Playgroud)

数据类型与操作码

假设您有16位整数和32位整数作为本机类型.寄存器为32位,因此数据类型适合.现在,当您添加两个寄存器时,可以将数据类型设为参数:

ADD int16, R1, R2, R3
ADD int32, R1, R2, R3
Run Code Online (Sandbox Code Playgroud)

例如,对于有符号和无符号整数也是如此.这样,ADD可以是一个短操作码,一个字节,然后你有另一个字节(或者可能只是4位)告诉VM如何解释寄存器(它们是否保持16位或32位值).或者您可以废弃类型编码,而是有两个操作码:

ADD16 R1, R2, R3
ADD32 R1, R2, R3
Run Code Online (Sandbox Code Playgroud)

有些人可能会说两者完全相同 - 只是解释第一种方式,因为16位操作码可行.是的,但是一个非常幼稚的翻译可能看起来很不一样.例如,如果每个操作码有一个函数并使用switch语句调度(不是最好的方式,函数调用开销,switch语句也许不是最优的,我知道),这两个操作码可能如下所示:

case ADD16: add16(p1, p2, …
Run Code Online (Sandbox Code Playgroud)

performance interpreter opcode vm-implementation

21
推荐指数
2
解决办法
2822
查看次数

C++:双精度,精度,虚拟机和GCC

我有以下代码:

#include <cstdio>
int main()
{
   if ((1.0 + 0.1) != (1.0 + 0.1))
      printf("not equal\n");
    else
      printf("equal\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当使用gcc(4.4,4.5和4.6)使用O3编译并本机运行(ubuntu 10.10)时,它会打印预期的"相等"结果.

但是,当如上所述编译并在虚拟机(ubuntu 10.10,virtualbox image)上运行时,它输出"不相等"的情况下相同的代码 - 这是O3和O2标志设置但不是O1及以下时的情况.当使用clang(O3和O2)编译并在虚拟机上运行时,我得到了正确的结果.

我理解1.1无法使用double正确表示,我读过"每个计算机科学家应该知道浮点算术的内容"所以请不要指向我那里,这似乎是GCC做的某种优化不知何故似乎在虚拟机中不起作用.

有任何想法吗?

注意:C++标准说在这种情况下类型提升是依赖于实现的,可能是GCC使用更精确的内部表示,当应用不等式测试时,它是否成立 - 由于额外的精度?

UPDATE1:以上修改上面的代码,现在得到了正确的结果.在某些时候,无论出于何种原因,GCC都会关闭浮点控制字.

#include <cstdio>
void set_dpfpu() { unsigned int mode = 0x27F; asm ("fldcw %0" : : "m" (*&mode)); 
int main()
{
   set_dpfpu();
   if ((1.0 + 0.1) != (1.0 + 0.1))
      printf("not equal\n");
    else
      printf("equal\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

UPDATE2:对于那些询问代码的const表达性质的人,我已经改变了如下,并且在使用GCC编译时仍然失败. - 但我认为优化器也可能将以下内容转换为const表达式.

#include <cstdio>
void …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-construction optimization double-precision vm-implementation

21
推荐指数
2
解决办法
1416
查看次数