之前说到可以使用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. ubuntu下安装mongodb

    https://www.cnblogs.com/shileima/p/7823434.html

  2. beanshell断言模版

    if("${createTime_1}".equals("${createTime_2}")){ Failure = false; FailureMessage ...

  3. nginx的配置与应用

    Nginx在应用程序中主要有以下作用(应用):1.解决跨域.2.请求过滤.3.配置Gzip.4.负载均衡.5.静态资源服务器. Nginx的配置结构 Nginx主要是通过修改配置文件nginx.con ...

  4. git的安装(和远程仓库建立连接)

    安装完git 1.配置用户名和邮箱 $ git config --global user.name "My Name"  $ git config --global user.em ...

  5. Nginx HTTP变量原理

    L:72 首先如何获取url追加参数值 如: http://www.xxx.com?a=1&b=2 return '$arg_a, $arg_b'; #通过前缀 arg_a 就能获取到 参数a ...

  6. Tomcat 配置文件 server.xml

    Tomcat隶属于Apache基金会,是开源的轻量级Web应用服务器,使用非常广泛.server.xml是Tomcat中最重要的配置文件,server.xml的每一个元素都对应了Tomcat中的一个组 ...

  7. dsu on tree 树上启发式合并 学习笔记

    近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...

  8. sourceinsight问题

    1.添加.cc文件 Options-〉“Document   Options”-〉在“File   filter”   裡邊加上*.cc Project--->Add and Remove Pr ...

  9. <02>labSQL的配置和使用方法

    任务布置:制作简单地铁站点管理系统<2> 要求一:正确配置系统,建立基本正常的数据通道:要求二:实现地铁站点的登记,拥有查询功能: 正文: 今天介绍labview虚拟仪器软件中  labS ...

  10. 【tensorflow】学习笔记

    1.tensorflow中dynamic_rnn和rnn有什么区别?    在tensorflow中没有找到rnn这个方法难道是废弃掉了? rnn是静态图,比如有10个时间序列,那么它将全部展开,并且 ...