#virtual-machine #compiler #toolchain #transient #tvm #transient-assembly #tasm

app transient-asm

TransientAssembly 的工具链。包括编译器和虚拟机。

2 个版本

0.1.1 2024 年 8 月 9 日
0.1.0 2024 年 8 月 8 日

#44编程语言

Download history 201/week @ 2024-08-05 27/week @ 2024-08-12

228 每月下载量

MIT 许可证

40KB
697

瞬态

🔥 ~ 开始 ~

[!IMPORTANT]
这是一个纯粹的教育项目,因此不提供任何保证。我的项目可以免费使用,只要遵守相关许可证,并在适当的地方给予信用。祝您玩得开心!

这是一个编译和运行 TransientAssembly (TASM) 程序的实用工具集合。Transient 项目包括一个编译器,可以将 TransientAssembly (TASM) 编译成 TransientBytecode (TBC),然后由 TransientVM (TVM) 执行。本文件包括安装指南、编译器指南以及如何编写 TransientAssembly (TASM) 的快速教程。

⬇️ 安装

[!NOTE]
本指南假定您已安装 Rust 工具链。如果您没有,请使用 rustup 或合适的等效工具安装 Rust。只有在首次安装编译器和虚拟机时才需要 Rust 编译器。它们的运行时不需要 Rust 工具链。

编译器(transientcompile)和虚拟机(transientvm)都可以使用 Cargo 作为捆绑包安装。您首先需要克隆 GitHub 仓库

$ git clone https://github.com/redtechtiger/transient

然后,导航到新创建的目录并运行 Cargo 以安装二进制文件

$ cd transient
$ cargo install --path .

🗑️ 删除

如果您希望从系统中删除这些实用工具,可以使用 Cargo。运行以下命令

$ cargo uninstall --package transient

📚 示例用法

要编译和运行 TransientAssembly (TASM) 文件,只需用输入和输出文件调用编译器。这将生成一个 .tbc 文件(瞬态字节码),然后您可以使用虚拟机运行它。为了测试工具链是否正常工作,您可以尝试编译示例项目。例如,以下是编译斐波那契序列的方法

$ transientcompile examples/fibonacci.tasm fibonacci.tbc
$ transientvm fibonacci.tbc

💻 ~ TransientAssembly ~

这是编写 TransientAssembly 的基本教程。由于整个项目都处于早期阶段,语法、功能以及语言的根本工作方式都可能发生重大变化。这也意味着语言非常基础,可能只有熟悉汇编或非常低级代码的人才能理解。

结构

以下是您阅读以下文本时可以参考的典型指令。

add64 $variable1 $another_var $result

在TransientAssembly中,每一行都会执行一个操作,除非是注释 "//"、标签 "#" 或空行。我们稍后会回到标签,现在让我们看看语言的一般结构。在一行的开头,你有操作 - 一旦你看了几个例子,这个操作就很容易理解了。它后面跟着一个后缀(64、32、16、8),这个后缀决定了表达式中的变量有多少位。关于这一点,我们稍后再详细说明。然后是参数,可以是变量(以 $ 前缀),也可以是中间变量(以 !{size}_ 前缀,例如 !64_)。看看下面的例子

// This is a comment.
// Blablabla

// This is a tag!
#tag_1

// And this is an operation. We are creating a 64 bit variable called `my_variable` with the value 5.
set64 $my_variable 5

// Create another 64 bit variable with value 10
set64 $another_var 10

// We need to initialize this beforehand!
set64 $result 0

// Add `my_variable` and `another_var`, and store the sum in `result`.
add64 $my_variable $another_var $result

// The variable `result` will now be 15

操作

以下是可用的操作列表。

mov - Copies the first variable into the second
add - Adds two variables and stores the result in a third
sub - Subtracts the second variable from the first and stores the result in a third
mov - Same except multiplied
divt - Same except divided (truncated)
divr - Same except divided (rounded)
rem - Same except moduli
cgt - Compares if the first variable is greater than the second variable. If true, the third variable will be set to 1. If false, it will be set to 0
cls - Same except less than
equ - Same except equals
jmp - Stops execution, jumps to a tag, and resumes
jie - If variable two is 1, jumps to a tag. If 0 or other value, keep executing as normal
jne - Same except only jumps if variable is 0
puti - Prints the integer stored at the first variable to the console
putc - Prints the integer at first variable formatted to an ascii character
imz - Get the size of the program in bytes and stores it in the first variable
hlt - Stop program execution and exit the virtual machine

大小

操作的大小只是指定了所使用的变量有多大。例如,如果你正在添加两个8位整数,你必须使用 add8add8 的输出也将始终是8位整数。同样,如果你正在添加两个64位整数并保存到64位整数中,你必须使用 add64。每个操作都必须包括一个大小提示,尽管并非所有操作实际上都使用它。例如,暂停指令(hlt)始终是64位(8字节),但编译器仍然需要你指定一个大小,这是出于技术原因。

最重要的是,相关变量的 大小必须 相同。(如果你不确定选择什么,你可以将此保持为64)。例如,你不能创建一个64位变量并尝试将其用于32位、16位或8位操作,除非你真的知道你在做什么,否则这会导致内存和/或运行时代码损坏,从而导致糟糕的错误。目前编译器不会验证这一点,所以这取决于你来进行验证。

标签

标签只是你的代码中可以跳转到的点。在底层,编译器将这些扩展到标签后面的最近指令的内存地址。以下是一个无限循环的例子

#foo
jmp #foo

这是另一个计数到10的循环。

set64 $value 0
set64 $comparison_result 0

#loop
puti64 $value
add64 $value !64_1 $value
cgt64 $value !64_10 $comparison_result
jne64 #loop $comparison_result

hlt64

无运行时依赖