输入与输出
处理所有输入和输出。(environment call)会请求操作系统或模拟器为你的汇编代码执行一项服务。屏幕和键盘就是可以通过这种方式使用的两项服务。
将服务编号放入 a7,将任何参数放入 a0,然后触发 。该模拟器知道的服务有:
服务 (a7)
1 # 打印整数 (a0 = 数值)4 # 打印字符串 (a0 = 文本地址)5 # 读取整数 (结果返回到 a0)10 # 退出程序32 # 休眠 (a0 = 毫秒)
服务调用
program
a71
a0值
ecall
system打印一个数字
a7 = 1 选择打印服务。
a7 指定要运行的服务,而 a0 承载该服务所需的任何内容:要输出的值、要读取的地址、或等待的时间。 该列表是固定且简短的,仅包含五项,因此只要掌握一次这种握手机制,就能涵盖该模拟器与外部世界通信的所有方式。真正的操作系统会将这一理念扩展到更长的列表中。读取一个数字,将其翻倍,然后输出该数字
li a7, 5 # 读取整数 -> a0ecalladd a0, a0, a0 # 将其翻倍li a7, 1 # 打印整数ecallli a7, 10ecall
选择读取整数, 会暂停等待输入,并将你的数字返回到 a0。 将 a0 与自身相加,就地将其翻倍。然后 和 打印结果, 和 退出。当你 Run 它时,模拟器会弹出一个输入框。输入一个数字,看着它以两倍的值返回。
打印文本
首先介绍两个新词。节(section)是程序中带有标签的区域:指令位于 .text 节中,而文本等固定数据则位于 .data 节中。 而地址只是一个用于标识内存中某个位置的数字。寄存器无需携带整个字符串,只需携带该字符串的起始地址,打印服务便会从该处读取内容。
文本放在数据段中。你给它附加一个标签,然后用 ("load address")加载该标签的地址,并用服务 4 打印它。
你好,RISC-V
.datamsg: .string "Hello, RISC-V!\n".textla a0, msg # a0 = 文本地址li a7, 4 # 打印字符串ecallli a7, 10ecall
在 .data 中,该伪指令为文本预留空间并附加标签 msg。.string 存储这些字符并追加 \n,即换行符。在 .text 中, 将文本的地址放入 a0, 选择打印字符串服务, 从该地址打印字符,直到到达字符串末尾。然后程序照常退出。
