本文转自: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本身的数据结构。

<转>字节码指令的更多相关文章

  1. invokedynamic字节码指令

    1. 方法引用和invokedynamic invokedynamic是jvm指令集里面最复杂的一条.本文将从高观点的角度下分析invokedynamic指令是如何实现方法引用(Method refe ...

  2. [四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式

      前言简介   前文已经对虚拟机进行过了简单的介绍,并且也对class文件结构,以及字节码指令进行了详尽的说明 想要了解JVM的运行机制,以及如何优化你的代码,你还需要了解一下,java编译器到底是 ...

  3. JVM总括三-字节码、字节码指令、JIT编译执行

    JVM总括三-字节码.字节码指令.JIT编译执行 目录:JVM总括:目录 java文件编译后的class文件,java跨平台的中间层,JVM通过对字节码的解释执行(执行模式,还有JIT编译执行,下面讲 ...

  4. jvm理论-字节码指令

    Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成. 基本数据类型 1.除了l ...

  5. i++ 和 ++i的字节码指令

    代码 public class Test{ public static void main(String args[]){ int i=0;i=i++; System.out.println(i);} ...

  6. 大话+图说:Java字节码指令——只为让你懂

    前言 随着Java开发技术不断被推到新的高度,对于Java程序员来讲越来越需要具备对更深入的基础性技术的理解,比如Java字节码指令.不然,可能很难深入理解一些时下的新框架.新技术,盲目一味追新也会越 ...

  7. 深入理解java虚拟机(六)字节码指令简介

    Java虚拟机指令是由(占用一个字节长度.代表某种特定操作含义的数字)操作码Opcode,以及跟随在其后的零至多个代表此操作所需参数的称为操作数 Operands 构成的.由于Java虚拟机是面向操作 ...

  8. 深入了解java虚拟机(JVM) 第十章 字节码指令

    一.字节码指令的含义 Java字节码指令由一个字节长度的,代表某种特定操作含义的数字(操作码)以及其后的零至多个代表此操作所需参数(操作数).此外字节码指令是面向操作数栈的,这里操作数栈在功能上对应实 ...

  9. Java字节码指令

    1. 简介 Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码)以及跟随其后的零至多个代表此操作所需参数(称为操作数)而构成. 由于Java虚拟机采用面向操作数栈而不是寄存 ...

  10. Java字节码指令收集大全

    Java字节码指令大全 常量入栈指令 指令码 操作码(助记符) 操作数 描述(栈指操作数栈) 0x01 aconst_null null值入栈. 0x02 iconst_m1 -1(int)值入栈. ...

随机推荐

  1. C#邮件发送(最坑爹的邮箱-QQ邮箱)

    最近工作挺清闲的,有空的时候陪妹子出去玩玩,自己看看小说,看看电影,日子过的挺欢乐的,这个星期幡然悔悟,代码才是我的最爱,做点小东西,就写个邮件发送程序.说的邮件发送相信工作过基本上都会用到过,用户注 ...

  2. CentOS 6和CentOS 7防火墙的关闭

    CentOS6.5查看防火墙的状态: 1 [linuxidc@localhost ~]$service iptable status 显示结果: 1 2 3 4 5 [linuxidc@localho ...

  3. Building LinkedIn’s Real-time Activity Data Pipeline

    转自:http://blog.163.com/guaiguai_family/blog/static/20078414520138911393767/ http://sites.computer.or ...

  4. Hibernate: No Session found for current thread

    在Struts2+Hibernate+Srping项目中经常会遇到这种问题 我知道的一种情况是: Spring的事务配置中没有配置好异常出现处的路径 <aop:advisor pointcut= ...

  5. C 语言宏定义

    C 语言宏定义1.例子如下: #define PRINT_STR(s) printf("%s",s.c_str()) string str = "abcd"; ...

  6. 一些常用&实用的Linux命令

    这些指令还是很常用的,最起码有些我每天都要用.当然,很多东西还是写成shell脚本用起来更方便. man 命令(查看一个命令的详细帮助信息) 命令 --help(显示一个命令的简单帮助信息) 命令 | ...

  7. Google Chrome Resize Plugin

    https://chrome.google.com/webstore/detail/window-resizer/kkelicaakdanhinjdeammmilcgefonfh

  8. Swift语言精要 - 浅谈结构体(Struct)

    CGRect, CGSize, CGPoint这些是 . String, Int, Array, Dictionary这些我们经常用的也是结构体(Struct). 那么结构体(Struct)到底是什么 ...

  9. 通示jQuery实例方法,未DOM对象添加多个方法

    <script type="text/javascript"> /* * 通示jQuery实例方法,未DOM对象添加多个方法 * 用按钮做多个事件的调用 */ (fun ...

  10. openfiler在esxi下的安装配置

    注意分区的时候如果硬盘太小自动分区会导致分配的卷大小不够用 后改为如下: 以root登录: 应该以openfiler登录,口令是password 也可以导入虚拟机安装 升级虚拟机硬件版本 终端登录用户 ...