机器指令翻译成 JavaScript —— No.6 深度优化
第一篇 中我们曾提到,JavaScript 最终还得经过浏览器来解析。因此可以把一些优化工作,交给脚本引擎来完成。
现代浏览器的优化能力确实很强,但是,运行时的优化终归是有限的。如果能在事先实现,则可投入更多资源,优化得更充分。
优化尝试
指令 1:1 翻译成 JS,结果显然会存在一些累赘的逻辑。
例如状态标志,很多时候是不必计算的:
A = read(10) // LDA 10
SR_N = ... // 无意义,可以去除
SR_Z = ...
X = read(20) // LDX 20
SR_N = ... // 值得商榷
SR_Z = ...
if (!SR_Z) { // BNE ..
nextFn = ...
return
}
Y = read(30) // LDY 30
SR_N = ...
SR_Z = ...
第一步的状态标志,会被后面的覆盖,显然是没必要计算的。但第二步,就有一些奥妙了。
如果 !SR_Z 成立,那么进入下一个流程块;否则执行 LDY,状态被重置。因此,要不要计算 SR_N,可以先看 SR_Z 的结果。
于是,可将顺序调整成:
X = read(20) // LDX 20
SR_Z = ...
if (!SR_Z) { // BNE ..
SR_N = ... // 移到这里
...
}
这样,就能避免无意义的计算。
此外,再对表达式进行合并,最终变成:
A = read(10) // LDA 10
X = read(20) // LDX 20
if (X != 0) { // BNE ..
SR_N = (X > 127)
nextFn = ...
return
}
Y = read(30) // LDY 30
SR_N = (Y > 127)
SR_Z = (Y == 0)
看起来就更精简了。
再进一步,若能发现 nextFn 不依赖该流程的状态标记,那么 SR 的计算也可以省略!
其他,还有诸如 inline 优化。例如一些简单的跳转:
JSR L1
XXX 1
XXX 2
L1:
XXX 3
XXX 4
RTS
直接将其展开,于是变成:
XXX 3
XXX 4
XXX 1
XXX 2
这样就能减少指令块的分割,降低流程模拟的开销。
类似的优化方案还有很多。但是,若想亲自实现这些,则需要深厚的理论知识。并且实现起来也很麻烦,完全不适合这种周末时间的小研究。
借用工具
理论知识固然重要,但工程师的宗旨,就是最大程度利用现有资源,将想法快速变成现实。
这几篇文章都只是理论探讨,实现未必就得如此。事实上,我们应该借助现成的工具,快速验证想法。
既然前面提到优化,那就选择一个强大的优化方案 —— LLVM。
我们可以将 6502 指令逻辑,转换成 LLVM 中间表示。这样,即可用现成工具进行优化。
但是这么做有些麻烦。一是对 LLVM 不太熟悉,二是调试起来也不方便。
对于 LLVM 来说,最适合的输入语言当然是 C 了,毕竟 clang 就是为此产生的。

所以,我们不妨将 6502 指令翻译成 C 语言。C 不仅简单优雅,而且借助 IDE 开发调试都超级方便。
下一篇,我们尝试这个方案是否可行。
机器指令翻译成 JavaScript —— No.6 深度优化的更多相关文章
- 【探索】机器指令翻译成 JavaScript
前言 前些时候研究脚本混淆时,打算先学一些「程序流程」相关的概念.为了不因太枯燥而放弃,决定想一个有趣的案例,可以边探索边学. 于是想了一个话题:尝试将机器指令 1:1 翻译 成 JavaScript ...
- 机器指令翻译成 JavaScript —— No.5 指令变化
上一篇,我们通过内置解释器的方案,解决任意跳转的问题.同时,也提到另一个问题:如果指令发生变化,又该如何应对. 指令自改 如果指令加载到 RAM 中,那就和普通数据一样,也是可以随意修改的.然而,对应 ...
- 机器指令翻译成 JavaScript —— No.7 过渡语言
上一篇,我们决定使用 LLVM 来优化程序,并打算用 C 作为输入语言.现在我们来研究一下,将 6502 指令转换成 C 的可行性. 跳转支持 翻译成 C 语言,可比 JS 容易多了.因为 C 支持 ...
- 机器指令翻译成 JavaScript —— 终极目标
上一篇,我们顺利将 6502 指令翻译成 C 代码,并演示了一个案例. 现在,我们来完成最后的目标 -- 转换成 JavaScript. 中间码输出 我们之所以选择 C,就是为了使用 LLVM.现在来 ...
- 机器指令翻译成 JavaScript —— No.3 流程分割
上一篇 我们讨论了跳转指令,并实现「正跳转」的翻译,但最终困在「负跳转」上.而且,由于线程模型的差异,我们不能 1:1 的翻译,必须对流程进行一些改造. 当初之所以选择翻译,而不是模拟,就是出于性能考 ...
- 机器指令翻译成 JavaScript —— No.2 跳转处理
上一篇,我们发现大多数 6502 指令都可以直接 1:1 翻译成 JS 代码,但除了「跳转指令」. 跳转指令,分无条件跳转.条件跳转.从另一个角度,也可分: 静态跳转:目标地址已知 动态跳转:目标地址 ...
- 机器指令翻译成 JavaScript —— No.4 动态跳转
上一篇,我们用模拟流程的方式,解决了跳转问题. 不过静态跳转,好歹事先是知道来龙去脉的.而动态跳转,只有运行时才知道要去哪.既然流程都是未知的,翻译从何谈起? 动态跳转,平时出现的多吗?非常多!除了 ...
- 深度优化LNMP之Nginx [2]
深度优化LNMP之Nginx [2] 配置Nginx gzip 压缩实现性能优化 1.Nginx gzip压缩功能介绍 Nginx gzuo压缩模块提供了压缩文件内容的功能,用户请求 ...
- 四十年前的 6502 CPU 指令翻译成 JS 代码会是怎样
去年折腾的一个东西,之前 blog 里也写过,不过那时边琢磨边写,所以比较杂乱,现在简单完整地讲解一下. 前言 当时看到一本虚拟机相关的书,正好又在想 JS 混淆相关的事,无意中冒出个问题:能不能把某 ...
随机推荐
- 平台之大势何人能挡? 带着你的Net飞奔吧!
镇楼图: 跨平台系列: Linux基础 1.Linux基础学习 By dnt http://www.cnblogs.com/dunitian/p/4822807.html 环境配置 1.Hyper-v ...
- SQLSERVER走起微信公众帐号已经开通搜狗微信搜索
SQLSERVER走起微信公众帐号已经开通搜狗微信搜索 请打开下面链接 http://weixin.sogou.com/gzh?openid=oIWsFt-hiIb_oYqQHaBMoNwRB2wM ...
- 浅谈我对DDD领域驱动设计的理解
从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品 ...
- HTML 事件(四) 模拟事件操作
本篇主要介绍HTML DOM中事件的模拟操作. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4. ...
- 解读发布:.NET Core RC2 and .NET Core SDK Preview 1
先看一下 .NET Core(包含 ASP.NET Core)的路线图: Beta6: 2015年7月27日 Beta7: 2015年9月2日 Beta8: 2015年10月15日 RC1: 2015 ...
- [开发笔记]yum错误
yum 错误TypeError: rpmdb open failed 解决办法 是因为RPM数据库出现损坏导致的,它导致所有的软件的升级.安装甚至是删除都会出现问题,终端出现乱码,YUMEX也用不成, ...
- 从啥也不会到可以胜任最基本的JavaWeb工作,推荐给新人的学习路线(二)
在上一节中,主要阐述了JavaScript方面的学习路线.先列举一下我朋友的经历,他去过培训机构,说是4个月后月薪过万,虽然他现在还未达到这个指标. 培训机构一般的套路是这样:先教JavaSE,什么都 ...
- js面向对象学习 - 对象概念及创建对象
原文地址:js面向对象学习笔记 一.对象概念 对象是什么?对象是“无序属性的集合,其属性可以包括基本值,对象或者函数”.也就是一组名值对的无序集合. 对象的特性(不可直接访问),也就是属性包含两种,数 ...
- JavaScript作用域
JavaScript作用域 JavaScript作用域一直是前端开发的难题,现在只要用五句话就可解决. 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个 ...
- android绘制圆形图片的两种方式
看下效果先 下面有完整的示例代码 使用BitmapShader(着色器) 我们在绘制view 的时候 就是小学上美术课 用水彩笔在本子上画画 使用着色器绘制圆形图片最简单的理解方式 就是把bitmap ...