« VC 对 memcpy 的优化 | 返回首页 | 书终于出版了 »

实现一个虚拟机

在编程的世界中,只有你想不到的事情,懒的做的事情,没有做不到的事情。

曾经一度为使用哪种脚本嵌入游戏犯愁,lua 的源码过了几遍,python 的也看了点。lcc 也试过,还有 ch 什么的。真正用在项目里的就是 lua 和 python 了。我个人更偏好 lua 一点。越读它的 source code 越觉得它作为世界上最快的脚本语言,是名副其实。

很早以前,我觉得显示一个图片很难,好象发现很简单。曾经觉得汇编很难,结果发现很简单。曾经担心 C++ 太复杂学不会,现在已经感觉游刃有余了。还有学习 perl php 或者是 stl mfc 这样的库,不懂的时候都觉得难,懂了却是不过如此。

对于游戏,说什么掌握 3d ,网络编程,无非是些技术方向而已。肯花时间,一定没问题的。

这次是脚本虚拟机。已经想了很久了,怕太复杂需要投入过多时间和精力。可事实上,写起来却又一次发现不过如此。

上周五开始有这个念头的。自己实现脚本,一可以再享受一次编码的兴奋。二是自己实现的东西方便控制,想加什么加什么,想改什么改什么。语言也可以重新设计。三就是性能心里有底,看了那么多人家的实现,该怎么做好,也应该有数了。最后就是安全问题。网络游戏防外挂和逆向工程的问题,嘿嘿。估计是学术上为人鄙视,但我不得不重视的环节。

一开始我想用纯 C 做。不为别的,就是想练习一下 C 语言的功底。写了 1500 行程序,花了两天一晚。周日的时候,写到 gc 的部分就受不了了。对比以前写的 C 程序,感觉好了很多。但是比较自己的 C++ 代码,还是不够优美。一咬牙,C++ 重构。

到批昨天晚上,已经把先实现的东西弄完了。大约实现了基本逻辑,和堆栈,table ,函数等的支持,2000多行代码。最后 gc 模块写的比较顺利。用的标记整理算法。做的时候希望运行时减少一些大块内存移动。就在内部做了分页。原来以后是个小优化,后来为这个吃够了苦头。

晚上的时候, gc 完成,用 byte code 写了一个递归算阶程的小程序测试,并定义了函数嵌套。结果问题百出啊。最近几年写程序越写越顺,都有点飘飘然了。觉得自己编码几乎不会出错。腹稿一般都打的比较好。这次做设计也是腹稿打了很久,去年年末就在想实现了。酝酿到现在才动手写,觉得出了错也是小问题的。没想到,bug 折磨了一夜。

最初的问题来至于我对 byte code 本身的处理。byte code 我也设计成了 gc object 可以被回收和整理的。结果,一段被执行的代码也成了不稳定的东西,运行了一半,gc 跑起来,可能运行指针都飞了。后半截代码有可能不在原来的位置。这是现在发现设计考虑不成熟的唯一一个地方。解决了这个问题之后,就开始漫长的 debug 。

因为我是真正的内存整理的 gc ,所以的 gc object 都可能不在他们原来的位置,甚至任何一个虚拟机调用后,指针都会变的不可靠。而且监控内存很不方便。前面采用的分页整理害苦了我。而且第一页还是一个特别页,stack 会 share 一部分空间。这样虽然可以保证整个虚拟机跑在几大快内存上,绝对不产生任何内存碎片,但是 gc 代码异常复杂。

最近又比较累,半夜里头脑开始不清醒,只好到处加 assert。好在测试程序写的还可以,加的越多,新问题就越少。直到白天中午。才确保问题都被找到。

这次写这个东西,我悟到几个道理:
一个把 C 语言代码能写的非常优美的人,写 C++ 会更上一层楼。以后应该多多写纯 C 代码提高 C++ 功力。
熬夜写代码是兴奋的,但是熬夜调试复杂的程序,最好少干。
原理弄懂了,没有什么程序难写。但是原理自己悟的效果要好过看书。

下一步就是写编译器了 :)

Comments

在Google搜索``语言 虚拟机 实现''结果来到了这里,虽然云风大大没有讲具体是怎么做的,不过倒是看到了一点和我一样的东西:用递归定义的阶乘来测试——哈哈,我也是这样呢;-)虽然我只是写个解释器,不带虚拟机的而已~

路过进来看看!!

怎么回事啊

哦、、天拉‘’这些编程的我是一点也不通啊

兄弟,您现在还在搞虚拟机吗,我现在在写一个可以运行有流程控制语句的脚本语言的虚拟机,想请教点经验.

C脚本和虚拟机我3年前就做出来了
http://www.kipway.com

看着你们都是高手,想多请教一下。
我的email:clcarwin@gmail.com

计划做一个ia32虚拟机,请指点指点呀!

可以学到新的东西,可以更加理解别人的设计并用的更好。

用在自己的游戏上更加不容易被破解。

可以根据实际情况调整实现,达到更高的效率。

想问问自己研究虚拟机的设计有些什么应用价值,能否举几个例子?

前期的分析、编译和基本的虚拟机都还好,特别是对于比较简单的语法而言。但是真个系统的完成仅仅依赖语法分析、编译和虚拟机是不够的。后面的系统函数、执行二进制文件、代码库的互相包含都是非常重要而且必须实现的东西,很可惜,这些东西在书上都很难找到资料,而且往上资料也不多。大家只好自己摸索摸索了。另外,面向对象的实现也比过程的实现复杂很多。

编译器可以先定义好语言的结构,有了巴科斯范式后,先用lex/yacc生成一个做做实验,修改语法,比较满意后再动笔自己写。楼主,还是不要晚睡,要不对身体没好处,我以前也这样,深受其害。

现在在无比头痛的写编译器中,已经两天4点才睡觉了。

无奈,白天杂事太多。出差太久思路需要好一阵子才回的来。

我想这些东西尽信书不如无书,遇到问题就找资料终归不太好。我现在在做一遍扫描的编译器。不想扫描那么多次。

实现虚拟机的中文文章就找到这篇,最近写编译器,还好有点编译原理的底子,基本上编译前端没有什么好说的,后端的代码优化就头疼了,写一个玩玩的虚拟机也没什么,要写实用的太多问题要考虑,不知楼主有什么资料?BTW,顺便看了你的主页,武钢三中,莫不是在青山区红钢城?

读书的时候我没有好好学C,现在有点后悔了.
现在又想学JAVA.哎~~~~~

哈哈,老大,我是搁一会又来看贴子,终于看到您回复了,好激动呀,老大您是在广州?小弟今年刚毕业在广州工作!

交个朋友嘛 :D
我曾经也想做一个 IA32 的模拟器的

呵呵,云风老大,一直很想攀你这个朋友,不知道有没有这个福气!
我也曾经对这个感兴趣,自己动手写过一个ia-32的虚拟机,所有的ia-32常规指令都能执行,反正upx的壳是能在我的这个小虚拟机下运行解出来的,以后有机会想老大请教!

我正在写脚本,欢迎到我的blog讨论脚本问题。
http://spaces.msn.com/members/gamedeveloper

大家多交流 :) 不过我做虚拟机主要是为了抵御逆向工程,所以更多的是放在内存数据加密上。

也是这个原因,几乎不可能公开 source code 了。

从我个人的角度,倒是想把源代码公布出来的,自己写的好的程序,能给大家看才是乐趣。

本人目前正在开发一个支持静态元编程的开放式Lua语言编译器:
http://www.luachina.org/projects/openlua/

虚拟机也是我的下一步计划。

希望能与你多多交流。

用自己的解释器要比公开源码的方外挂容易得多,而且控制在自己手里,修改起来很方便,可以随心所欲的构造

在编程的世界中,只有你想不到的事情,懒的做的事情,没有做不到的事情。

这句话说得真好!强烈赞同!

我现在逐步减少对IDE的依赖了。目前做项目全部用 editplus + bjam 。make tool 真的很重要,过分依赖 IDE ,结果开发手段都被约束住了。

嗯,Michael Abrash 在他的书里面说的好只有去应用才能算掌握了技术.佩服云风,这点做的非常好!

大二时候想过做虚拟机,理论的准备后备受打击,太难了;

大三时候朋友说一起做个编译器,没有下文...

看了你的东西,唉,高手之所以高手悟性,勤奋....看自己没有那么一点点..

:P 写代码是享受啊
以前上学的时候跟一个年轻老师聊天 我问他,最常用的开发工具是什么?嘿嘿 是Word。结果我现在最常用的开发工具不是Word,是vi。呵呵。都用来写文档了。

Post a comment

非这个主题相关的留言请到:留言本