<转>字节码指令
本文转自:http://www.cnblogs.com/nazhizq/p/6525263.html
在llimits.h文件中定义了指令的类型。其实就是32个字节。
typedef lu_int32 Instruction;
上节说到变量最终会存入proto的数组k中,返回的索引放在expdesc *var->u.s.info。那么这个索引就是用来生成中间码的指令。如下。
int e = luaK_exp2anyreg(fs, ex);//返回寄存器索引
luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);//生成指令
首先讲一下lua指令的构造,如图。简单来说就是把32位字节分割一下,低位的6个字节表示的是哪一种操作指令, 即opcode; 后面的分为2个参数和三个参数的情况。参数代表的计算在寄存器中的索引,寄存器可以想象成一个数组。
例如,如果指令的三段分别代表,“add 0 1”.表示的意思是对两个数求和,两个数分别在寄存器中,索引为0 和 1 的地方。
lopcodes.h定义了相关方法。其实就是些二进制的操作,可以获取指定范围内的比特值。不熟悉的同学可以先学习C语言的二进制运算。
#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
lopcodes.c中定义了相关参数的比特长度:
enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
/*
** size and position of opcode arguments.
*/
#define SIZE_C 9
#define SIZE_B 9
#define SIZE_Bx (SIZE_C + SIZE_B)
#define SIZE_A 8
#define SIZE_OP 6
#define POS_OP 0
#define POS_A (POS_OP + SIZE_OP)
#define POS_C (POS_A + SIZE_A)
#define POS_B (POS_C + SIZE_C)
#define POS_Bx POS_C
生成指令时,主要依据以下的格式:
#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T A B C mode opcode */
opmode(, , OpArgR, OpArgN, iABC) /* OP_MOVE */
,opmode(, , OpArgK, OpArgN, iABx) /* OP_LOADK */
,opmode(, , OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
,opmode(, , OpArgR, OpArgN, iABC) /* OP_LOADNIL */
,opmode(, , OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
,opmode(, , OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
,opmode(, , OpArgR, OpArgK, iABC) /* OP_GETTABLE */
,opmode(, , OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
......
} #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
生成指令后,那么寄存器的地址和函数类型proto是如何对应的呢,如下图
至此,生成中间码指令的过程就分析完了。下一步重点关注lua本身的数据结构。
<转>字节码指令的更多相关文章
- invokedynamic字节码指令
1. 方法引用和invokedynamic invokedynamic是jvm指令集里面最复杂的一条.本文将从高观点的角度下分析invokedynamic指令是如何实现方法引用(Method refe ...
- [四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式
前言简介 前文已经对虚拟机进行过了简单的介绍,并且也对class文件结构,以及字节码指令进行了详尽的说明 想要了解JVM的运行机制,以及如何优化你的代码,你还需要了解一下,java编译器到底是 ...
- JVM总括三-字节码、字节码指令、JIT编译执行
JVM总括三-字节码.字节码指令.JIT编译执行 目录:JVM总括:目录 java文件编译后的class文件,java跨平台的中间层,JVM通过对字节码的解释执行(执行模式,还有JIT编译执行,下面讲 ...
- jvm理论-字节码指令
Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成. 基本数据类型 1.除了l ...
- i++ 和 ++i的字节码指令
代码 public class Test{ public static void main(String args[]){ int i=0;i=i++; System.out.println(i);} ...
- 大话+图说:Java字节码指令——只为让你懂
前言 随着Java开发技术不断被推到新的高度,对于Java程序员来讲越来越需要具备对更深入的基础性技术的理解,比如Java字节码指令.不然,可能很难深入理解一些时下的新框架.新技术,盲目一味追新也会越 ...
- 深入理解java虚拟机(六)字节码指令简介
Java虚拟机指令是由(占用一个字节长度.代表某种特定操作含义的数字)操作码Opcode,以及跟随在其后的零至多个代表此操作所需参数的称为操作数 Operands 构成的.由于Java虚拟机是面向操作 ...
- 深入了解java虚拟机(JVM) 第十章 字节码指令
一.字节码指令的含义 Java字节码指令由一个字节长度的,代表某种特定操作含义的数字(操作码)以及其后的零至多个代表此操作所需参数(操作数).此外字节码指令是面向操作数栈的,这里操作数栈在功能上对应实 ...
- Java字节码指令
1. 简介 Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码)以及跟随其后的零至多个代表此操作所需参数(称为操作数)而构成. 由于Java虚拟机采用面向操作数栈而不是寄存 ...
- Java字节码指令收集大全
Java字节码指令大全 常量入栈指令 指令码 操作码(助记符) 操作数 描述(栈指操作数栈) 0x01 aconst_null null值入栈. 0x02 iconst_m1 -1(int)值入栈. ...
随机推荐
- 极光推送 JPush 简介 集成 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- mysql启动报错cannot allocate memory for the buffer pool处理
今天启动mysql服务器时失败了.去/var/log/mysql/查看error.log,报错信息如下: 160123 22:29:26 InnoDB: Initializing buffer poo ...
- 基于Bootstrap+jQuery.validate Form表单验证实践
基于Bootstrap jQuery.validate Form表单验证实践 项目结构 : github 上源码地址:https://github.com/starzou/front-end- ...
- Mongoose vs mongodb native driver – what to prefer?
Paul Shan 7th Jun 2015 Mongoose or mongodb native driver, which one to use? This is one of the ini ...
- android中实现简单的聊天功能
这个例子只是简单的实现了单机版的聊天功能,自己跟自己聊,啦啦~~ 主要还是展示RecyclerView控件的使用吧~ 参考我之前写的文章: android中RecyclerView控件的使用 andr ...
- Jenkins知识地图
转自:http://blog.csdn.net/feiniao1221/article/details/10259449 这篇文章大概写于三个月前,当时写了个大纲列表,但是在CSDN上传资源实在不方便 ...
- 部分Android或IOS手机拍照后照片被旋转的问题
1.我们平时手机拍的照片,传到电脑后,使用Photoshop或者其它图片浏览工具打开时,发现图片是被转过的.可是Windows上预览却是正的.其实原因是部分Android或IOS手机拍照后,将图片角度 ...
- 忘记MySQL root密码重置MySQL root密码
(1)停止mysql# /etc/init.d/mysql stop(2)以不检查权限的方式启动# mysqld --skip-grant-tables &(3)登录mysql修改root用户 ...
- JAVA开发总结
1.Float取整 long warning; float fwarning = 0f; fwarning = total*0.34/100; warning = new Float(fwarning ...
- flume杀掉重启
Flume在启动的过程中加了一个钩子处理线程,用kill -3或者kill杀掉Flume进程,这样能通知钩子线程去关闭这些tmp文件 直接kill-9 会永久保留hdfs上的tmp后缀文件