First try globals. Lua, Which is copied from lua1.0. Because lua1.0 has some doubts about the output of this program, execute it here.
The source code is as follows:
---------------------------
$ Debug
K, V = nextvar (k)
While K do
Print (k)
K, V = nextvar (k)
End
---------------------------
Execute the following output:
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
We can see that K and V are printed out, But K is printed out in lua1.0, and V is not. There should be a problem in lua1.0.
After a simple analysis, all the printed variables are global variables, including those registered by C and defined in Lua.
Type, tonumber, next, nextvar, print, dofile, and dostring are registered in table. C.
Readfrom, writeto, appendto, read, write, execute, remove these seven are Io library functions, registered in iolib. C.
Strfind, strlen, strsub, strlower, and strupper are string library functions and are registered in strlib. C.
Abs, sin, cos, tan, asin, ACOs, atan, Ceil, floor, Mod, SQRT, pow, Min, and Max are mathematical library functions in mathlib. c.
This is a total of 33 (7 + 7 + 5 + 14) registered functions. Pay attention to the number 33.
Let's take a look at the bytecode printed by the above program.
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
Brief Analysis of this bytecode:
------------------------------
K, V = nextvar (k)
3 pushglobal 3
6 pushmark
7 pushglobal 33
10 callfunc
Pushglobal 3. What is this 3? Note the 33 global variables registered above:
Type is 0, tonumber is 1, next is 2, nextvar is 3, print is 4... Min is 31, Max is 32.
The positions of these global variables in the symbol table increase sequentially.
So pushglobal 3 means to press nextvar to stack.
Pushmark label is used to press the stack. This is mainly used to find parameters for function calls.
Pushglobal 33. What is this 33? The position of 33 in the symbol table is K, just as output above. V is 34. So here it means K-pressure stack.
Callfunc function call corresponds to nextvar (k) in the code ).
------------------------------
K, V = nextvar (k)
15 adjust 2
16 storeglobal 34
19 storeglobal 33
Adjust 2 adjusts the stack. This function has two return values.
Storeglobal 34
Storeglobal 33
Assign the returned result to K and V. The return values of the function are in reverse order, so here we can see that we assign values to V (storeglobal 34) and then assign values to K (storeglobal 33 ).
------------------------------
While K do
25 pushglobal 33
28 iffjmp 38
Pushglobal 33 global variable v pressure stack.
If iffjmp 38 is false (that is, V is nil), jump down to 38 bytes.
Let's see where the jump is. Add the Offset Value of the next command: 31 + 38 = 69; 69 is halt, and it ends.
The PC Method for Calculating the code execution position is the same as that in the Assembly. The relative position to jump to is the position relative to the next instruction.
------------------------------
Print (k)
34 pushglobal 4
37 pushmark
38 pushglobal 33
41 callfunc
43 adjust 0
Pushglobal 4 -- print pressure Stack
Pushmark -- add tags
Pushglobal 33 -- k pressure Stack
Callfunc -- function call
Adjust 0 -- no return value
------------------------------
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
The bytecode here is the same as the first line.
The upjmp in the last sentence is a jump up, the offset of the next command is 69-44 = 25, and the 25 rows are pushglobal 33, which is just in the place of "while K do.
Lua1.1 Program Analysis 1