2个版本
0.1.1 | 2019年12月21日 |
---|---|
0.1.0 | 2019年12月21日 |
#102 in 模拟器
130KB
2K SLoC
ch8asm
开源的Chip-8汇编器
概述
ch8asm
,发音类似于单词"chasm",是一个简单易用且易于学习的Chip-8复古视频游戏平台的汇编器。它使用简单的语法,只需一两天就能轻松掌握。
安装
在终端中输入以下命令来安装 ch8asm
cargo install ch8asm
用法
要使用 ch8asm
,请在终端中键入 ch8asm <源文件>
,将 <源文件>
替换为您的Chip-8源代码文件的路径。假设没有出错(错误将在下面描述),您将看到一条消息说您的文件已正确汇编。然后,您可以使用您选择的模拟器运行生成的二进制文件。如果您还没有Chip-8模拟器,您可以使用我的模拟器Cookie,可以在这里找到。
出了点问题...
当您尝试汇编游戏时,如果没有看到消息 Successfully assembled <source file> into <binary file>
,则 ch8asm
将显示一条错误消息,说明汇编二进制文件时出错的原因。以下是一些可能的错误消息及其最可能的解决方案
"无法获取标签 XXXX 的地址"
这条消息表示您试图在不定义标签(例如 XXXX
)的情况下使用它。请确保在标签定义后加上冒号。
"XXXX 指令的参数错误"
这条消息表示您在一个不支持该寄存器(通常是 I
寄存器)的指令中使用了错误的寄存器。请确保您使用正确的指令参数,如下所述。
"未知字符 X"
这条消息表示您在源代码中意外地放入了 ch8asm
不认识的字符。转到错误消息中提到的行号,查找任何多余的字符。
"未知指令 XXXX"
这条消息表示您不小心拼错了指令或试图发明一个新的指令。转到错误消息中提到的行号,检查您的代码是否有正确的拼写。
"预期 XXXX,发现 XXXX"
此消息表示您的代码中存在位置不正确的符号。转到错误消息中提到的行号,并根据错误消息更正您的代码。
"跳转类型错误 XXXX"
此消息表示您不小心拼写了一个用于 SKIP
指令的条件。检查有效条件的表,并更正您的代码以使用有效的条件。
"二进制数太大"
这仅仅意味着您的游戏比Chip-8芯片上的可用内存大。遗憾的是,唯一的方法是重写您的游戏以生成更小的二进制文件。有关此方法的说明超出了本文档的范围,可能在网上找到。
处理器信息
Chip-8处理器有十六个通用寄存器,编号从 V0
到 VF
。每个寄存器可以存储一个字节,可以随意操作。然而,寄存器 VF
被多个指令用作标志寄存器,并且只能用于该目的。
Chip-8还有一个名为 I
的“索引”寄存器。其主要用途是用于数据存储和精灵绘图操作时的内存寻址。它可以存储从0到4095的值。
Chip-8还有4096(0x1000)字节内存。其中,地址0x050到0x0A0保留用于内置字符集,二进制文件从地址0x200开始加载到内存中。所有其他地址都可以供您的游戏使用。
Chip-8还有两个内置定时器,称为 延迟定时器 和 声音定时器。两者都可以通过代码设置,并在设置为非零值时以60Hz的频率计数到0。延迟定时器可以读取,而声音定时器则不能。当声音定时器不为零时,将播放声音。
数据类型
ch8asm
的汇编语言有四种主要数据类型。它们是
- 十进制文字(以
#
符号开头) - 十六进制文字(以
$
符号开头) - 二进制文字(以
%
符号开头) - 标签(以
_
符号开头)
十进制和十六进制文字可以是0到4095之间的任何值,而二进制文字只能是一个字节长。二进制文字的一个用途是使用它们来绘制精灵。将二进制文字排列成1s代表所需的像素,附加到标签定义中,然后您可以在代码的其他部分使用该标签来表示您的精灵。
标签有两种类型: 定义 和 引用。定义向 ch8asm
提供了游戏代码中某个位置的名字,而引用允许定义在代码中使用以引用该位置。定义总是后跟冒号,而引用则从不跟冒号。
以下示例代码片段在屏幕左上角绘制一个笑脸
;this is a definition
_spr:
%00000000
%01000010
%00000000
%01000010
%00100100
%00011000
mov I, _spr ;this is a reference
mov V0, #0
mov V1, #0
draw V0, V1, #6
作为旁注,您可以使用分号来注释代码。注释从分号开始,直到行尾。
指令
以下是ch8asm
支持的指令列表。所有指令和寄存器均不区分大小写,参数之间必须用逗号分隔。在本文档中,通用寄存器用VX
和VY
表示,索引寄存器用I
表示,常量值用NN
或NNN
表示,具体取决于常量的大小,标签用_lbl
表示,其中lbl
是标签的实际名称。
绘图指令
- CLS - 清除屏幕。
- DRAW VX, VY, H - 在坐标(VX, VY)处绘制高度为H像素的精灵。精灵从内存位置开始读取,该位置由
I
指向。为了便于碰撞检测,如果任何像素从开启变为关闭,则将VF
设置为1,否则设置为0。
起始地址为I
指向的位置。为了便于碰撞检测,如果任何像素从开启变为关闭,则将VF
设置为1,否则设置为0。 - SCH VX - 将
I
设置为指向与VX值对应的十六进制字符,其中VX必须在0到15的范围内(包含0和15)。
控制指令
- JMP _lbl - 无条件地将程序流程跳转到_lbl
- CALL _lbl - 在_lbl处调用子程序。
- RET - 从子程序返回到调用代码
- SKIP.condition args - 如果condition对args为真,则跳过下一个指令。有关有效condition的列表,请参阅下表。
- JPC (_lbl或NNN) - 无条件地跳转到参数加上
V0
跳转条件
条件 | 参数 | 真值条件 |
---|---|---|
EQ |
VX ,VY 或NN |
参数相等 |
NE |
VX ,VY 或NN |
参数不相等 |
KD |
|
按键VX 被按下 |
KU |
|
按键VX 未被按下 |
操作指令
- MOV dest, src - 将src的值存储在dest中。如果dest指的是
I
寄存器,则src必须是一个常量或一个标签。src不能是I
寄存器。 - ADD dest, (VX或NN) - 将第二个参数加到第一个参数上,并将结果存储在第一个参数中。如果第二个参数是常量,则dest不能是
I
寄存器。此外,如果加法时发生溢出,则将寄存器VF
设置为1。如果没有发生溢出,则将VF
设置为0。 - OR VX, VY - 将VX设置为自身与VY按位或。
- AND VX, VY - 将VX设置为自身与VY按位与。
- XOR VX, VY - 将VX设置为自身与VY按位异或。
- SUB VX, VY - 将VX设置为VX减去VY。如果发生借位,则将
VF
设置为0,否则设置为1。 - SUBN VX, VY - 将VX设置为VY减去VX。如果发生借位,则将
VF
设置为0,否则设置为1。 - SHR VX - 将VX的最低有效位存储在
VF
中,并将VX按位右移1。 - SHL VX - 将VX的最高有效位存储在
VF
中,并将VX按位左移1。
其他指令
- RAND VX, NN - 将与NN按位与的随机字节存储在VX中。
- GDL VX - 将延迟定时器的当前值存储在VX中。
- KEY VX - 停止执行,直到按键被按下,并将其存储在VX中。
- SDL VX - 将延迟定时器设置为VX。
- 设置声音定时器为 VX
- BCD VX - 将 VX 的二进制编码十进制表示存储在从地址
I
开始的内存中。 - RDP VX - 将寄存器
V0
到 VX 的值存储在从地址I
开始的内存中。 - RLD VX - 从从地址
I
开始的内存读取数据到寄存器V0
到 VX。
进一步阅读
您可能希望阅读有关 Chip-8 的 维基百科页面 以获取有关处理器及其功能的更多信息。
许可协议
ch8asm
使用 GNU 通用公共许可证,版本 3。
结束语
我们始终欢迎反馈和建议,因此如果您有任何想法,请直接在 GitHub 上发起拉取请求或提交问题。感谢使用 ch8asm
,祝您编程愉快!
依赖项
~225KB