上一篇计算机系统5-> 计组与体系结构2 | MIPS指令集(上)| 指令系统从顶层讲解了一个指令集 / 指令系统应当具备哪些特征和工作原理。这一篇就聚焦MIPS指令集(MIPS32),看看其汇编语句和机器语言是什么样子的。
参考资料:
本文约定MIPS32的数据格式定义如下:
这个不搞搞清楚,后续还会麻烦,不如放在最前面。
自上一篇对于指令系统的整体介绍可以知道,指令集的操作数是指令的操作对象,它有三个来源:立即数、寄存器和存储器。这里来看一下MIPS32指令系统支持的操作数空间。
在上一篇的介绍中,立即数是由地址码表示的,所以MIPS的立即数的长度由指令格式决定,再具体一点是指令格式中的地址码长度决定。
2022-04-16 整理此文期间,老师发了一个讲解寄存器的链接
打开之后,我觉得讲得还不错,对于各个寄存器的功能都有说明,就是排版不太好。
MIPS-32指令集共有32个32位通用寄存器,按照编码原理,机器指令中可以用5个bit来编码32个寄存器;在汇编中可以用寄存器编号0~31表示,但更推荐用它们的名字( $ +两个字符),因为不同的寄存器的默认工作不同,如果有名称来进行区分,对于汇编层次的程序设计者更友好一些。具体表示如:$sp , $t0等等。
为什么会给寄存器取名,从下面这个表格就可见一斑。后续下一篇介绍高级语言程序段的汇编翻译的时候,还会具体说明这些寄存器的功能分类。
为什么使用32个通用寄存器?
答:
使用64个或更多寄存器不但需要更大的指令空间来对寄存器编码,还会增加上下文切换的负担。除了那些很大不能感非常复杂的函数,32个寄存器就已足够保存经常使用的数据。使用更多的寄存器并不必要,同时计算机设计有个原则叫“越小越快”,但是也不是说使用31个寄存器会比32个性能更好,32个通用寄存器是流行的做法。
| 编号 | 助记符 | 英文全称 | 功能简述 |
|---|---|---|---|
| $0 | $zero | zero | 恒零值,0号寄存器参与加法运算可实现MOV功能 |
| $1 | $at | Assemble Temp | 汇编器保留寄存器,可用于伪指令的中间变量 |
| $2 ~ 3 | $v0 ~ v1 | value | 存储子程序的非浮点返回值 |
| $4 ~ 7 | $a0 ~ a3 | Argument | 用于存储子程序调用前的4个非浮点参数 |
| $8 ~ 15 | $t0 ~ t8 | Temporaries | 临时变量,调用者保存寄存器,可在子程序中直接调用 |
| $16 ~ 23 | $s0 ~ s7 | Saved Registers | 通用寄存器,被调用者保存寄存器,在子程序中使用时必须先压栈保存原值,使用后应出栈恢复原值 |
| $24 ~ 25 | $t8 ~ t9 | Temporaries | 临时变量,同$8 ~ 15。 |
| $26 ~ 27 | $k0 ~ k1 | Kernel Reserved | 操作系统内核保留寄存器,用于中断处理 |
| $28 | $gp | Global Pointer | 全局指针 |
| $29 | $sp | Stack Pointer | 栈指针,指向栈顶 |
| $30 | $fp / $s8 | Frame Pointer | 帧指针,用于过程调用;也是$s8,可用作Saved Register |
| $31 | $ra | Return Address | 存储子程序返回地址 |
我们通常意义上说的32个寄存器,就是上述32个通用寄存器。事实上,MIPS还提供了32个32位的单精度浮点寄存器,用$f0 ~ f31表示,两两拼合还可以形成16个64位的双精度寄存器。此外,MIPS还有其他特殊寄存器:
整数乘除寄存器\(hi,\)lo
mfhi("move from hi")来访问hi。mflo("move from lo")访问lo。程序控制器PC
⭐协处理器CP0的寄存器
有230个存储器字,根据00部分的数据格式,这里一个存储器字也就是32位bit,即4个byte,所以换算成我们更常见的形式有:
232bytes = 222KB = 212MB=4GB,可见MIPS32的内存是4GB。
上一篇中我们介绍了指令系统的11 种访存方式,MIPS只采用了其中的五种,即:(也简单回忆一下)
立即数寻址
imm字段 / D字段就是立即数本身。
寄存器寻址
操作数放在某个寄存器中,形式地址D字段 / imm字段给出寄存器的编号,有的指令可能会使用多个寄存器,也就会用到多段寄存器编码段。
基址寻址
寄存器存放基地址,形式地址D字段存放变化量。
相对寻址
EA = PC + 4 + D。
伪直接寻址
这种比较新,实际操作是EA = { PC+4的高四位(31到28),imm(D字段),00 }
可见此处的EA达到了32位bit,也即30位存储字。
对于具体的指令格式,R型指令的寻址方式只有寄存器寻址;I型指令的寻址方式有寄存器寻址、立即数寻址、基址寻址、相对寻址;J型指令的只有伪直接寻址。
了解一个指令集最重要的是指令格式,指令格式统帅了所有其他的方面。MIPS32种所有的指令都是32位定长指令,格式很规整(很漂亮);对于实在难以用统一格式表述的指令,MIPS采取了折中的办法,即让指令的一部分看上去是一样的,其他的部分进行一些微调。
MIPS指令格式有三种:I型、R型、J型;具体格式如下:

下面是对上图各个部分的一个解释:
R型指令的操作数只能来自寄存器,运算结果也只能来自寄存器,属于上一篇中所提到RR型指令。下面先来说说MIPS的R型指令的机器语言格式:
因为具体指令打算放到指令功能里再整理,这里举一个典例,MIPS的加法在汇编中表示为:
add $s1,$t0,$s4
# 当然也可写成
add $17,$8,$20
意思是 把 t0(8号)和s4(20号) 寄存器的内容相加,把结果放到s1(17号)寄存器,机器格式为:
| 位数 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 06 | 05 ~ 00 |
|---|---|---|---|---|---|---|
| 格式 | op | rs | rt | rd | shamt | funct |
| 举例 | 000000 | 8 | 20 | 17 | 0 | 32 |
I型指令就是立即数型指令,至多可以使用两个寄存器,按照执行的功能有以下情况:
举一个典例,MIPS中的beq指令,指令作用是相等则跳转:
beq $s1,$s2,25
意为判断\(s1和\)s2中操作数是否相等,如果相等去地址为PC+4+imm的地方继续运行。
| 位数 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | op | rs | rt | imm |
| 举例 | 000100 | 17 | 18 | 25 |
注意这里的意义是:
if($s1 == $32) go to
PC+4+100 #即 imm<<2
为什么是100不是25呢?
答:如果发生转移,要将imm左移2位,并符号扩展至32位,然后与PC+4相加,加法的结果就是转移目的地址,从该地址取指令。
J型指令主要是无条件转移指令,其特点是仅有操作码和地址码两个字段,采用伪直接寻址,有效地址EA 用PC+4的高4位与 26位的imm经左移2位后拼接得到:
J型指令常用的有两个:j 和 jal
注意:jr和jalr虽然也实现无条件跳转,但不是J型。
| 指令名 | OP | IMM | 实现描述 | 备注 |
|---|---|---|---|---|
| j | 000010 | 26位 | PC <- {PC+431:28,imm,00} | 无条件分支 |
| jal | 000011 | 26位 | R[31] <- PC+8(如无延迟槽为PC+4);PC <- {PC+431:28,imm,00} | 子程序调用指令 |
本部分参考:龙芯杯MIPS指令系统规范手册,开源,上传至博客文件。

一共十四条,包括加、减、乘、除、置1五个小类。
ADD
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 100000 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
ADD rd, rs, rt
功能描述:
操作定义:

例 外:
ADDI
机器格式:
| 地址 | 31 ~ 26 | 26~21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 001000 | rs | rt | imm |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
ADDI rt, rs, imm
功能描述:
操作定义:

例外:
ADDU
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 100001 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
ADDU rd, rs, rt
功能描述:
操作定义:
GPR[rd] ← GPR[rs] + GPR[rt]
例 外:
ADDIU
机器格式:
| 地址 | 31 ~ 26 | 26~21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 001001 | rs | rt | imm |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
ADDIU rt, rs, imm
功能描述:
操作定义:
GPR[rt] ← GPR[rs] + sign_extend(imm)
例 外:
SUB
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 100010 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
SUB rd, rs, rt
功能描述:
操作定义:

例外:
SUBU
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 100011 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
SUBU rd, rs, rt
功能描述:
操作定义:
GPR[rd] ← GPR[rs] – GPR[rt]
例 外:
SLT
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 101010 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
SLT rd, rt, rs
功能描述:
操作定义:
if GPR[rs] < GPR[rt] then
GPR[rd] ← 1
else
GPR[rd] ← 0
endif
例 外:
SLTI
机器格式:
| 地址 | 31 ~ 26 | 26~21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 001010 | rs | rt | imm |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
SLTI rt, rs, imm
功能描述:
操作定义:
if GPR[rs] < Sign_extend(imm) then
GPR[rt] ← 1
else
GPR[rt] ← 0
endif
例 外:
SLTU
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 101011 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
SLTU rd, rs, rt
功能描述:
操作定义:
if (0||GPR[rs]31..0) < (0||GPR[rt]31..0) then
GPR[rd] ← 1
else
GPR[rd] ← 0
endif
例 外:
SLTIU
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 001011 | rs | rt | imm |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
SLTIU rt, rs, imm
功能描述:
操作定义:
if (0||GPR[rs]31..0) < Sign_extend(imm) then
GPR[rt] ← 1
else
GPR[rt] ← 0
endif
例 外:
DIV
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | 00 0000 0000 | 011010 |
| 位数 | 6 | 5 | 5 | 10 | 6 |
汇编格式:
DIV rs, rt
功能描述:
操作定义:

例 外:
DIVU
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | 00 0000 0000 | 011011 |
| 位数 | 6 | 5 | 5 | 10 | 6 |
汇编格式:
DIVU rs, rt
功能描述:
操作定义:

例 外:
MULT
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | 00 0000 0000 | 011000 |
| 位数 | 6 | 5 | 5 | 10 | 6 |
汇编格式:
MULT rs, rt
功能描述:
操作定义:
例 外:
MULTU
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | 00 0000 0000 | 011001 |
| 位数 | 6 | 5 | 5 | 10 | 6 |
汇编格式:
MULTU rs, rt
功能描述:
操作定义:
例 外:无
add, sub, addiaddu, subu, addiuaddu, addiu, subu,即不检查溢出异常

AND
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 100100 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
AND rd, rs, rt
功能描述:
寄存器 rs 中的值与寄存器 rt 中的值按位逻辑与,结果写入寄存器 rd 中。
操作定义:
GPR[rd] ← GPR[rs] & GPR[rt]
例 外:
ANDI
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 001100 | rs | rt | imm |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
ANDI rt, rs, imm
功能描述:
操作定义:
GPR[rt] ← GPR[rs] and Zero_extend(imm)
例 外:
LUI
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 001111 | 00000 | rt | imm |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
LUI rt, imm
功能描述:
操作定义:
GPR[rt] ← (imm || 0000 0000 0000 0000)
例 外:
NOR
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 100111 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
NOR rd, rs, rt
功能描述:
操作定义:
GPR[rd] ← GPR[rs] nor GPR[rt]
例 外:
OR
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 100101 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
OR rd, rs, rt
功能描述:
操作定义:
GPR[rd] ← GPR[rs] or GPR[rt]
例 外:
ORI
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 001101 | rs | rt | imm |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
ORI rt, rs, imm
功能描述:
操作定义:
GPR[rt] ← GPR[rs] or Zero_extend(imm)
例 外:
XOR
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 100110 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
XOR rd, rs, rt
功能描述:
操作定义:
GPR[rd] ← GPR[rs] xor GPR[rt]
例 外:
XORI
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 001110 | rs | rt | imm |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:XORI rt, rs, imm
功能描述:寄存器 rs 中的值与 0 扩展至 32 位的立即数 imm 按位逻辑异或,结果写入寄存器 rt 中。
操作定义:GPR[rt] ← GPR[rs] xor Zero_extend(imm)
例 外:无

SLLV
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 000100 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
SLLV rd, rt, sa
功能描述:
操作定义:
例 外:
SLL
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 000000 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
SLL rd, rt, sa
功能描述:
操作定义:
例 外:
SRAV
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 000111 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
SRAV rd, rt, rs
功能描述:
操作定义:
例 外:
SRA
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 000011 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
SRA rd, rt, sa
功能描述:
操作定义:
例 外:
SRLV
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 000110 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
SRLV rd, rt, rs
功能描述:
操作定义:
例 外:
SRL
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 000000 | rs | rt | rd | 00000 | 000010 |
| 位数 | 6 | 5 | 5 | 5 | 5 | 6 |
汇编格式:
SRL rd, rt, sa
功能描述:
操作定义:
例 外:无

BEQ
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 000100 | rs | rt | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
BEQ rs, rt, offset
功能描述:
操作定义:

例 外:
BNE
汇编格式:
BNE rs, offset
功能描述:
操作定义:

例 外:
BGEZ
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 000001 | rs | 000001 | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
BGEZ rs, offset
功能描述:
操作定义:

例 外:
BGTZ
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 000111 | rs | 000000 | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
BGTZ rs, offset
功能描述:
操作定义:

例 外:
BLEZ
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 000110 | rs | 000000 | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
BLEZ rs, offset
功能描述:
操作定义:

例 外:
BLTZ
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 000001 | rs | 000000 | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
BLTZ rs, offset
功能描述:
操作定义:

例 外:
BGEZAL
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 000001 | rs | 100001 | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
BGEZAL rs, offset
功能描述:
操作定义:

例 外:
BLTZAL
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 000001 | rs | 100000 | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
BLTZAL rs, offset
功能描述:
操作定义:

例 外:
J
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 0 |
|---|---|---|
| 格式 | 000010 | offset |
| 位数 | 6 | 16 |
汇编格式:
J target
功能描述:
操作定义:
例 外:
JAL
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 0 |
|---|---|---|
| 格式 | 000011 | offset |
| 位数 | 6 | 16 |
汇编格式:JAL target18
功能描述:无条件跳转。跳转目标由该分支指令对应的延迟槽指令的 PC 的最高 4 位与立即数 instr_index 左移2 位后的值拼接得到。同时将该分支对应延迟槽指令之后的指令的 PC 值保存至第 31 号通用寄存器中。
操作定义:
例 外:
JR
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|
| 格式 | 000000 | rs | 00 0000 0000 | 00000 | 001000 |
| 位数 | 6 | 5 | 10 | 5 | 6 |
汇编格式:
JR rs
功能描述:
操作定义:
例 外:
JALR
汇编格式:
功能描述:
操作定义:
I: temp← GPR[rs]
GPR[rd] ← PC + 8
I+1: PC ← temp
例 外:

MFHI
指令格式:
| 地址 | 31 ~ 26 | 25 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|
| 格式 | 000000 | 00 0000 0000 | rd | 00000 | 01 0000 |
| 位数 | 6 | 10 | 5 | 5 | 6 |
汇编格式:
MFHI rd
功能描述:
操作定义:
GPR[rd] ← HI
例外:
MFLO
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 16 | 15 ~ 11 | 10 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|---|
| 格式 | 000000 | 00 0000 0000 | rd | 00000 | 01 0010 |
| 位数 | 6 | 10 | 5 | 5 | 6 |
汇编格式:
MFLO rd
功能描述:
操作定义:
GPR[rd] ← LO
例 外:
MTHI
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|
| 格式 | 000000 | rs | 000 0000 0000 0000 | 01 0001 |
| 位数 | 6 | 5 | 15 | 6 |
汇编格式:
MTHI rs
功能描述:
操作定义:
HI ← GPR[rs]
例 外:
MTLO
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|
| 格式 | 000000 | rs | 000 0000 0000 0000 | 01 0011 |
| 位数 | 6 | 5 | 15 | 6 |
汇编格式:
MTLO rs
功能描述:
操作定义:
LO ← GPR[rs]
例 外:

BREAK
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 6 | 5 ~ 0 |
|---|---|---|---|
| 格式 | 000000 | code | 001101 |
| 位数 | 6 | 20 | 6 |
汇编格式:
BREAK
功能描述:
操作定义:
SignalException(Breakpoint)
例外:
SYSCALL
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 6 | 5 ~ 0 |
|---|---|---|---|
| 格式 | 000000 | code | 001100 |
| 位数 | 6 | 20 | 6 |
汇编格式:
SYSCALL
功能描述:
操作定义:
SignalException(SystemCall)
例外:

LB
机器指令:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 100000 | base | rt | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
LB rt, offset(base)
功能描述:
操作定义:

例外:无
LBU
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 100100 | base | rt | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
LBU rt, offset(base)
功能描述:
操作定义:

例外:
LH
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 100001 | base | rt | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
LH rt, offset(base)
功能描述:
操作定义:

例外:
LHU
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 100001 | base | rt | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
LHU rt, offset(base)
功能描述:
操作定义:

例外:
LW
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 100011 | base | rt | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
LW rt, offset(base)
功能描述:
操作定义:

例外:
SB
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 101000 | base | rt | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
SB rt, offset(base)
功能描述:
操作定义:

例外:
SH
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 101011 | base | rt | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
SH rt, offset(base)
功能描述:
操作定义:

例外:
SW
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 0 |
|---|---|---|---|---|
| 格式 | 101011 | base | rt | offset |
| 位数 | 6 | 5 | 5 | 16 |
汇编格式:
SW rt, offset(base)
功能描述:
操作定义:

例外:
特权指令在上一篇中仅简单提到了一次。特权指令指具有特殊权限的指令。 这类指令只用于操作系统或其他系统软件,一般不直接提供给用户使用。 在多用户、多任务的计算机系统中特权指令必不可少。
ERET
机器格式:
| 地址 | 31 ~ 26 | 25 | 25 ~ 6 | 5 ~ 0 |
|---|---|---|---|---|
| 格式 | 010000 | 1 | 000 0000 0000 0000 0000 | 011000 |
| 位数 | 6 | 1 | 19 | 6 |
汇编格式:
eret
功能描述:从 中断、例外 处返回。
操作定义:PC ← EPC,Status.EXL ← 0,刷新流水线。
例外:无
MFC0
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 3 | 2 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 010000 | 00000 | rt | rd | 0000_0000 | sel |
| 位数 | 6 | 5 | 5 | 5 | 8 | 3 |
汇编格式:
MFC0 rt,rd,sel24
功能描述:
操作定义:
例外:
MTC0
机器格式:
| 地址 | 31 ~ 26 | 25 ~ 21 | 20 ~ 16 | 15 ~ 11 | 10 ~ 3 | 2 ~ 0 |
|---|---|---|---|---|---|---|
| 格式 | 010000 | 00100 | rt | rd | 00000000 | sel |
| 位数 | 6 | 5 | 5 | 5 | 8 | 3 |
汇编格式:
MTC0 rt, rd, sel
功能描述:
操作定义:
例外:
指令集其实太多了,比如2020年就又出了Loongarch指令集,要每种都在一篇文中讲完太过分了。其实我最想说的是×86和RISC-V指令集。后续我还打算继续了解这两方面的内容(一个经典且广泛应用,另一个新兴且优美),csapp也是×86指令集。
0417看到一个新闻,说是wave computing(MIPS的ip拥有者)转向了RISC-V。网上感慨的人还很多。
×86由16位的8088 / 8086指令系统发展而来,是32位的CISC系统。
寄存器
共有8个通用寄存器和8个其他寄存器:
通用寄存器有:
| 寄存器编号 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
|---|---|---|---|---|---|---|---|---|
| 寄存器名字 | EAX | ECX | EDX | EBX | ESI | EDI | ESP | EBP |
其他有:状态寄存器EEFLAGS、程序寄存器EIP、还有六个段寄存器CS、SS、DS、ES、FS、GS。
指令格式
×86需要向前兼容16位系统甚至再之前的8位系统,所以现在的×86极其复杂,硬件实现也很困难。从上一篇文也可以知道它是变长编码,通过类似于数据结构哈夫曼树的形式进行编码,实现前缀码不冲突。
寻址方式
支持8种寻址方式:
| 序号 | 寻址方式 | EA / 操作数S | 指令示例 |
|---|---|---|---|
| 1 | 立即数寻址 | S = Disp | MOV EAX,1000 |
| 2 | 直接寻址 | EA = Disp | MOV EAX,[1080H] |
| 3 | 寄存器寻址 | S = R[R / M] | MOV EAX,ECX |
| 4 | 寄存器间接寻址 | EA = R[R / M] | MOV EAX,[EBX] |
| 5 | 寄存器相对寻址 / 基址寻址 | EA = R[R / M] + Disp | MOV EAX,[ESI+100H] |
| 6 | 基址 + 比例变址寻址 | EA = S * index + Base | MOV |
| 7 | 基址 + 比例寻址 + 偏移量寻址 | EA = S * index + Base + Disp | MOV EAX,[EBX+EDI*4+66] |
| 8 | 相对寻址 | EA = PC + Disp | JMP 1000H |
寄存器
RISC-V的寄存器和MIPS大同小异,各种用途的寄存器各有所增减。
指令格式
首先遵循RISC的一些要求,同时可以扩展为变长。RISC-V的特色是指令硬件实现容易,最大的特色是指令字中的各字段位置固定(这一点MIPS都没有做到,可以说更整齐了)。
较于MIPS多了好几种格式。

寻址方式
| # | 寻址方式 | 有效地址EA / S | 指令示例 |
|---|---|---|---|
| 1 | 立即数寻址 | S = imm | addi = rd,rs1,imm |
| 2 | 寄存器寻址 | S = R[rs1] | add rd,rs1,rs2 |
| 3 | 寄存器相对寻址 / 基址寻址 | EA = R[rs1] + imm | lw rd,imm(rs1) |
| 4 | 相对寻址 | EA = PC+imm<<1 | beq rs1,rs2,imm |
加粗是与地址直接相关的部分。
这部分主要针对MIPS指令集本身进行了学习,主要是它上层的汇编表示和下层的机器表示,以及它的访存方式、操作数等等。
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我已经看到了一些其他的问题,尝试了他们的建议,但没有一个对我有用。我已经使用Rails大约一年了,刚刚开始一个新的Rails项目,突然遇到了问题。我卸载并尝试重新安装所有Ruby和Rails。Ruby很好,但Rails不行。当我输入railss时,我得到了can'tfindgemrailties。我当前的Ruby版本是ruby2.2.2p95(2015-04-13修订版50295)[x86_64-darwin15],尽管我一直在尝试通过rbenv设置ruby2.3.0。如果我尝试rails-v查看我正在运行的版本,我会得到同样的错误。我使用的是MacOSXElCapitan版本10
给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in
考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://
给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at