之前说到可以使用Assembly language来实现程序编写,把程序通过一个Assembler就可以得到计算机可以操作的二进制文件。

但是Assembly language依旧不适于编程,但怎么将高级编程语言转变为Assembly language呢,该课程的思路是类似JAVA,先将其转换为VM language,再将VM language转化为Assembly language。

所以首先需了解VM language。其共有4种指令:

下面将分别介绍。

1)Memory segment commands

在VM里很重要的一个概念就是Stack。其实就是把寄存器当作一个stack,第0个寄存器的值RAM[0]就是栈顶的位置。比如说RAM[0]=257,就表示当前的栈顶是第257个寄存器,通过修改RAM[0]的值,就可以修改栈顶的位置。然后就可以使用push/pop了。

该课程很鸡肋的地方,就是提了个指针的概念:定义SP = RAM[0],*SP表示当前栈顶的值。要push一个值a,就令*SP = a;SP++; 要pop一个值,就令SP--;

好吧,问题来了,指针实际上既不是VM language,也不是Assembly language,只是该课程为了描述栈提出的一个概念,那具体怎么和这两者联系起来呢?举例如下,这里很容易模糊的地方是,在指针里,SP就表示栈顶地址,但在Assembly里SP表示第1个寄存器的地址!真是讨厌。

VM code:

push constant 17;

指针:

*SP = 17;SP++;

Assembly code:

@17

D = M

@SP

A = M

M = D

@SP

M = M+1

上面提到了 push constant i,对于constant,直接push就可以了,但对于别的类型数据local/static/this/that/temp/pointer,就要分类型存储了。

分类存储的思路就用到了类似汇编里段地址的概念,就是把内存分成一段段的。在数据里没有变量名的概念,但有变量名对应的地址表,这里就不考虑变量名。

在该课程中,具体设置如下:

默认SP的范围为256~2047;

对于constant类型数据,刚刚也说了,直接push到SP的范围内;

对于local类型数据,其base address存入第1个寄存器,即为RAM[1],那么local对应的stack里的第i个值的地址就是RAM[1] + i,其值就是RAM[ RAM[1]+i ]。类似于SP指向栈顶地址,定义LCL指向local类型数据的base address。类似地,ARG-RAM[2]、THIS-RAM[3]、THAT-RAM[4]。对于这些数据,其base address的具体值暂无设置规则,只要知道其值就可以了;

对于static类型数据,在Assembly中会直接将其作为一个变量,变量的申明和使用同Hack programming,其范围为16~255;

temp的范围为5~12,13~15用于general purpose registers;另外还有pointer,只能取值0/1,指向this/that,还没弄明白有啥用。

2)Arithmetic/Logical commands

假设是add,就会pop出两个数a、b,然后执行a+b,再push回去。其他类似。

3)Branching commands

goto label:无条件jump

if-goto label:先判断再jump

4)Function commands

在高级编程语言里,经常会用到各种函数。为描述其实现细节,课程里举了个很好的例子。假设有个机器人正在扫地,你突然给它下个指令让它端杯水来,机器人会怎么做?正常的流程应该是把扫地的指令记住,再执行端水,再返回继续扫地。其实和执行函数是一个道理,为了记住当前状态,就会使用到栈。

先分别解释几个commands的意思:

function foo nVars:声明函数foo,local variables数目为nVars;

call foo nArgs:请求执行函数foo,实参数目为nArgs;因此执行这一command之前,要先push nArgs个参数

return:执行call操作后,原先的nArgs个参数被清空,且栈顶为返回值

看起来很神奇,怎么利用栈来实现执行函数foo呢?更具体的说,怎么把这个VM code 转化为 Assembly code呢?可以先看下面这个例子

首先,function foo nVars这一语句会被定义为LABEL,使用goto/if-goto就可以实现函数的调用。

但怎么保存当前的状态呢?保存LCL/ARG/THIS/THAT就好了;

怎么将foo需要的参数传过去呢?重新定义ARG就好了。注意之前已经保存了ARG,所以重新定义也不要紧;

然后为local variables push nVars个0。做完这些就可以使用使用goto进入foo函数内部啦。

进入函数内部执行操作后,到了该返回值的时候了。首先可以将要返回的值赋给ARG指向的寄存器,然后程序该走向何方呢?

说明应该要记住foo被调用的地方,这样才能回去。这里就又用到了LABEL,定义一个returnAddress的LABEL,并在调用函数前就push进去。关于这里为什么要使用临时变量retAdd,课程给出的答案是,“if the function has no arguments, the next command, which is *arg = pop(), will override the return address” 不太理解...

没有去编程实现,看后面需要吧。

Virtual Machine的更多相关文章

  1. Azure PowerShell (6) 设置单个Virtual Machine Endpoint

    <Windows Azure Platform 系列文章目录> 请注意: - Azure不支持增加Endpoint Range - 最多可以增加Endpoint数量为150 http:// ...

  2. Azure PowerShell (7) 使用CSV文件批量设置Virtual Machine Endpoint

    <Windows Azure Platform 系列文章目录> 请注意: - Azure不支持增加Endpoint Range - 最多可以增加Endpoint数量为150 http:// ...

  3. (学)解决VMware Taking ownership of this virtual machine failed

    原文:http://blog.csdn.net/fisher_jiang/article/details/6992588背景: 一次crash可能会造成虚拟机锁死的情况发生现象:点击take owne ...

  4. Azure Virtual Machine 之 如何利用Management Class Libraries 创建VM

    之前发的blog简单的介绍了如何使用Management Class Libraries 来控制Azure platform. 但由于官方并没有提供文档,所以我们只能够通过自己研究来摸索使用该类库的方 ...

  5. fail to create java virtual machine..

    今天打开zend stdio 的时候 出现的错误  fail to create java virtual machine... 然后找度娘了,,都说改xxxxx, 我打开360  ,把内存清理了一遍 ...

  6. VMware Workstation cannot connect to the virtual machine 解决方案

    今天 打开虚拟机 忽然遇到这个问题: VMware Workstation cannot connect to the virtual machine. Make sure you have righ ...

  7. [New Portal]Windows Azure Virtual Machine (11) 在本地使用Hyper-V制作虚拟机模板,并上传至Azure (1)

    <Windows Azure Platform 系列文章目录> 本章介绍的内容是将本地Hyper-V的VHD,上传到Azure数据中心,作为自定义的虚拟机模板. 注意:因为在制作VHD的最 ...

  8. [New Portal]Windows Azure Virtual Machine (12) 在本地使用Hyper-V制作虚拟机模板,并上传至Azure (2)

    <Windows Azure Platform 系列文章目录> 本章介绍的内容是将本地Hyper-V的VHD,上传到Azure数据中心,作为自定义的虚拟机模板. 注意:因为在制作VHD的最 ...

  9. [New Portal]Windows Azure Virtual Machine (13) 在本地使用Hyper-V制作虚拟机模板,并上传至Azure (3)

    <Windows Azure Platform 系列文章目录> 本章介绍的内容是将本地Hyper-V的VHD,上传到Azure数据中心,作为自定义的虚拟机模板. 注意:因为在制作VHD的最 ...

  10. [New Portal]Windows Azure Virtual Machine (14) 在本地制作数据文件VHD并上传至Azure(1)

    <Windows Azure Platform 系列文章目录> 之前的内容里,我介绍了如何将本地的Server 2012中文版 VHD上传至Windows Azure,并创建基于该Serv ...

随机推荐

  1. photoshop出现错误:要求96和8之间的整数。已插入最接近的数值

    win10升级后出现该问题.我用的是ps cc2014 解决办法:修改注册表 计算机\HKEY_CURRENT_USER\Software\Adobe\Photoshop\80 新建的是DWORD(3 ...

  2. B树和B+树详解

    一 B树 1.B树的定义:B树(B-tree)是一种树状数据结构,它能够存储数据.对其进行排序并允许以O(log n)的时间复杂度运行进行查找.顺序读取.插入和删除的数据结构.B树,概括来说是一个节点 ...

  3. 关于Oracle使用管理员账号登录失败的问题

    我在本地建的Oracle数据库在调试自己写的存储过程的时候提示缺少 debug connect session 权限,一般情况下根据这个提示直接用管理员账号登录进去,执行 grant debug co ...

  4. Activiti6-TaskService(学习笔记)重要

    任务管理服务: 可以看出来,TaskService操作对象,主要针对于UserTask, 对于业务方来说,最重要的就是用户任务,可以对用户任务进行增删改查的管理.可以对相关流程的控制.也可以设置一些用 ...

  5. js的数组的一些操作

    1 arr.reduce let xxx = arr.reduce( function (pv, cv, ci ,arr) { return }[, init_val] ) 对arr的每个元素,执行匿 ...

  6. P1140 相似基因 (dp)

    题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了44种核苷酸,简记作A,C,G,TA,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. 在一个人类基因工作组的任务 ...

  7. 关于bytes和bytearray

    背景 平时工作因为有批量线上数据进行更新,通过Python程序连接数据库,利用连接池和gevent的并发性能,处理大量数据. 因为数据方提供的数据表结构中带有varbinary类型字段,并非全部,所以 ...

  8. GWAS后续分析:LocusZoom图的绘制

    LocusZoom图几乎是GWAS文章的必备图形之一,其主要作用是可以快速可视化GWAS找出来的信号在基因组的具体信息:比如周围有没有高度连锁的位点,高度连锁的位点是否也显著. 下面是locuszoo ...

  9. 织梦dede如何获取图集调用第一张图片完美解决方法【5.7sp2版本】

    制作产品图集多图效果的时候,常常需要获取图集第一张图片的功能,假设获取的是缩略图,那么缩略图不够大的情况下,第一展示效果就会很差,下面来介绍下如何获取调用织梦图集第一张图片的方法: 首先在 inclu ...

  10. CF451E Devu and Flowers

    多重集求组合数,注意到\(n = 20\)所以可以用\(2 ^ n * n\)的容斥来写. 如果没有限制那么答案就是\(C(n + s - 1, n - 1)\).对每一个限制依次考虑,加上有一种选多 ...