Chinese

From jmips


BDBengali BG CN ENEnglish ES ET FR DE IN IT JPJapanese PLPolish RO RURussian



Contents

一个简单的Java编程的MIPS仿真器

这是一个操作简单的用java编程的MIPS仿真器。你应该已经下载好了压缩源代码(更新的代码链接 jMIPS project pages) 需要下载的部分在doc/html 子目录下.

了解以上代码极大地辅助了我们学习MIPS结构并且让我们更加熟悉计算机系统和结构的基本内容。

以下有5个版本的java仿真器代码供同学们观赏和把玩,分别标记为1到5。越排在后面的模型就越细致复 杂,因此:

  1. 基本未流水线化的处理器(这些页面)
  2. 未优化但流水线化的处理器
  3. 优化且流水线化的处理器
  4. 有高速缓存的优化流水线化的处理器
  5. 有高速缓存和中断处理的优化流水线化的处理器

以下的页面将会带领你详细地了解构建和使用基本的仿真器,然后再考虑其他的仿真器. 这些仿真器在如何构造和使用上并无区别- 唯一的是在每种情况下的内部结构的不同,这样就导致在同样的环境下一种模型会比另一种模型快。

你可能会想要依次地操作这些仿真器,心里带着想要提高这模型运行速度的目标。

运行所有指令需要花多长时间和单条指令是仿真器的默认输出。如果你想得到一些数据,例如每一类的指令在特 定环境下花多长时间执行, 你需要自己写出这部分代码。这是开源的!你可以做到的。这些代码在这里写得并且解释得很清楚。


怎样运行最基本的MIPS仿真器

这应该有一个Java压缩文件(a jar)zip格式或者tar格式(链接 project page). 如果没有的话,到这看看next section.

你应该把它解压缩。

% unzip jMIPS-1.7.zip jMIPS-1.7/lib/CPU.jar

或者

% tar xzvf jMIPS-1.7.tgz jMIPS-1.7/lib/CPU.jar

同时解压缩一些misc目录下的内容如下

% unzip jMIPS-1.7.zip jMIPS-1.7/misc/hello_mips32

或者

% tar xzvf jMIPS-1.7.tgz jMIPS-1.7/lib/hello_mips32

然后Cpu1 类就可以在任何系统下被Java Virtual Machine (JVM)运行了. 你可能在Linux环境下这样做

% java -cp jMIPS-1.7/lib/CPU.jar CPU.Cpu1 -q jMIPS-1.7/misc/hello_mips32

例如:

% java -cp jMIPS-1.7/lib/CPU.jar CPU.Cpu1 -q jMIPS-1.7/misc/hello_mips32
  Hello world
%

怎样编译基本MIPS仿真器

如果你想编译java代码使其运行,你可以通过以下的方式,这取决于你可以运用的工具。由于人们用不同的 编译工具在用不同的操作系统下,以下的内容将在指定的操作系统下得以运行。

在Linux或者Unix下编译

如果你在用一个Mac, 并且用HFS或者HFS+文件系统, 要进入系统属性就为文件系统开启case sensitivity。你需要这样做,因为否则的话文件名会产生冲突而这是你不希望看到的。

解压缩文件(链接project page)

% unzip jMIPS-1.7.zip

or

% tar xzvf jMIPS-1.7.tgz

分别。

然后在新的未打包的文件树状结构下找到src/目录,并且把它设为当前路径。(用cd jMIPS-1.7/src语句做). 我倾向于选择产生generic Java bytecode 为Java Virtual machine (JVM),用

% javac CPU/Cpu1.java

src/ 目录,之后产生的Cpu1.class文件可以用JVM在 任何的平台上运行。在linux下你可能需要用

% java CPU/Cpu1 -q ../misc/hello_mips32

例如:

% java CPU/Cpu1 -q ../misc/hello_mips32
  Hello world
%

构建一个jar文件是构建所有java类文件的第一个问题:


% javac CPU/*.java
%

然后做一个jar文件

% jar cf ../lib/CPU.jar CPU/*.class
%

事实上,一个jar就仅仅是一个没压缩package的zip, 包括一个额外的manifest文 件。所以你只需要一个zip压缩软件,不必专门的jar工具。 更多细节尽在 [1]


在Windows下编译

导入源文件到java NetBeans IDE, 开始一个新的NB project (取名`jMIPS'), 保证IDE对话框的勾选项`Main Class', 等等,统统不勾。

一旦IDE建立了目录和其所需要的文件,从源代码文档复制src/CPU/ 目录和 *.java 文件,从而建立一个新的,被NetBeans创建的jMPIS目录的"src/CPU/子目录。

利用操作系统从zip文档中直接复制命令,如果可能的话,尽量避免文件在传输过程中避免接触磁盘。 否则Windows可能会隐藏一些文件名。如果NetBeans有一个菜单可以选择“从zip文档导入”或 者“从zip编译”,那就完美了。

IDE会在源代码中进行探测,并且它会扩展'源包裹'树,观测(jMIPS/src 目录)来概括CPU“包裹”以及他的java文件。

如果你愿意的话,你可以从CPU1.java 为每个处理模型系统的重命名java类的文件,等等。举例来说,WinCpu1.java, WinCpu2.java, 等等。你要重命名在每个文件里面声明的类去匹配。

运行仿真器的注意事项

命令行意思的选择如下:

  • 没有选择:在没有任何选择的情况下运行仿真器(特别是在没有“-q”的情况下;例如没有 “quiet”),这将会使每个机器代码指导被一一列出,并且在时间内执行。
% java CPU.Cpu1  hello_mips32
0:      0.000000007s:   0x80030080:     addiu $29, $29, -32
1:      0.000000012s:   0x80030084:     sw $31, 28($29)
2:      0.000000019s:   0x80030088:     sw $30, 24($29)
3:      0.000000024s:   0x8003008c:     addu $30, $29, $0
4:      0.000000030s:   0x80030090:     sw $28, 16($29)
...
218:    0.000001567s:   0x8003000c:     lui $3, -20480
219:    0.000001573s:   0x80030010:     ori $3, $3, 16
220:    0.000001580s:   0x80030014:     sb $3, 0($3)
%


以上代码在0.000001580仿真秒运行了220个命令(时钟的转速是1仿真秒每赫兹)。也就是每个指 令的执行时钟需要转5次。

  • -q:使用“-q”(“quiet”)在它们运行的时候抑制反汇编机器代码指令。换句话说,通过 “-q“,你只能看到被运行程序应该产生什么,并没有其它的杂音。
% java CPU.Cpu1 -q hello_mips32
Hello world
%
  • -d:额外的信息是输出如果”-d“(”debug“)已经给出。 重复”-d“选择用来增加调试杂音的数量。
% java CPU.Cpu1 -d hello_mips32
text start at virtual addr 0x80030000 file offset 0x10000
text end   at virtual addr 0x800300e0 file offset 0x100e0
text entry at virtual addr 0x80030080 file offset 0x10080
read 224B at offset 65536 from file 'hello_mips32'
stack start at virtual addr 0xb0000000
stack end   at virtual addr 0xb0100000
0:      0.000000007s:   0x80030080:     addiu $29, $29, -32
1:      0.000000012s:   0x80030084:     sw $31, 28($29)
2:      0.000000019s:   0x80030088:     sw $30, 24($29)
...
%
  • -o: 例如,你可以通过-o MEMORY_LATENCY=1000设置内部 变量。在”Cmdline.java“查找代码并且添加你自己可能的选择用来设置现在非常短的列表!

请尽情地编辑并在这些源文件上添加你想添加的东西, 把你自己加入源码文件顶端的credit list, 然后提交你改过的代码- 或者发表在你想发表的别的任何地方。

在处理器中产生MIPS机器码来运行

“Hello World”程序准备建在MIPS R3000的机器代码是在作为“hello_mips32”文件在“MISC/”子目录的归档。

(C语言)为它的源代码是在“hello_mips32.c”文件存档“杂项/目录,它的MIPS 汇编”hello_mips32.s“。机器码相当标准已编译从源机器代码,通过

% gcc -static -o hello_mips32 -Wl,-e,f hello_mips32.c

一个真正的MIPS机器上。检查“GCC”的命令(即"man gcc"),以找出此命令行中给出的选项的确切意思。

在非MIPS平台但是在Unix平台上,以下代码应该可以得到与使用的“MIPS-gcc的”交叉编译器 套件同样的结果(通常你可能需要在你的shell环境中的命令设置“MIPS设置”,以设置可执行文件的搜 索路径去连接交叉编译器的组成部分):

% mips-gcc -DMIPS -mips1 -mabi=32 -c hello_mips32.c
% mips-ld -Ttext 0x80003000 -e f -o hello_mips32 hello_mips32.o

MIPS处理器的软件模型代替真正的MIPS机器运行的“Hello World”的机器代码时得心应手。

% java CPU/Cpu1 -q hello_mips32
Hello world

然而,这种模式在执行更为复杂的机器代码,比如涉及中断和外设时,可能不能胜任。

获取源代码

下面一些让你"变成"源代码的一些建议,希望你获得乐趣。

选择一部分非常简单的CPU1 java类的源代码并且按照你个人的满意度来评论它。这是一种相当不错的注释,但是可以肯定的是你会感觉需要更多的(或者更少的,或者不同的)。

用你最大的信用修改编辑它,并且把改动寄给这个工程。

这是获取代码的最好方法。抱怨它写得多么的差并且多么难以理解,并且改正它。

在下面的部分你会发现大量关于代码的说明。你会想要结合手里的这些说明看代码。这些说明将会证明在对于大 型功能特性方面非常有用,只会留下细微差别通过源代码注解来解释。

添加bgezal和bltzal指令到MIPS指令集在一个模拟器的单一的大循环中。

首先查看网页看看指令是干什么的并且它们的机器码格式是什么!唯一可以说的是从名字来看,他们必须是一个 分支指令和跳跃链接指令的交叉。假设bgezal和bltzal非常相似,但是在一个成功的测试中它做了和 jal指令相同的事(在返回的地址寄存器中放置下面这些指令的地址, ra).这在实现一个子程序的调用上是十分有用的。查看google!

用二进制编辑器来为hello world来编辑机器码(如果你是一个视觉识别器的使用者,在Unix系统上,“bvi”将会工作得很好:如果你是编辑器的使用者,你会知道编辑器已经有 一个二进制编辑器)并且用机器码bgezal v0, foo来替换bnez v0, foo。

用修改机器代码来测试你的改性模拟器,你将会需要对程序做一些补偿性的改变来存储和恢复 the $ra return address register around the branch,但是你会看到新分支指令自己工作.

一个简单的未处理的管线式处理器模型

从这页开始,你将会发现一个更复杂的MIPS处理器模型来处理程序。 他们比起基本的MIPS模拟器更快(并且更难理解)。每一个都比之前的更复杂更精致。

你会希望一个一个来解决他们。

运行CPU2模型

如果你从压缩文件中有一个jar文件,你应该能够直接运行字节代码通过下面的代码:

java -cp lib/CPU.jar CPU.Cpu2 misc/helloworld_mips32

Java的源代码在 Cpu2.java文件中。如果需要(比如jar文件丢失或者损坏)你可以编译他通过

javac CPU/Cpu2.java

从未归档文件的src目录中。这将会产生位元码你可以运行它通过

java  CPU.Cpu2 misc/helloworld_mips32


在顶部,代码依然有着与基础CPU1模拟器代码相同的界面:

Cpu2
static void main (String args[]) entry point; handles command line options
CPU2
CPU2 () CPU builder
void run () fetch/decode/execute cycle

但是,在本质上CPU2代码比CPU1中未采用流水线技术的代码要复杂得多,并且不用去走过,虽然你也可 以这么做。

什么是新的?

采用流水线技术的代码与未采用的最大的区别在于,单程提取译码执行循环在未采用流水技术的代码中被分解成 了分开的提取,解码,(读取),执行(和写入)元素(”阶段“),相应的有关各个阶段从哪里开始哪里结束的 评论注解,你可以在未采用流线技术的CPU1的运行代码(比如,”

Image:pipe.gif

注意流水线包含额外的小寄存器(我将会称它们为“持有者”)它们持有从各个阶段为了传到下一个的输入和输 出。换句话说,流水线是一个身体上显现的流水线。“持有者”就像洗衣篮,在洗衣房里,从洗的阶段到烘干阶段 中间,衣物会被放在里面—把衣服从洗衣机里拿出来直接放到烘干机中不是一个问题。洗衣篮和持有者都允许有一 些轻微的风潮在工作过程中。为了下一次使用你要清洗洗衣机,你不需要清理烘干机—你可以把衣服从洗衣机放到 洗衣篮里来取代。