#assembly #instructions #isa #architecture #label #computer #gheith

app rgsm

用Rust编写的Gheith ISA汇编器

6个稳定版本

1.0.5 2024年4月25日
1.0.4 2024年4月24日
1.0.1 2024年4月22日

#3 in #computer

MIT 许可证

60KB
1K SLoC

rgsm 🦀

用Rust编写的Gheith ISA汇编器。

内容

  1. 简介
  2. 入门指南
  3. 编写汇编

简介

这是gasm项目的兄弟项目。

请注意,rgsm是Gheith教授CS 429H计算机体系结构课程的最终项目的贡献。对于完成流水线的学生,建议使用gasmdasm,因为它们包含更多与项目完成相关的功能。

rgsm是作为Gheith工具链的一部分构建和维护的。

入门指南

rgsm是一个简单的Rust二进制文件。它在Cargo(官方Rust包管理器)上发布,因此可以使用以下命令安装

安装

cargo install rgsm

先决条件

  1. Rust 2021

编写汇编

在本节中,您将学习如何编写Gheith汇编程序。

注释

可以使用前缀//将注释放置在汇编程序的任何位置。解析器将在解析此令牌后忽略该行后面的其余部分。

部分

汇编程序分为两个主要“部分”——.text.data。实际上,有效的汇编程序可以有任意数量的这些部分;然而,每个程序基本上都由这些部分组成。

.text部分相当简单:它包含所有要执行的指令。

.text
main:
    print #97
    print #98
    print #99
    // ...
    end

.data部分将包含放置在内存中的数据。Gheith体系结构是16位的,因此每个条目可以表示 $2^{17} - 1$ 个值之一:{ $0$,$1$,... $2^{17} - 1$ }。

.data
a:
    #97
b:
    #98
c:
    #99
// ...

注意,在这个示例和上面的示例中,每个数字都以前缀#开头。这将在稍后进行解释,但每个数字(实际上,几乎所有东西)都必须将其自身标记为它所代表的。在这些情况下,这些数字是立即的十进制值。

标签定义

程序实际上只是存储在内存中的数据。因此,在汇编中,如果我们想引用一组指令(或者实际上是程序中的任何东西),我们必须通过使用某些唯一的标识符(标签)来这样做。

.text
my_program_starts_here:
    // ...

这些标签实际上是数字——程序中特定部分将驻留的内存位置。您可以使用它们在任何您会使用另一个数字的情况中使用,如下所示

// @0 -> Memory location word 0
.text
my_program_starts_here:
    // ...
    // This instruction jumps to the beginning of the program!
    j my_program_starts_here
    // ...

标签定义的声明方式如上所示,随后使用 : 标记来指定它是一个定义。标签引用将省略此冒号。标签是唯一的,您不能有两个具有相同名称的标签来引用程序的不同部分。例如,以下代码将是无效的

// @12 -> Memory location word 12
label_1:
    print #97 // <- label_1 references word 12
label_1:
    print #98 // <- label_1 references word 13 (?)
              // hopefully it is clear why this makes no sense
    // ...
    // just in case it isn't clear
    j label_1 // where should this jump to?
              // word 12 or 13?

只需记住,标签实际上只是代表其下指令/数据的内存位置。

指令

rgsm 支持扩展的 Gheith ISA。它支持的特定指令可以在支持文档中找到。

以下是指令的一般形式:<INSTRUCTION NAME> [F1] [F2] [F3]

指令最多有 3 个字段,其存在和类型由 ISA 文档规定。它们可以是三种类型之一:寄存器、立即数或标签。

寄存器引用

以下 add 指令为例

add r3, r4, r5

此操作将 r4r5 的值相加,并将结果存储在 r3 中。

寄存器引用以字母 r 为前缀。Gheith 架构中有 16 个寄存器,即 r0-r15。它们的标识如下

寄存器编号。 标识 说明
0 零/打印寄存器 x 写入此寄存器将打印 x
1 返回/参数寄存器 不适用
2 双寄存器 此寄存器存储值 $2$
7 跳转位置寄存器 由跳转到标签覆盖
1-7 通用调用者保留 不适用
8-15 通用被调用者保留 不适用
14 链接寄存器 不适用
15 SP 寄存器 初始化为 0xFFFF

立即数

立即数是十进制值,其范围取决于指令。它们以 # 为前缀。这就是全部内容。

标签引用

标签可以在需要立即数的地方使用(尽管,在像 ldosto 指令中,这样做可能从语义上讲并不总是有意义的)。标签可以在定义前后引用,因为它们是预处理的。

伪指令

除了官方支持的扩展 Gheith ISA 指令外,rgsm 还支持一些“伪指令”,或者更易于阅读的指令,这些指令汇编为简单的 Gheith 指令。以下列出的是

指令名称 字段(s) 功能
print <ra: Register> add r0,ra,r0
movlb <rt: Register>, <label: Label> movl ra, label[7:0], movh ra, label[15:8]
j <rt: Register> jz rt,r0
j <label: Label> movl r7, 标签[7:0]movh r7, 标签[15:8]jz r7, r0

入口点

Geith 架构遵循冯·诺依曼架构的文本共享地址空间与数据的原理。rgsm 组织程序的方式遵循这一原则。

程序文本放置在内存地址 0,入口点是第一个 .text 节的第一条指令——这是将放置在地址 0 的指令。如果您查看汇编输出,您将看到

@0
// first instruction
// ... and so on ...

@0 指示以下块从地址 0 开始顺序排列。

.text 节被合并并首先放置在内存中,然后 .data 节被合并并最后放置。因此,生成的机器代码形式为

@0
// first instruction
// second instruction
// ...
// end of `.text`
// first data entry
// second data entry
// ...
// end of `.data`

骨架

有效汇编程序的骨架为

.data
    // Place your relevant data here!

.text
    // Place your instructions here!
    end

依赖关系

~3.5–5MB
~87K SLoC