写出图3-28的助记符程序?

上一篇从顶层讲解了一个指令集 / 指令系统应当具备哪些特征和工作原理。这一篇就聚焦MIPS指令集(MIPS32),看看其汇编语句和机器语言是什么样子的。

  1. 龙芯杯MIPS指令系统规范手册
  2. 课件,由于是英文且只是老师的思路,所以是辅助参考
  3. 《计算机组成原理》谭志虎,HUST(此书强推)

本文约定MIPS32的数据格式定义如下:

这个不搞搞清楚,后续还会麻烦,不如放在最前面。

自上一篇对于指令系统的整体介绍可以知道,指令集的操作数是指令的操作对象,它有三个来源:立即数、寄存器和存储器。这里来看一下MIPS32指令系统支持的操作数空间。

01-1 立即数操作数

在上一篇的介绍中,立即数是由地址码表示的,所以MIPS的立即数的长度由指令格式决定,再具体一点是指令格式中的地址码长度决定。

01-2 寄存器操作数

整理此文期间,老师发了一个讲解

打开之后,我觉得讲得还不错,对于各个寄存器的功能都有说明,就是排版不太好。

MIPS-32指令集共有32个32位通用寄存器,按照编码原理,机器指令中可以用5个bit来编码32个寄存器;在汇编中可以用寄存器编号0~31表示,但更推荐用它们的名字(\(+两个字符),因为不同的寄存器的**默认工作不同**,如果有名称来进行区分,对于汇编层次的程序设计者更友好一些。具体表示如:\)sp , $t0等等。

为什么会给寄存器取名,从下面这个表格就可见一斑。后续下一篇介绍高级语言程序段的汇编翻译的时候,还会具体说明这些寄存器的功能分类。

为什么使用32个通用寄存器?

使用64个或更多寄存器不但需要更大的指令空间来对寄存器编码,还会增加上下文切换的负担。除了那些很大不能感非常复杂的函数,32个寄存器就已足够保存经常使用的数据。使用更多的寄存器并不必要,同时计算机设计有个原则叫“越小越快”,但是也不是说使用31个寄存器会比32个性能更好,32个通用寄存器是流行的做法。

恒零值,0号寄存器参与加法运算可实现MOV功能
汇编器保留寄存器,可用于伪指令的中间变量
存储子程序的非浮点返回值
用于存储子程序调用前的4个非浮点参数
临时变量,调用者保存寄存器,可在子程序中直接调用
通用寄存器,被调用者保存寄存器,在子程序中使用时必须先压栈保存原值,使用后应出栈恢复原值
操作系统内核保留寄存器,用于中断处理

我们通常意义上说的32个寄存器,就是上述32个通用寄存器。事实上,MIPS还提供了32个32位的单精度浮点寄存器,用$f0 ~ f31表示,两两拼合还可以形成16个64位的双精度寄存器。此外,MIPS还有其他特殊寄存器:

    • hi 寄存器存放乘法指令结果的高半部分或是除法指令结果的余数。
  • lo 寄存器存放乘法指令结果的低半部分或是除法指令结果的商。
  • 协处理器CP0的寄存器

    • CP0是协处理器((Co-Processor)之一其中有一组寄存器,一共32个;
    • CP0 必须实现,起到控制CPU的作用,主要用于中断、例外控制。MMU、异常处理、乘除法等功能,都依赖于协处理器CP0来实现。它是MIPS的精髓之一,也是打开MIPS特权级模式的大门。
    • 后续的特权指令中会有很多使用CP0寄存器的地方。
    • 这里提一个寄存器,EPC,这个寄存器存放异常发生时,系统正在执行的指令的地址。后面特权指令ERET会用到。

01-3 存储器操作数

有230个存储器字,根据00部分的数据格式,这里一个存储器字也就是32位bit,即4个byte,所以换算成我们更常见的形式有:

上一篇中我们介绍了指令系统的11 种访存方式,MIPS只采用了其中的五种,即:(也简单回忆一下)

  1. imm字段 / D字段就是立即数本身。

  2. 操作数放在某个寄存器中,形式地址D字段 / imm字段给出寄存器的编号,有的指令可能会使用多个寄存器,也就会用到多段寄存器编码段。

  3. 寄存器存放基地址,形式地址D字段存放变化量。

  4. 这种比较新,实际操作是EA = { PC+4的高四位(31到28),imm(D字段),00 }

    可见此处的EA达到了32位bit,也即30位存储字。

对于具体的指令格式,R型指令的寻址方式只有寄存器寻址;I型指令的寻址方式有寄存器寻址、立即数寻址、基址寻址、相对寻址;J型指令的只有伪直接寻址。

了解一个指令集最重要的是指令格式,指令格式统帅了所有其他的方面。MIPS32种所有的指令都是32位定长指令,格式很规整(很漂亮);对于实在难以用统一格式表述的指令,MIPS采取了折中的办法,即让指令的一部分看上去是一样的,其他的部分进行一些微调。

MIPS指令格式有三种:I型、R型、J型;具体格式如下:

下面是对上图各个部分的一个解释:

  • 图中opcode字段就是操作码,一般简称为OP,不过R型指令有一点与众不同,R型指令的OP段全为0),具体的指令功能由低6位function(funct) 字段决定,这里的funct字段就是扩展操作码
  • 至于寻址方式,MIPS的寻址方式是没有单独的字段的,而是放在操作码字段里。
  • 上面看到的rs、rt、rd就是寄存器操作数字段,各用五位表示(32个通用寄存器正好编码5个二进制位);R型指令可以有三个寄存器操作数,而I型指令最多两个寄存器操作数,而J型不需要寄存器操作数。
  • 上图其他元素还有shamt字段(五位的sa),用于移位指令,其他指令这一段为0;以及I型指令的imm字段,可以表示16位的有符号立即数,立即数范围为 [-3]。J型指令的instr_index(Address字段)有26位。

R型指令的操作数只能来自寄存器,运算结果也只能来自寄存器,属于上一篇中所提到RR型指令。下面先来说说MIPS的R型指令的机器语言格式:

因为具体指令打算放到指令功能里再整理,这里举一个典例,MIPS的加法在汇编中表示为:

意思是 把 t0(8号)和s4(20号) 寄存器的内容相加,把结果放到s1(17号)寄存器,机器格式为:

0

I型指令就是立即数型指令,至多可以使用两个寄存器,按照执行的功能有以下情况:

  1. 如果是双目运算,则将寄存器rs和立即数imm分别作为源操作数,将结果送入rt寄存器中;
  2. 如果是Load / Store指令,则将寄存器rs和立即数imm值相加得到有效地址EA,将EA送入rt寄存器中;
  3. 如果是条件分支指令,则对rs和rt寄存器中的数据进行规定的判别运算,并根据结果决定是否进行跳转,如果发生跳转,那么跳转后的地址EA由相对寻址方式获得(PC+4与立即数imm相加得到)

举一个典例,MIPS中的beq指令,指令作用是相等则跳转:

意为判断\(s1和\)s2中操作数是否相等,如果相等去地址为PC+4+imm的地方继续运行。

为什么是100不是25呢?

答:如果发生转移,要将imm左移2位,并符号扩展至32位,然后与PC+4相加,加法的结果就是转移目的地址,从该地址取指令。

J型指令主要是无条件转移指令,其特点是仅有操作码和地址码两个字段,采用伪直接寻址,有效地址EA 用PC+4的高4位26位的imm经左移2位后拼接得到:

J型指令常用的有两个:j 和 jal

注意:jr和jalr虽然也实现无条件跳转,但不是J型。

本部分参考:龙芯杯MIPS指令系统规范手册,开源,上传至博客文件。

04-1 算术运算指令

一共十四条,包括加、减、乘、除、置1五个小类。

      • 将寄存器 rs 的值与寄存器 rt 的值相加,结果写入寄存器 rd 中。如果产生溢出,则触发整型溢出例外(IntegerOverflow)。
      • 如果有溢出,则触发整型溢出例外。
      • 将寄存器 rs 的值与有符号扩展至 32 位的立即数 imm 相加,结果写入 rt 寄存器中。如果产生溢出,则触发整型溢出例外(IntegerOverflow)。
      • 如果有溢出,则触发整型溢出例外。
      • 将寄存器 rs 的值与寄存器 rt 的值相加,结果写入 rd 寄存器中。
    • 将寄存器 rs 的值与有符号数至 32 位的立即数 imm 相加,结果写入 rt 寄存器中。(没写错1!)
      • 将寄存器 rs 的值与寄存器 rt 的值相减,结果写入 rd 寄存器中。如果产生溢出,则触发整型溢出例外(IntegerOverflow)。
      • 将寄存器 rs 的值与寄存器 rt 的值相减,结果写入 rd 寄存器中。
      • 将寄存器 rs 的值与寄存器 rt 中的值进行有符号数比较,如果寄存器 rs 中的值小,则寄存器 rd 置 1;否则寄存器 rd 置 0
      • 将寄存器 rs 的值与有符号扩展至 32 位的立即数 imm 进行有符号数比较,如果寄存器 rs 中的值小,则寄存器 rt 置 1;否则寄存器 rt 置 0。
      • 将寄存器 rs 的值与寄存器 rt 中的值进行无符号数比较,如果寄存器 rs 中的值小,则寄存器 rd 置 1;否则寄存器 rd 置 0。
    • /problem/Gym-101991J 题目很长,其实就是给你一个正三角形,并且告诉你它的中点在Z轴上以及法向量,边长和顶点A的坐标(自由度已定),让你求A ...

}

我要回帖

更多关于 与指令的助记符是 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信