MARS MIPS 模拟器
MARS MIPS 模拟器是 MIPS 处理器的汇编语言编辑器,汇编器,模拟器和调试器,由密苏里州立大学( src )的 Pete Sanderson 和 Kenneth Vollmar 开发。
你在这里免费获得 MARS。至于安装 4.5 版本,你可能需要从此处为你的系统提供合适的 Java SDK
在组装之前,这个模拟器的环境可以简单地分成三个部分: 左上角的编辑器,正在编写所有代码,编辑器/输出正下方的编辑器和代表 CPU
的寄存器列表对于我们的计划。
组装后(通过简单地按 F3)环境发生变化,两个新的段获得编辑器的位置: 文本段在哪里
i)每行汇编代码在基本列中清除伪指令(我们将在一秒内讨论)
ii)代码列中每条指令的机器代码,
以及数据段,我们可以看一下具有 little-endian 顺序的处理器的内存表示。
组装完成后,我们可以一次性(F5)或逐步(F7)执行我们的代码,并将执行的几个步骤倒退到后面(F8)。
现在,让我们看一下上面的示例代码并解释每一行:
.text
.globl main
main: #main function
li $v0, 11 #11=system code for printing a character, $v0=register that gets the system code for printing as value
la $a0, 'a' #'a'=our example character, $a0=register that accepts the character for printing
syscall #Call to the System to execute our instructions and print the character at the a0 register
li $v0, 10 #11=system code for terminating, $v0=register that gets the system code for terminating (optional, but desirable)
syscall #Call to the System to terminate the execution
MARS 接受并导出 .asm 文件类型的文件
但是上面的代码只打印了一个字符,那么好的 Hello World
呢?怎么样,不知道,添加一些数字还是什么?好吧,我们可以改变我们的一点点:
.data #data section
str: .asciiz "Hello world\n"
number: .word 256
.text #code section
.globl main
main:
li $v0, 4 #system call for printing strings
la $a0, str #loading our string from data section to the $a0 register
syscall
la $t0, number #loading our number from data section to the $t0 register
lw $s1, 0($t0) #loading our number as a word to another register, $s1
addi $t2, $s1, 8 #adding our number ($s1) with 8 and leaving the sum to register $t2
sw $t2, 0($t0) #storing the sum of register $t2 as a word at the first place of $t0
li $v0, 10 # system call for terminating the execution
syscall
在通过 MARS 说明结果之前,需要对这些命令进行更多解释:
-
系统调用是操作系统提供的一组服务。要使用系统调用,需要将调用代码放入$ v0 寄存器以进行所需操作。如果系统调用有参数,则将它们放在$ a0- $ a2 寄存器中。这是所有系统调用。
-
li
(load immediate)是一个伪指令(稍后我们将讨论),它立即加载一个带有值的寄存器。la
(加载地址)也是一个伪指令,用于将地址加载到寄存器。使用li $v0, 4
,$ v0 寄存器现在已经将4
作为值,而la $a0, str
将str
的字符串加载到$a0
寄存器。 -
一个字 (就我们所说的 MIPS 而言)是一个 32 位序列,其中第 31 位是最高有效位,第 0 位是最低有效位。
-
lw
(加载字)从存储器传输到寄存器,而sw
(存储字)从寄存器传输到存储器。使用lw $s1, 0($t0)
命令,我们加载到$s1
寄存器,该寄存器位于$t0
寄存器的 LSB 处(这就是0
在这里的符号,这个字的偏移量),也就是256
。$t0
这里有地址,而$s1
有值。sw $t2, 0($t0)
做了相反的工作。 -
MARS 使用 Little Endian ,意味着一个字的 LSB 存储到存储器的最小字节地址。
-
MIPS 使用字节地址,因此地址与前一个地址和下一个地址相差 4。
通过汇编之前的代码,我们可以进一步了解内存和寄存器的交换方式,从数据段中禁用十六进制值:
或从数据段启用 ASCII
:
像这样开始吧
$ java -jar Mars4_5.jar
创建此文件并保存。
.text
main:
li $s0,0x30
loop:
move $a0,$s0 # copy from s0 to a0
li $v0,11 # syscall with v0 = 11 will print out
syscall # one byte from a0 to the Run I/O window
addi $s0,$s0,3 # what happens if the constant is changed?
li $t0,0x5d
bne $s0,$t0,loop
nop # delay slot filler (just in case)
stop: j stop # loop forever here
nop # delay slot filler (just in case)
按 F3 组装它,然后按运行。现在你开始编译并执行 MIPS 代码。