2个版本
| 0.7.2 | 2024年5月16日 |
|---|---|
| 0.7.1 | 2024年5月12日 |
| 0.7.0 |
|
#473 in 硬件支持
126 每月下载量
320KB
9K SLoC
Trion
Trion是一个汇编器(具有一些反汇编功能),专为Raspberry Pico (RP2040)微控制器设计。
运行
您可以通过以下两种方式之一运行此软件包中的可执行文件
- 首先使用
cargo install trion(另请参阅cargo文档中的--bin <name>选项),然后仅使用trias <args>或tridas <args>运行已安装的版本。 - 直接使用
cargo run --bin <name>,其中trias是汇编器,tridas是反汇编器。
如果您选择后者,请注意,本说明文档使用前者方法以简化说明。安装也不需要在软件包文件夹内运行命令,但另一方面,需要在每次版本更改后手动重新安装,因此不适合开发。
此软件包也可以用作库(如示例仓库所示使用)因此没有默认的可执行文件(您必须指定一个)。用作此类时,处理文件读取、汇编和输出写入的主要代码将不存在,但负责汇编的功能(包括解析器、指令和输出格式辅助器)可用于不同的环境。
汇编语法
Trion的汇编语法与其他汇编器大致相似,略有修改以简化解析步骤。
汇编文件(通常是但不限于*.asm)由一系列语句组成,可以是以下任何一种
- 指令:
"." <name> [<argument> {"," <argument>}] ";" - 标签:
<name> ":" - 指令
<name>["." <flags>] [<argument> {"," <argument>}] ";"
接受的参数数量和类型取决于所使用的指令,但如果它们不正确,解析可能会继续。
参数
指令和指令通常接受参数,这些参数控制其行为。原子参数是
- 立即数:源代码中以二进制、八进制、十进制或十六进制格式编码的整数值。二进制、八进制和十六进制的前缀分别是
"0b"、"0o"和"0x"。 - 字符:实际上是立即数,但格式化为以单引号分隔的 Unicode 代码点。
- 标识符:可以引用寄存器或常量的名称。有效字符是
"A"到"Z"(不区分大小写)和"_",在第一个"$"、"."、"@"或"0"到"9"之后也是有效的。 - 字符串:由双引号分隔的 Unicode 代码点序列。
此外,Trion 支持(按优先级顺序)一系列数值操作
- 否定
"-" <arg>、按位非"!" <arg> - 乘法
<lhs> "*" <rhs>,除法<lhs> "/" <rhs>,取模<lhs> "%" <rhs> - 加法
<lhs> "+" <rhs>,减法<lhs> "-" <rhs> - 左移(逻辑)
<lhs> "<<" <rhs>,右移(逻辑)<lhs> ">>" <rhs> - 二进制与
<lhs& <rhs> - 二进制异或
<lhs> ^ <rhs> - 二进制或
<lhs| <rhs>
最后,还有一些特殊运算符
- 地址(
"[" <arg> "] "):指示处理器应该访问内存地址而不是数值。 - 序列(
"{" [<argument> {, <argument>}] "}"):一组通用的参数,通常是一个寄存器集。 - 函数(
<name> "(" [<argument> {"," <argument>}] ")"):用于对任何类型的值进行计算的一般用途。
与常规数学一样,总是可以将任何参数用括号括起来以影响计算顺序。然而,对于数值操作,所有参数都必须计算为寄存器或数值才能有效。此外,数学运算的结果如果超出常数的整数限制(64位有符号整数)将会出错。
常数
Trion利用编译时常数来实现简化和代码重用。常数不得与当前指令集中的任何寄存器同名。常数为有符号64位整数,可以舒适地包含RP2040的32位地址和寄存器大小。标签本身是常数,其值等于其位置,因此可以使用任意数值参数作为分支/加载目标。
常数的使用由范围决定:除导入/导出外,所有指令和指令都使用局部常数。可以在使用常数之后(尤其是标签)声明常数,但除非常数延迟,否则搜索不会超出父范围。
汇编
用法:trias <input_file.asm> [<output_file.uf2>]
汇编器用于将人类可读的汇编源代码转换为RP2040启动程序所认可的UF2容器。因此,汇编器可以直接通过选择设备驱动器内的输出路径将代码上传到设备。输出文件参数是可选的,如果省略,汇编器将正常进行,但不会保存最终输出。这适用于语法验证或测试目的。
指令
".addr" <addr> ";":将当前输出地址更改为addr(数据和指令写入的位置)。".align" <alignment> ";":将当前地址对齐到alignment字节。如果有空位,将用0xBE(BKPT指令的指令码)填充。".const" <name> "," <value> ";":创建具有给定名称(标识符)和值的局部常数。value必须计算为包含无延迟常数的数值。".du8" <value> ";",".du16" <value> ";",".du32" <value> ";":输出一个无符号整数,该整数必须在指定的范围内。".dhex" <value> ";":解码一个十六进制字符串并输出结果字节。".dstr" <value> ";":以原样输出字符串(不带填充、长度前缀或终止字符)。".dfile" <path> ";":以原样输出指定文件,path必须是指定于当前文件路径的字符串。".global" <name> ";":声明一个延迟常数name,该常数在局部作用域结束时导出。常数可以已在本地存在,包括延迟存在。在前一种情况下,它将立即导出。".import" <name> ";":从父作用域导入(可能是延迟的)常数name到局部作用域。".export" <name> ";":从局部作用域导出现有、非延迟常数name到父作用域。".include" <path> ";":汇编相对路径path(必须为字符串)的文件,并将结果输出到当前地址。文件使用其自己的局部作用域进行汇编,但它可以从中导入/导出常数到当前文件的局部作用域。
只能在使用过.addr之后使用可以写入数据的方向(和指令)。汇编器不需要适当的对齐,但RP2040将无法访问未对齐的数据或执行指令。
指令
Trion 目前仅支持 ARMv6-M 指令集(由 RP2040 使用)。指令具有相同的名称,但与 ARM 的 UAL 不同,需要以分号结尾。仅支持(实际上也要求)UDF 指令(具有窄和宽表示形式)的标志。
反汇编
用法:tridas <输入文件.bin>
反汇编器不是汇编器的精确逆过程。例如,它需要一个仅包含操作码的二进制文件作为输入,而不是 UF2 容器。因此,由于汇编过程会去除标签名称,反汇编器将假定二进制文件位于地址 0x2000000(RP2040 SRAM 的起始地址)处,并根据这些地址生成基于十六进制的标签名称。它目前仅跟随指向其他代码的标签,不会为相关数据项(例如使用立即 LDR)生成任何指令。