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 ...
随机推荐
- photoshop出现错误:要求96和8之间的整数。已插入最接近的数值
win10升级后出现该问题.我用的是ps cc2014 解决办法:修改注册表 计算机\HKEY_CURRENT_USER\Software\Adobe\Photoshop\80 新建的是DWORD(3 ...
- B树和B+树详解
一 B树 1.B树的定义:B树(B-tree)是一种树状数据结构,它能够存储数据.对其进行排序并允许以O(log n)的时间复杂度运行进行查找.顺序读取.插入和删除的数据结构.B树,概括来说是一个节点 ...
- 关于Oracle使用管理员账号登录失败的问题
我在本地建的Oracle数据库在调试自己写的存储过程的时候提示缺少 debug connect session 权限,一般情况下根据这个提示直接用管理员账号登录进去,执行 grant debug co ...
- Activiti6-TaskService(学习笔记)重要
任务管理服务: 可以看出来,TaskService操作对象,主要针对于UserTask, 对于业务方来说,最重要的就是用户任务,可以对用户任务进行增删改查的管理.可以对相关流程的控制.也可以设置一些用 ...
- js的数组的一些操作
1 arr.reduce let xxx = arr.reduce( function (pv, cv, ci ,arr) { return }[, init_val] ) 对arr的每个元素,执行匿 ...
- P1140 相似基因 (dp)
题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了44种核苷酸,简记作A,C,G,TA,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. 在一个人类基因工作组的任务 ...
- 关于bytes和bytearray
背景 平时工作因为有批量线上数据进行更新,通过Python程序连接数据库,利用连接池和gevent的并发性能,处理大量数据. 因为数据方提供的数据表结构中带有varbinary类型字段,并非全部,所以 ...
- GWAS后续分析:LocusZoom图的绘制
LocusZoom图几乎是GWAS文章的必备图形之一,其主要作用是可以快速可视化GWAS找出来的信号在基因组的具体信息:比如周围有没有高度连锁的位点,高度连锁的位点是否也显著. 下面是locuszoo ...
- 织梦dede如何获取图集调用第一张图片完美解决方法【5.7sp2版本】
制作产品图集多图效果的时候,常常需要获取图集第一张图片的功能,假设获取的是缩略图,那么缩略图不够大的情况下,第一展示效果就会很差,下面来介绍下如何获取调用织梦图集第一张图片的方法: 首先在 inclu ...
- CF451E Devu and Flowers
多重集求组合数,注意到\(n = 20\)所以可以用\(2 ^ n * n\)的容斥来写. 如果没有限制那么答案就是\(C(n + s - 1, n - 1)\).对每一个限制依次考虑,加上有一种选多 ...