Lua1.1 程序分析一

先试下 globals.lua, 这个是从 Lua1.0 那里拷贝过来的。因为在 Lua1.0 里对这个程序的输出有点疑问,所以这里再执行一下它。

源代码如下:
---------------------------
$debug
k,v=nextvar(k)
while k do
 print(k)
 k,v=nextvar(k)
end
---------------------------
执行一下输出:
type
tonumber
next
nextvar
print
dofile
dostring
readfrom
writeto
appendto
read
write
execute
remove
strfind
strlen
strsub
strlower
strupper
abs
sin
cos
tan
asin
acos
atan
ceil
floor
mod
sqrt
pow
min
max
k
v
可以看到,k, v 都打印出来了,而在 Lua1.0 里只有 k 打印出来了, v 没有。Lua1.0 里应该有问题。
简单的分析下结果,这些打印出来的都是全局变量,包括由 C 注册的和 Lua 中定义的。
type,tonumber,next,nextvar,print,dofile,dostring 这 7 个是在 table.c 中注册。
readfrom,writeto,appendto,read,write,execute,remove 这 7 个是 IO 库函数,在iolib.c 中注册。
strfind,strlen,strsub,strlower,strupper 这 5 个是字符串库函数,在 strlib.c 中注册。
abs,sin,cos,tan,asin,acos,atan,ceil,floor,mod,sqrt,pow,min,max 这 14 个是数学库函数,在 mathlib.c 中注册。
这一共是 33 (7+7+5+14)个已经注册的函数,注意 33 这个数字。

再看下上面的那个程序打印出来的字节码
CODE
0 SETLINE 2
3 PUSHGLOBAL 3
6 PUSHMARK
7 PUSHGLOBAL 33
10 CALLFUNC
11 SETLINE 2
15 ADJUST 2
16 STOREGLOBAL 34
19 STOREGLOBAL 33
22 SETLINE 3
25 PUSHGLOBAL 33
28 IFFJMP 38
31 SETLINE 4
34 PUSHGLOBAL 4
37 PUSHMARK
38 PUSHGLOBAL 33
41 CALLFUNC
43 ADJUST 0
44 SETLINE 5
47 PUSHGLOBAL 3
50 PUSHMARK
51 PUSHGLOBAL 33
54 CALLFUNC
55 SETLINE 5
59 ADJUST 2
60 STOREGLOBAL 34
63 STOREGLOBAL 33
66 UPJMP 44
69 HALT

简单分析一下这段字节码:
------------------------------
k,v=nextvar(k)
3 PUSHGLOBAL 3
6 PUSHMARK
7 PUSHGLOBAL 33
10 CALLFUNC

PUSHGLOBAL 3 ,这个 3 是什么?注意上面说的注册的 33 个全局变量:
type 为 0,tonumber 为 1,next 为 2, nextvar 为 3,print 为 4... min 为 31, max 为 32。
这些全局变量在符号表中的位置依次递增。
所以 PUSHGLOBAL 3 的意思就是把 nextvar 压栈。

PUSHMARK 标签压栈,这个主要是为了在函数调用时找参数用。

PUSHGLOBAL 33 ,这个 33 是什么?符号表中 33 的位置是 k,就像上面输出的一样。v 为 34。 所以这里的意思是 k 压栈。

CALLFUNC 函数调用,对应的就是代码中的 nextvar(k)。
------------------------------
k,v=nextvar(k)
15 ADJUST 2
16 STOREGLOBAL 34
19 STOREGLOBAL 33

ADJUST 2 调整栈,这个函数有 2 个返回值。

STOREGLOBAL 34
STOREGLOBAL 33
把返回的结果赋值给 k,v。函数返回值的顺序是倒序,所以这里看到的是先给 v 赋值(STOREGLOBAL 34),再给 k 赋值(STOREGLOBAL 33)。
------------------------------
while k do
25 PUSHGLOBAL 33
28 IFFJMP 38

PUSHGLOBAL 33 全局变量 v 压栈。

IFFJMP 38 如果为假(就是 v 为 nil ),向下跳转 38 个字节。
看看跳转到哪儿了,下一条指令的偏移值加上它:31+38 =69; 69 为 HALT,结束。
这里的计算代码执行位置 pc 的方法和在汇编中的效果一样,跳转到的相对位置都是指相对下一条指令的位置。
------------------------------
print(k)
34 PUSHGLOBAL 4
37 PUSHMARK
38 PUSHGLOBAL 33
41 CALLFUNC
43 ADJUST 0

PUSHGLOBAL 4 -- print 压栈
PUSHMARK -- 加标签
PUSHGLOBAL 33 -- k 压栈
CALLFUNC -- 函数调用
ADJUST 0 -- 无返回值
------------------------------
k,v=nextvar(k)
47 PUSHGLOBAL 3
50 PUSHMARK
51 PUSHGLOBAL 33
54 CALLFUNC
55 SETLINE 5
59 ADJUST 2
60 STOREGLOBAL 34
63 STOREGLOBAL 33
66 UPJMP 44

这里的字节码和第一行一样。
最后一句的 UPJMP 为向上跳,下一条指令的偏移 69-44 = 25, 25 行是 PUSHGLOBAL 33 刚好到了 "while k do" 这个地方。

时间: 2024-10-12 23:02:00

Lua1.1 程序分析一的相关文章

基于时间片轮转程序分析进程调度

张雨梅   原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10000 背景知识 一般程序运行过程中都会发生中断,发生中断时,CPU先把当前的内容保存,然后执行中断程序,中断返回时,根据保存的内容恢复现场.这次实验用一个简单的时间片轮转程序分析进程调度的过程. 实验过程 使用实验楼的虚拟机操作,实验代码在mykernel中找,包括3个c文件,mypcb.h,mymain.c,myinterrupt.c. 打开

linux程序分析工具介绍(一)—-”/proc”

写在最前面:在开始本文之前,笔者认为先有必要介绍一下linux下的man,如果读者手头用linux系统,直接在终端输入man man便可以看到详细的说明,我在这里简单的总结一下,man命令是用来查看linux下各种命令.工具等的用户手册(manual)的.一种比较常用的用法是"man n field",这里的n是要查找的手册了类型,field是关键字.在这里介绍一下n: 0 /usr/include下的头文件 1 可执行程序和shell命令 2 系统调用 3 系统库函数 4 /dev下

(IOS)BaiduFM 程序分析

本文主要分享下楼主在学习Swift编程过程中,对GitHub上的一个开源app BaiduFM的研究心得. 项目地址:https://github.com/belm/BaiduFM-Swift 一.项目简介 项目通过使用百度音乐的API实现了播放.下载与收藏音乐的FM基本功能.同时实现了歌词滚动,显示实时进度条,支持后台播放,锁屏显示歌曲信息及控制播放等附加功能并添加了对Apple Watch的支持.此APP可谓是功能十分强劲,下面楼主就来好好分析下这款APP的代码及功能实现原理. 二.APP

Hadoop之MapReduce程序分析

摘要:Hadoop之MapReduce程序包括三个部分:Mapper,Reducer和作业执行.本文介绍和分析MapReduce程序三部分结构. 关键词:MapReduce   Mapper  Reducer   作业执行 MapReduce程序包括三个部分,分别是Mapper,Reducer和作业执行. Mapper 一个类要充当Mapper需要继承MapReduceBase并实现Mapper接口. Mapper接口负责数据处理阶段.它采用形式为Mapper<K1,V1,K2,V2>的Jav

linux程序分析工具介绍(三)——sar

本文要介绍的sar,是linux下用来分析系统本身运行情况的非常有用的工具.我们知道,程序在操作系统上要运行,要关注的点不外乎内存,CPU和IO(包括磁盘IO和网络IO).我们的应用程序在操作系统中运行前,我们需要了解系统当前的内存,cpu和IO的使用状况,还需要明白我们的应用程序运行时自身所需要的内存,cpu和IO资源的情况.只有操作系统剩余的内存,cpu和IO资源能够满足应用程序所需要的,才能保证应用程序在操作系统中正常的运行.sar就是用来帮助我们了解操作系统当前内存,cpu和IO等资源的

linux程序分析工具介绍(二)—-ldd,nm

本文要介绍的ldd和nm是linux下,两个用来分析程序很实用的工具.ldd是用来分析程序运行时需要依赖的动态库的工具:nm是用来查看指定程序中的符号表相关内容的工具.下面通过例子,分别来介绍一下这两个工具: 1. ldd, 先看下面的例子, 用ldd查看cs程序所依赖的动态库: [email protected]:~/Public$ ldd cs linux-gate.so.1 => (0xffffe000) libz.so.1 => /lib/libz.so.1 (0xb7f8c000)

代码实现:判断101-200之间有多少个素数(质数),并输出所有素数。 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。

package com.heima.Coding; /* 判断101-200之间有多少个素数(质数),并输出所有素数. 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数.*/ public class Test { public static void main(String[] args) { int count = 0; for (int i = 100; i < 200; i++) { for (int j = 2; j <=

Lua1.0 代码分析 库

Lua1.0 代码分析 库库的代码相对比较简单.这里以数学库为例进行说明.比如看下这个取绝对值的数学函数 static void math_abs (void) {  double d;  lua_Object o = lua_getparam (1);  if (o == NULL)  { lua_error ("too few arguments to function `abs'"); return; }  if (!lua_isnumber(o))  { lua_error (

C#程序分析

一.程序及问题 阅读下面程序,请回答如下问题: 问题1:这个程序要找的是符合什么条件的数? 问题2:这样的数存在么?符合这一条件的最小的数是什么? 问题3:在电脑上运行这一程序,你估计多长时间才能输出第一个结果?时间精确到分钟(电脑:单核CPU 4.0G Hz,内存和硬盘等资源充足). 问题4:在多核电脑上如何提高这一程序的运行效率? using System; using System.Collections.Generic; using System.Text; namespace Find