Virtual Machine
之前说到可以使用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的更多相关文章
- Azure PowerShell (6) 设置单个Virtual Machine Endpoint
<Windows Azure Platform 系列文章目录> 请注意: - Azure不支持增加Endpoint Range - 最多可以增加Endpoint数量为150 http:// ...
- Azure PowerShell (7) 使用CSV文件批量设置Virtual Machine Endpoint
<Windows Azure Platform 系列文章目录> 请注意: - Azure不支持增加Endpoint Range - 最多可以增加Endpoint数量为150 http:// ...
- (学)解决VMware Taking ownership of this virtual machine failed
原文:http://blog.csdn.net/fisher_jiang/article/details/6992588背景: 一次crash可能会造成虚拟机锁死的情况发生现象:点击take owne ...
- Azure Virtual Machine 之 如何利用Management Class Libraries 创建VM
之前发的blog简单的介绍了如何使用Management Class Libraries 来控制Azure platform. 但由于官方并没有提供文档,所以我们只能够通过自己研究来摸索使用该类库的方 ...
- fail to create java virtual machine..
今天打开zend stdio 的时候 出现的错误 fail to create java virtual machine... 然后找度娘了,,都说改xxxxx, 我打开360 ,把内存清理了一遍 ...
- VMware Workstation cannot connect to the virtual machine 解决方案
今天 打开虚拟机 忽然遇到这个问题: VMware Workstation cannot connect to the virtual machine. Make sure you have righ ...
- [New Portal]Windows Azure Virtual Machine (11) 在本地使用Hyper-V制作虚拟机模板,并上传至Azure (1)
<Windows Azure Platform 系列文章目录> 本章介绍的内容是将本地Hyper-V的VHD,上传到Azure数据中心,作为自定义的虚拟机模板. 注意:因为在制作VHD的最 ...
- [New Portal]Windows Azure Virtual Machine (12) 在本地使用Hyper-V制作虚拟机模板,并上传至Azure (2)
<Windows Azure Platform 系列文章目录> 本章介绍的内容是将本地Hyper-V的VHD,上传到Azure数据中心,作为自定义的虚拟机模板. 注意:因为在制作VHD的最 ...
- [New Portal]Windows Azure Virtual Machine (13) 在本地使用Hyper-V制作虚拟机模板,并上传至Azure (3)
<Windows Azure Platform 系列文章目录> 本章介绍的内容是将本地Hyper-V的VHD,上传到Azure数据中心,作为自定义的虚拟机模板. 注意:因为在制作VHD的最 ...
- [New Portal]Windows Azure Virtual Machine (14) 在本地制作数据文件VHD并上传至Azure(1)
<Windows Azure Platform 系列文章目录> 之前的内容里,我介绍了如何将本地的Server 2012中文版 VHD上传至Windows Azure,并创建基于该Serv ...
随机推荐
- ubuntu下安装mongodb
https://www.cnblogs.com/shileima/p/7823434.html
- beanshell断言模版
if("${createTime_1}".equals("${createTime_2}")){ Failure = false; FailureMessage ...
- nginx的配置与应用
Nginx在应用程序中主要有以下作用(应用):1.解决跨域.2.请求过滤.3.配置Gzip.4.负载均衡.5.静态资源服务器. Nginx的配置结构 Nginx主要是通过修改配置文件nginx.con ...
- git的安装(和远程仓库建立连接)
安装完git 1.配置用户名和邮箱 $ git config --global user.name "My Name" $ git config --global user.em ...
- Nginx HTTP变量原理
L:72 首先如何获取url追加参数值 如: http://www.xxx.com?a=1&b=2 return '$arg_a, $arg_b'; #通过前缀 arg_a 就能获取到 参数a ...
- Tomcat 配置文件 server.xml
Tomcat隶属于Apache基金会,是开源的轻量级Web应用服务器,使用非常广泛.server.xml是Tomcat中最重要的配置文件,server.xml的每一个元素都对应了Tomcat中的一个组 ...
- dsu on tree 树上启发式合并 学习笔记
近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...
- sourceinsight问题
1.添加.cc文件 Options-〉“Document Options”-〉在“File filter” 裡邊加上*.cc Project--->Add and Remove Pr ...
- <02>labSQL的配置和使用方法
任务布置:制作简单地铁站点管理系统<2> 要求一:正确配置系统,建立基本正常的数据通道:要求二:实现地铁站点的登记,拥有查询功能: 正文: 今天介绍labview虚拟仪器软件中 labS ...
- 【tensorflow】学习笔记
1.tensorflow中dynamic_rnn和rnn有什么区别? 在tensorflow中没有找到rnn这个方法难道是废弃掉了? rnn是静态图,比如有10个时间序列,那么它将全部展开,并且 ...