mirror of
https://github.com/andremm/lad.git
synced 2026-08-22 12:16:25 -06:00
740 lines
24 KiB
HTML
740 lines
24 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>Lua Assembler/Disassembler</title>
|
|
<style type=text/css>
|
|
<!--
|
|
hr {
|
|
background-color: #BCAE79;
|
|
border-width: 1px;
|
|
color: #BCAE79;
|
|
height: 1px;
|
|
padding: 0;
|
|
width: 98%;
|
|
}
|
|
|
|
a {
|
|
text-decoration: none;
|
|
}
|
|
|
|
h3 {
|
|
color: #3175A2;
|
|
}
|
|
|
|
body {
|
|
background: #F4F4F4;
|
|
font-size: 12px;
|
|
line-height: 150%;
|
|
font-family: verdana, sans-serif
|
|
}
|
|
|
|
div#container {
|
|
width: 80%;
|
|
margin-left: 10%;
|
|
margin-right: 10%;
|
|
border: 1px solid #F0F0F0;
|
|
background: white;
|
|
}
|
|
|
|
div#logo {
|
|
margin: 2px 2px 2px 2px;
|
|
}
|
|
|
|
div#content {
|
|
margin: 20px 10px 10px 10px;
|
|
border: 1px solid #F0F0F0;
|
|
padding-left: 10px;
|
|
padding-right: 10px;
|
|
text-align: justify;
|
|
}
|
|
|
|
div#menu {
|
|
margin: 2px 2px 2px 20px;
|
|
}
|
|
|
|
div#footer {
|
|
margin: 2px 10px 20px 10px;
|
|
clear: both;
|
|
border: 1px solid #F0F0F0;
|
|
}
|
|
|
|
.lua-code {
|
|
background-color: #F4F4F4;
|
|
border: 1px solid silver;
|
|
font-family: "Andale Mono", monospace;
|
|
margin-left: 1em;
|
|
margin-right: 1em;
|
|
padding: 1em;
|
|
}
|
|
|
|
pre span {color:gray}
|
|
|
|
code {
|
|
font-size: medium;
|
|
font-weight: bold;
|
|
color: gray;
|
|
}
|
|
|
|
table#solid {
|
|
border: 1px solid black;
|
|
border-collapse: collapse;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
}
|
|
|
|
table#solid th {
|
|
border: 1px solid black;
|
|
padding: 0.5em;
|
|
}
|
|
|
|
table#solid td {
|
|
border: 1px solid black;
|
|
padding: 0.5em;
|
|
}
|
|
|
|
span.function {
|
|
color: #00008BA2;
|
|
font-weight: bold;
|
|
}
|
|
|
|
table.func-parts {
|
|
padding-left: 10px;
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
table.func-parts td.part {
|
|
font-weight: bold;
|
|
}
|
|
|
|
div.api {
|
|
padding-left: 10px;
|
|
padding-top: 10px;
|
|
}
|
|
|
|
//
|
|
-->
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="container">
|
|
<div id="logo">
|
|
<center><img alt="xmlparser logo" src="logo1.png"></center>
|
|
<div id="menu">
|
|
<center>
|
|
<h3>Lua Assembler/Disassembler</h3>
|
|
<a href="#description">Description</a> | <a href="#requirements">Requirements</a> | <a href="#install">Install</a> |
|
|
<a href="#assembler_options">Assembler Options</a> | <a href="#disassembler_options">Disassembler Options</a> |
|
|
<a href="#how-to-use">How To Use</a> | <a href="#examples">Examples</a> | <a href="#syntax">Assembly Syntax</a> |
|
|
<a href="#opcodes">Instructions</a> | <a href="#notes">Notes</a> | <a href="#licence">Licence</a>
|
|
</center>
|
|
</div>
|
|
</div>
|
|
<div id="content">
|
|
<h3><a name="description">Description</a></h3>
|
|
|
|
<p><code>Lua Assembler/Disassembler</code> is a set of two applications. The former is the disassembler, which
|
|
can be used to generate assembly code from Lua code or Lua bytecode, while the latter is the assembler, which
|
|
can be used to generate Lua byte code from assembly code.
|
|
|
|
The assembler uses <a href="http://www.inf.puc-rio.br/~roberto/lpeg/">Lpeg</a> in order to implement the parser
|
|
for the assembly syntax, which is presented on this document.
|
|
</p>
|
|
|
|
<hr>
|
|
|
|
<h3><a name="requirements">Requirements</a></h3>
|
|
<code>Lua Assembler/Disassembler</code> is compatible with Lua version 5.1.4 and Lpeg version 0.10.
|
|
<hr />
|
|
|
|
<h3><a name="install">Install</a></h3>
|
|
<p>
|
|
To run <code>Lua Assembler/Disassembler</code> in your computer, first you need install the
|
|
<a href="http://www.lua.org/manual/5.1/manual.html#pdf-package.path">Lua language</a> and the
|
|
<a href="http://www.inf.puc-rio.br/~roberto/lpeg/#download">Lpeg</a> library.
|
|
The <code>Lua Assembler/Disassembler</code> is an application composed by 2 files.
|
|
To install you need to <a href="">download</a> and just copy the following files
|
|
to a directory in your computer or to your $PATH (which will depend on the operating system).
|
|
|
|
<ul>
|
|
<li><code>assembler.lua</code></li>
|
|
<li><code>disassembler.lua</code></li>
|
|
</ul>
|
|
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
<h3><a name="assembler_options">Assembler Options</a></h3>
|
|
|
|
The following synopsis should be used:
|
|
|
|
<pre class="lua-code">
|
|
lua assembler.lua [options] [filename]
|
|
</pre>
|
|
|
|
<p>Available options are listed below and must be separate.</p>
|
|
|
|
<a name="op-com"><h3 style="color:#00008B;">-h</h3></a>
|
|
<p>
|
|
Just prints a help message listing all available options and a brief explanation about them.
|
|
</p>
|
|
<a name="op-mat"><h3 style="color:#00008B;">-b</h3></a>
|
|
<p>
|
|
Output file on <b>big endian</b>, instead of the default <b>little endian</b>.
|
|
</p>
|
|
<a name="op-ver"><h3 style="color:#00008B;">-o file</h3></a>
|
|
<p>
|
|
Output to <b>file</b>, instead of the default <b>d.out</b>.
|
|
Be careful to not overwrite precious files since you might specify the output file as an existent source file.
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
<h3><a name="disassembler_options">Disassembler Options</a></h3>
|
|
|
|
The following synopsis should be used:
|
|
|
|
<pre class="lua-code">
|
|
lua disassembler.lua [options] [filename]
|
|
</pre>
|
|
|
|
<p>Available options are listed below and must be separate.</p>
|
|
|
|
<a name="op-com"><h3 style="color:#00008B;">-h</h3></a>
|
|
<p>
|
|
Just prints a help message listing all available options and a brief explanation about them.
|
|
</p>
|
|
<a name="op-mat"><h3 style="color:#00008B;">-l</h3></a>
|
|
<p>
|
|
Produce a listing of the compiled bytecode for Lua's virtual machine on <b>luac -l</b> style.
|
|
</p>
|
|
<a name="op-ver"><h3 style="color:#00008B;">-o file</h3></a>
|
|
<p>
|
|
Output to <b>file</b>, instead of the default <b>d.asm</b>.
|
|
Be careful to not overwrite precious files since you might specify the output file as an existent source file.
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
<h3><a name="how-to-use">How To Use</a></h3>
|
|
|
|
<p>The following command line shows how to use the <code>disassembler</code> in order to generate the assembly code
|
|
for a Lua source file:
|
|
<pre class="lua-code">
|
|
$ lua disassembler.lua -o hello.asm hello.lua
|
|
</pre>
|
|
|
|
The above command line outputs <b>hello.asm</b> which contains the assembly code for <b>hello.lua</b>.
|
|
<br><br>
|
|
It is important to remember that the <code>disassembler</code> can be used with a Lua bytecode too, as we shown below:
|
|
<pre class="lua-code">
|
|
$ lua disassembler.lua luac.out
|
|
</pre>
|
|
|
|
Notice that in this case we haven't specified the output file, in this way the output will be the default <b>d.asm</b>.
|
|
<br><br>
|
|
<p>The following command line shows how to use the <code>assembler</code> in order to generate Lua bytecode from
|
|
our assembly code:
|
|
<pre class="lua-code">
|
|
$ lua assembler.lua -o hello.out hello.asm
|
|
</pre>
|
|
|
|
The above command line outputs <b>hello.out</b> which contains Lua bytecode for <b>hello.asm</b> and can be executed using lua.
|
|
<br><br>
|
|
It is important to remember that if you do not specify the output file, then Lua bytecode will be generated as <b>d.out</b> by default.
|
|
|
|
<hr />
|
|
|
|
<h3><a name="examples">Examples</a></h3>
|
|
|
|
In this section we show some examples of our <b>assembly</b> language. The complete syntax can be checked
|
|
at <a href="#syntax">Assembly Syntax</a> as well as opcodes can be checked at <a href="#opcodes">Instructions</a>.
|
|
|
|
Here we show the assembly code that were generated, on above section, for <b>hello.lua</b> which is a simple
|
|
<b>hello world</b> program.
|
|
|
|
<pre class="lua-code">
|
|
main function:
|
|
1 [1] GETGLOBAL R[0] print
|
|
2 [1] LOADK R[1] "hello world!"
|
|
3 [1] CALL R[0] 2 1
|
|
4 [1] RETURN R[0] 1
|
|
</pre>
|
|
|
|
Once we use the <code>assembler</code> to output the Lua bytecode we can execute it using lua, as follows:
|
|
|
|
<pre class="lua-code">
|
|
$ lua hello.out
|
|
hello world!
|
|
$
|
|
</pre>
|
|
|
|
Now we define a recursive factorial in our assembly language. Notice that although <b>line number</b> and
|
|
<b>source line number</b> are optionals when we are writting the assembly code, <b>instructions</b>
|
|
as well as its arguments are still mandatory.
|
|
|
|
<pre class="lua-code">
|
|
main function:
|
|
CLOSURE R[0] fat_rec 1
|
|
SETGLOBAL R[0] fat
|
|
GETGLOBAL R[0] print
|
|
GETGLOBAL R[1] fat
|
|
LOADK R[2] 5
|
|
CALL R[1] 2 0
|
|
CALL R[0] 0 1
|
|
RETURN R[0] 1
|
|
|
|
function fat_rec:
|
|
EQ R[0] R[0] 0
|
|
JMP label1
|
|
LOADK R[1] 0
|
|
RETURN R[1] 2
|
|
JMP label3
|
|
label1: EQ R[0] R[0] 1
|
|
JMP label2
|
|
LOADK R[1] 1
|
|
RETURN R[1] 2
|
|
JMP label3
|
|
label2: GETGLOBAL R[1] fat
|
|
SUB R[2] R[0] 1
|
|
CALL R[1] 2 2
|
|
MUL R[1] R[0] R[1]
|
|
RETURN R[1] 2
|
|
label3: RETURN R[0] 1
|
|
</pre>
|
|
|
|
In this example we haven't used <b>line number</b> or <b>source line number</b>.
|
|
However, we have used <b>labels</b> on <b>fat_rec</b> function since it is easier to check where to jump.
|
|
|
|
<hr />
|
|
|
|
<h3><a name="syntax">Assembly Syntax</a></h3>
|
|
|
|
Here is the complete syntax of Assembly in <code>lpeg re</code> module.
|
|
|
|
<pre class="lua-code">
|
|
prog <- ( function )*
|
|
function <- header ( instruction )+
|
|
header <- ( %nl )* s (user / main) s ( %nl )+
|
|
user <- ( "function" s name s ":" )
|
|
main <- ( "main" s "function" s ":" )
|
|
number <- hex / float / int
|
|
int <- "-"? [0-9]+
|
|
float <- "-"? [0-9]+? "."? [0-9]+ ( [eE] ("-" / "+")? [0-9]+)? /
|
|
"-"? ([0-9]+ ".")? [0-9]+ ( [eE] ("-" / "+")? [0-9]+)?
|
|
hex <- "0x" [a-zA-Z0-9]+
|
|
name <- [a-zA-Z_][a-zA-Z0-9_]*
|
|
label <- name ":"
|
|
string <- '"' ('\\' / '\"' / !'"' .)* '"'
|
|
instruction <- ( s ( label / number)? s ln? s op ( s param )+ s ( %nl )+ )
|
|
op <- [A-Z]+
|
|
param <- register / number / name / string
|
|
register <- ( "R[" number "]" )
|
|
s <- ( !%nl %s )*
|
|
ln <- "[" number "]"
|
|
</pre>
|
|
<hr />
|
|
|
|
<h3><a name="opcodes">Instructions</a></h3>
|
|
|
|
<p>
|
|
We have three main types of instructions, they are so called <b>iABC</b>, <b>iABx</b> and <b>iAsBx</b>
|
|
and should be used as follows:
|
|
</p>
|
|
|
|
<center>
|
|
<table id='solid'>
|
|
<tr>
|
|
<td><strong>Instruction type</strong></td>
|
|
<td><strong>Pattern</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>iABC</td>
|
|
<td>OPCODE A B C</td>
|
|
</tr>
|
|
<tr>
|
|
<td>iABx</td>
|
|
<td>OPCODE A Bx</td>
|
|
</tr>
|
|
<tr>
|
|
<td>iAsBx</td>
|
|
<td>OPCODE A sBx</td>
|
|
</tr>
|
|
</table>
|
|
</center>
|
|
|
|
<p>
|
|
Some <b>iABC</b> instructions do not use argument B or C and below we specify when that is the case.
|
|
Nonetheless, most of the <b>iABC</b> instructions follow the pattern described in above table.
|
|
</p>
|
|
|
|
<p>
|
|
It is also important to keep in mind that parameters should comply with the <a href="#syntax">Assembly Syntax</a>.
|
|
Here a some examples:
|
|
</p>
|
|
|
|
<center>
|
|
<table id='solid'>
|
|
<tr>
|
|
<td><strong>Parameter type</strong></td>
|
|
<td><strong>Example</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Register</td>
|
|
<td>R[0], R[1], R[2], ...</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Number</td>
|
|
<td>0, 1, 2, ... / -1, -2, ... / 0.1, 0.2, ..., 1.0, 1.1, ... / -0.1, -0.2, ..., -1.0, -1,1, ...</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Name</td>
|
|
<td>F_0_1, blah, foo, ...</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Nil</td>
|
|
<td>NIL</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Boolean</td>
|
|
<td>TRUE / FALSE</td>
|
|
</tr>
|
|
<tr>
|
|
<td>String</td>
|
|
<td>"oi, tudo bem?", "hello world", "%s, string", ...</td>
|
|
</tr>
|
|
</table>
|
|
</center>
|
|
|
|
<p>
|
|
We will use a instruction notation as follows to show how to use each opcode.
|
|
</p>
|
|
|
|
<center>
|
|
<table id='solid'>
|
|
<tr>
|
|
<td><strong>Notation</strong></td>
|
|
<td><strong>Meaning</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>R(A), R(B), R(C)</td>
|
|
<td>Register specified in field A, B or C.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>PC</td>
|
|
<td>Program Counter.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Kst(n)</td>
|
|
<td>A constant that will be translated to a number n.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Upvalue[n]</td>
|
|
<td>An upvalue name that will be translated to a number n.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Gbl[sym]</td>
|
|
<td>A global variable.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>RK(B), RK(C)</td>
|
|
<td>A field that could be a register or a constant.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>sBx</td>
|
|
<td>Signal displacement for all kinds of jumps. It can be a number or a label.</td>
|
|
</tr>
|
|
</table>
|
|
</center>
|
|
|
|
<p>
|
|
Below we show each opcode that is available in our assembly language as well as their respective arguments.
|
|
</p>
|
|
|
|
<a name="op-com"><h3 style="color:#00008B;">MOVE A B</h3></a>
|
|
R(A) := R(B)
|
|
<p>
|
|
Copies the value of register R(B) into register R(A).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">LOADK A Bx</h3></a>
|
|
R(A) := Kst(Bx)
|
|
<p>
|
|
Loads constant Kst(Bx) into register R(A). Constants can be numbers or strings.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">LOADBOOL A B C</h3></a>
|
|
R(A) := (Bool)B; if (C) pc++
|
|
<p>
|
|
Loads a boolean value B (<b>TRUE</b> or <b>FALSE</b> should be used as B) into register R(A).
|
|
If C is not zero then next instruction is skipped.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">LOADNIL A B</h3></a>
|
|
R(A) := ... := R(B) := nil
|
|
<p>
|
|
Sets a range of registers from R(A) to R(B) to <b>nil</b>.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">GETUPVAL A B</h3></a>
|
|
R(A) := UpValue[B]
|
|
<p>
|
|
Copies the value in UpValue[B] into register R(A).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">GETGLOBAL A Bx</h3></a>
|
|
R(A) := Gbl[Kst(Bx)]
|
|
<p>
|
|
Copies the value of a global variable Gbl[Kst(Bx)] into register R(A).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">GETTABLE A B C</h3></a>
|
|
R(A) := R(B)[RK(C)]
|
|
<p>
|
|
Copies the value from a table element into register R(A).
|
|
The table is referenced by register R(B), while the index to the table is given by
|
|
RK(C), which may be register R(C) or a constant Kst(C).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">SETGLOBAL A Bx</h3></a>
|
|
Gbl[Kst(Bx)] := R(A)
|
|
<p>
|
|
Copies the value from register R(A) to a global variable Gbl[Kst(Bx)].
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">SETUPVAL A B</h3></a>
|
|
UpValue[B] := R(A)
|
|
<p>
|
|
Copies the value from register R(A) into UpValue[B].
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">SETTABLE A B C</h3></a>
|
|
R(A)[RK(B)] := RK(C)
|
|
<p>
|
|
Copies the value from register R(C) or constant Kst(C) into a table element.
|
|
The table is referenced by register R(A), while the index to the table is given by
|
|
RK(B), which may be register R(B) or a constant Kst(B).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">NEWTABLE A B C</h3></a>
|
|
R(A) := {} (size = B,C)
|
|
<p>
|
|
Creates a new empty table at register R(A).
|
|
Argument B is the size of the array part, while C is the size of the hash part.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">SELF A B C</h3></a>
|
|
R(A+1) := R(B); R(A) := R(B)[RK(C)]
|
|
<p>
|
|
It is used for object-oriented programming using tables.
|
|
Retrieves a function reference from a table element and places it in register R(A),
|
|
then a reference to the table itself is placed in the next register R(A+1).
|
|
R(B) is the register holding the reference to the table with the method,
|
|
while the method function is found using the table index RK(C), that can be
|
|
a register R(C) or a constant Kst(C).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">ADD A B C</h3></a>
|
|
R(A) := RK(B) + RK(C)
|
|
<p>
|
|
Adds RK(B) and RK(C) and holds the result into register R(A).
|
|
Both RK(B) and RK(C) may be either registers or constants.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">SUB A B C</h3></a>
|
|
R(A) := RK(B) - RK(C)
|
|
<p>
|
|
Subtracts RK(B) and RK(C) and holds the result into register R(A).
|
|
Both RK(B) and RK(C) may be either registers or constants.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">MUL A B C</h3></a>
|
|
R(A) := RK(B) * RK(C)
|
|
<p>
|
|
Multiplies RK(B) and RK(C) and holds the result into register R(A).
|
|
Both RK(B) and RK(C) may be either registers or constants.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">DIV A B C</h3></a>
|
|
R(A) := RK(B) / RK(C)
|
|
<p>
|
|
Divides RK(B) and RK(C) and holds the result into register R(A).
|
|
Both RK(B) and RK(C) may be either registers or constants.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">MOD A B C</h3></a>
|
|
R(A) := RK(B) % RK(C)
|
|
<p>
|
|
Performs modulus between RK(B) and RK(C) and holds the result into register R(A).
|
|
Both RK(B) and RK(C) may be either registers or constants.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">POW A B C</h3></a>
|
|
R(A) := RK(B) ^ RK(C)
|
|
<p>
|
|
Performs exponentiation between RK(B) and RK(C) and holds the result into register R(A).
|
|
Both RK(B) and RK(C) may be either registers or constants.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">UNM A B</h3></a>
|
|
R(A) := -R(B)
|
|
<p>
|
|
Performs unary minus where register R(B) is negated and the value is placed in register R(A).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">NOT A B</h3></a>
|
|
R(A) := not R(B)
|
|
<p>
|
|
Applies a boolean <b>not</b> to the value in register R(B) and holds the result in register R(A).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">LEN A B</h3></a>
|
|
R(A) := length of R(B)
|
|
<p>
|
|
Returns the length of object in register R(B) and holds the result in register R(A).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">CONCAT A B C</h3></a>
|
|
R(A) := R(B).. ... ..R(C)
|
|
<p>
|
|
Performs the concatenation among two or more strings. The start register is R(B) and the
|
|
final register is R(C), meaning that R(C) should always be greater then R(B).
|
|
The result is stored in register R(A).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">JMP sBx</h3></a>
|
|
pc+=sBx
|
|
<p>
|
|
Performs an unconditional jump to sBx, which should be the instruction number that should jump to.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">EQ A B C</h3></a>
|
|
if ((RK(B) == RK(C)) ~= A) then pc++
|
|
<p>
|
|
Performs a <b>equality</b> test between RK(B) and RK(C), wich may be registers or constants.
|
|
If the boolean is not A then next instruction is skipped.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">LT A B C</h3></a>
|
|
if ((RK(B) < RK(C)) ~= A) then pc++
|
|
<p>
|
|
Performs a <b>less than</b> test between RK(B) and RK(C), wich may be registers or constants.
|
|
If the boolean is not A then next instruction is skipped.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">LE A B C</h3></a>
|
|
if ((RK(B) <= RK(C)) ~= A) then pc++
|
|
<p>
|
|
Performs a <b>less than or equal to</b> test between RK(B) and RK(C), wich may be registers or constants.
|
|
If the boolean is not A then next instruction is skipped.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">TEST A C</h3></a>
|
|
if not (R(A) <=> C) then pc++
|
|
<p>
|
|
Can be used to implement <b>and</b>/<b>or</b> logical operators, or for testing
|
|
a single register in a conditional statement.
|
|
TEST should be used when a assignment operation is not needed and works same way TESTSET.
|
|
For more details, please, look at TESTSET.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">TESTSET A B C</h3></a>
|
|
if (R(B) <=> C) then R(A) := R(B) else pc++
|
|
<p>
|
|
Also can be used to implement <b>and</b>/<b>or</b> logical operators, or for testing
|
|
a single register in a conditional statement.
|
|
Register R(B) is coerced into a boolean and compared to the boolean field C.
|
|
If R(B) matches C then next instruction is skipped, otherwise R(B) is assigned to R(A).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">CALL A B C</h3></a>
|
|
R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))
|
|
<p>
|
|
Performs a function call. R(A) holds the reference to the function object to be called.
|
|
Parameters to the function should be placed in the registers following R(A).
|
|
<br><br>
|
|
If B is 1, the function has no parameters. If B is 2 or more there are B-1 parameters.
|
|
If B is 0 the function parameters range from R(A+1) to the top of the stack.
|
|
<br><br>
|
|
Results returned by the function call are placed in a range of registers starting from R(A).
|
|
If C is 1 no return results. If C is 2 or more there are C-1 results saved.
|
|
If C is 0 then multiple return results are saved.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">TAILCALL A B C</h3></a>
|
|
return R(A)(R(A+1), ... ,R(A+B-1))
|
|
<p>
|
|
Performs a tail call which happens when a <b>return</b> statement has a single function call as the expression.
|
|
Exactly like CALL, register R(A) is the reference to the function object to be called,
|
|
while B encodes the number of paramenters. However, even tough C is not used by TAILCALL, 0 should be
|
|
used to denote multiple return results.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">RETURN A B</h3></a>
|
|
return R(A), ... ,R(A+B-2)
|
|
<p>
|
|
Returns to the calling function with options return values.
|
|
<br><br>
|
|
If B is 1 there are no return values. If B is 2 or more, there are B-1 return values.
|
|
If B is 0, the set of values from R(A) to the top of the stack is returned.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">FORLOOP A sBx</h3></a>
|
|
R(A)+=R(A+2) ; if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A)
|
|
<p>
|
|
Should be used to initialize a numeric <b>for</b> loop.
|
|
A numeric for loop requires 4 registers on the stack where R(A) hold the initial value,
|
|
R(A+1) is the limit, R(A+2) is the stepping value and R(A+3) is the actual loop variable
|
|
that is local to the <b>for</b> block.
|
|
The argument sBx should be the instruction number that should jump unconditionally to FORLOOP.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">FORPREP A sBx</h3></a>
|
|
R(A)-=R(A+2); pc+=sBx
|
|
<p>
|
|
Should be used to perform an iteration of a numeric <b>for</b> loop.
|
|
The argument sBx should be the instruction number that should jump back to the loop body.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">TFORLOOP A C</h3></a>
|
|
R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)) ; if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++
|
|
<p>
|
|
Should be used to perform an iteration of a generic <b>for</b> loop, where
|
|
R(A) is the iterator function, R(A+1) is the state and R(A+2) is the enumeration index.
|
|
The loop variables are specified at locations R(A+3) and their count is defined by operand C,
|
|
which should be at least 1.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">SETLIST A B C</h3></a>
|
|
R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B
|
|
<p>
|
|
Sets the values for a range of arrays elements in a table referenced by R(A),
|
|
argument B is the number of elements to set and argument C is the number of blocks
|
|
to be initialized.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">CLOSE A</h3></a>
|
|
close all variables in the stack up to (>=) R(A)
|
|
<p>
|
|
Closes all local variables in the stack up to register R(A).
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">CLOSURE A Bx N</h3></a>
|
|
R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))
|
|
<p>
|
|
Should be used to create an instance of a closure of a function where Bx is the
|
|
function name and R(A) is the register that assigns the reference to the instantiated
|
|
function object. Although it is a <b>iABx</b> instruction the parameter N should specify
|
|
the number of parameters for the function that is being defined.
|
|
</p>
|
|
<a name="op-com"><h3 style="color:#00008B;">VARARG A B</h3></a>
|
|
R(A), R(A+1), ..., R(A+B-1) = vararg
|
|
<p>
|
|
Copies B-1 parameters into a number of registers starting from R(A).
|
|
If B is 0, VARARG copies as many values as it can based on the number of parameters passed.
|
|
If a fixed number of values is required, B is a value greater than 1.
|
|
If any number of values is required then B is 0.
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
<h3><a name="notes">Notes</a></h3>
|
|
<p>
|
|
The current version of <code>Lua Assembler/Disassembler</code> is 0.1.
|
|
</p>
|
|
<hr />
|
|
|
|
<h3><a name="licence">Licence</a></h3>
|
|
<p>
|
|
Copyright © 2010 Andre Murbach Maidl.
|
|
</p>
|
|
<p>
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to
|
|
deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
</p>
|
|
<p>
|
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
</p>
|
|
<p>
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
</p>
|
|
|
|
</div>
|
|
<div id="footer">
|
|
<center>
|
|
<small>Last modified by Andre Murbach Maidl</small>
|
|
</center>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|