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

参考资料:

  1. Computer Organization and Design the 5th Edition,即计算机组成与设计硬件软件接口第五版
  2. 龙芯杯MIPS指令系统规范手册
  3. 课件,由于是英文且只是老师的思路,所以是辅助参考
  4. 《计算机组成原理》谭志虎,HUST(此书强推)
  5. 《计算机组成原理》MOOC HUST

00 数据格式

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

  1. 比特(bit, b)
  2. 字节(Byte, 8bits, B)
  3. 半字(Halfword, 16bits, H)
  4. 字(Word, 32bits, W)

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

01 操作数

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

01-1 立即数操作数

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

01-2 寄存器操作数

2022-04-16 整理此文期间,老师发了一个讲解寄存器的链接

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

此文第32问之后,讲解了为什么是32个通用寄存器

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

    • hi 寄存器存放乘法指令结果的高半部分或是除法指令结果的余数。
    • 用指令mfhi("move from hi")来访问hi。
    • lo 寄存器存放乘法指令结果的低半部分或是除法指令结果的商。
    • 用指令mflo("move from lo")访问lo。
  • 程序控制器PC

    • 无法直接访问。
  • 协处理器CP0的寄存器

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

01-3 存储器操作数

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

232bytes = 222KB = 212MB=4GB,可见MIPS32的内存是4GB。

02 寻址方式

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

  1. 立即数寻址

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

  2. 寄存器寻址

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

  3. 基址寻址

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

  4. 相对寻址

    EA = PC + 4 + D。

  5. 伪直接寻址

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

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

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

03 指令格式

03-1 统一介绍

了解一个指令集最重要的是指令格式,指令格式统帅了所有其他的方面。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位的有符号立即数,立即数范围为 [-32768, 32767]。J型指令的instr_index(Address字段)有26位。

03-2 R型 / 寄存器型

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

03-3 I型 / 立即数型

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

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

举一个典例,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相加,加法的结果就是转移目的地址,从该地址取指令。

03-4 J型 / 跳转型

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} 子程序调用指令

04 指令功能

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

04-1 算术运算指令

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

  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
    • 功能描述:

      • 将寄存器 rs 的值与寄存器 rt 的值相加,结果写入寄存器 rd 中。如果产生溢出,则触发整型溢出例外(IntegerOverflow)。
    • 操作定义:

    • 外:

      • 如果有溢出,则触发整型溢出例外。
  2. ADDI

    • 机器格式:

      地址 31 ~ 26 26~21 20 ~ 16 15 ~ 0
      格式 001000 rs rt imm
      位数 6 5 5 16
    • 汇编格式:

      • ADDI rt, rs, imm
    • 功能描述:

      • 将寄存器 rs 的值与有符号扩展至 32 位的立即数 imm 相加,结果写入 rt 寄存器中。如果产生溢出,则触发整型溢出例外(IntegerOverflow)。
    • 操作定义:

    • 例外:

      • 如果有溢出,则触发整型溢出例外。
  3. 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
    • 功能描述:

      • 将寄存器 rs 的值与寄存器 rt 的值相加,结果写入 rd 寄存器中。
    • 操作定义:

      GPR[rd] ← GPR[rs] + GPR[rt]
    • 外:

  4. ADDIU

    • 机器格式:

    • 汇编格式:

      ADDIU rt, rs, imm
    • 功能描述:

      • 将寄存器 rs 的值与有符号数至 32 位的立即数 imm 相加,结果写入 rt 寄存器中。(没写错1!)
    • 操作定义:

      GPR[rt] ← GPR[rs] + sign_extend(imm)
    • 外:

    • ADDI,ADDIU,ADD,ADDU的区别、有符号无符号的谬误

  5. 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
    • 功能描述:

      • 将寄存器 rs 的值与寄存器 rt 的值相减,结果写入 rd 寄存器中。如果产生溢出,则触发整型溢出例外(IntegerOverflow)。
    • 操作定义:

    • 例外:

  6. 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
    • 功能描述:

      • 将寄存器 rs 的值与寄存器 rt 的值相减,结果写入 rd 寄存器中。
    • 操作定义:

      GPR[rd] ← GPR[rs] – GPR[rt]
    • 外:

  7. 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
    • 功能描述:

      • 将寄存器 rs 的值与寄存器 rt 中的值进行有符号数比较,如果寄存器 rs 中的值小,则寄存器 rd 置 1;否则寄存器 rd 置 0
    • 操作定义:

      if GPR[rs] < GPR[rt] then
      GPR[rd] ← 1
      else
      GPR[rd] ← 0
      endif
    • 外:

  8. SLTI

    • 机器格式:

      地址 31 ~ 26 26~21 20 ~ 16 15 ~ 0
      格式 001010 rs rt imm
      位数 6 5 5 16
    • 汇编格式:

      SLTI rt, rs, imm
    • 功能描述:

      • 将寄存器 rs 的值与有符号扩展至 32 位的立即数 imm 进行有符号数比较,如果寄存器 rs 中的值小,则寄存器 rt 置 1;否则寄存器 rt 置 0。
    • 操作定义:

      if GPR[rs] < Sign_extend(imm) then
      GPR[rt] ← 1
      else
      GPR[rt] ← 0
      endif
    • 外:

  9. 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
    • 功能描述:

      • 将寄存器 rs 的值与寄存器 rt 中的值进行无符号数比较,如果寄存器 rs 中的值小,则寄存器 rd 置 1;否则寄存器 rd 置 0。
    • 操作定义:

      if (0||GPR[rs]31..0) < (0||GPR[rt]31..0) then
      GPR[rd] ← 1
      else
      GPR[rd] ← 0
      endif
    • 外:

  10. SLTIU

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 001011 rs rt imm
      位数 6 5 5 16
    • 汇编格式:

      SLTIU rt, rs, imm
    • 功能描述:

      • 将寄存器 rs 的值与有符号扩展 至 32 位的立即数 imm 进行无符号数比较,如果寄存器 rs 中的值,则寄存器 rt 置 1;否则寄存器 rt 置 0。
    • 操作定义:

      if (0||GPR[rs]31..0) < Sign_extend(imm) then
      GPR[rt] ← 1
      else
      GPR[rt] ← 0
      endif
    • 外:

  11. 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
    • 功能描述:

      • 有符号除法,寄存器 rs 的值除以寄存器 rt 的值,商写入 LO 寄存器中,余数写入 HI 寄存器中。
    • 操作定义:

    • 外:

  12. 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
    • 功能描述:

      • 无符号除法,寄存器 rs 的值除以寄存器 rt 的值,商写入 LO 寄存器中,余数写入 HI 寄存器中。
    • 操作定义:

    • 外:

  13. 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
    • 功能描述:

      • 有符号乘法,寄存器 rs 的值乘以寄存器 rt 的值,乘积的低半部分和高半部分分别写入 LO 寄存器和 HI 寄存器。
    • 操作定义:

      • prod ← GPR[rs]31..0 ×GPR[rt]31..0
      • LO ← prod31..0
      • HI ← prod63..32
    • 外:

  14. 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
    • 功能描述:

      • 无符号乘法,寄存器 rs 的值乘以寄存器 rt 的值,乘积的低半部分和高半部分分别写入 LO 寄存器和 HI 寄存器。
    • 操作定义:

      • prod ← (0 || GPR[rs]31..0) ×(0 || GPR[rt]31..0)
      • LO ← prod31..0
      • HI ← prod63..32
    • 外:

04-2 逻辑运算指令

  1. 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]
    • 外:

  2. ANDI

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 001100 rs rt imm
      位数 6 5 5 16
    • 汇编格式:

      ANDI rt, rs, imm
    • 功能描述:

      • 寄存器 rs 中的值与 0 扩展至 32 位的立即数 imm 按位逻辑与,结果写入寄存器 rt 中。
    • 操作定义:

      GPR[rt] ← GPR[rs] and Zero_extend(imm)
    • 外:

  3. LUI

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 001111 00000 rt imm
      位数 6 5 5 16
    • 汇编格式:

      LUI rt, imm
    • 功能描述:

      • 将 16 位立即数 imm 写入寄存器 rt 的高 16 位,寄存器 rt 的低 16 位置 0。
    • 操作定义:

      GPR[rt] ← (imm || 0000 0000 0000 0000)
    • 外:

  4. 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
    • 功能描述:

      • 寄存器 rs 中的值与寄存器 rt 中的值按位逻辑或非,结果写入寄存器 rd 中。
    • 操作定义:

      GPR[rd] ← GPR[rs] nor GPR[rt]
    • 外:

  5. 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
    • 功能描述:

      • 寄存器 rs 中的值与寄存器 rt 中的值按位逻辑或,结果写入寄存器 rd 中。
    • 操作定义:

      GPR[rd] ← GPR[rs] or GPR[rt]
    • 外:

  6. ORI

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 001101 rs rt imm
      位数 6 5 5 16
    • 汇编格式:

      ORI rt, rs, imm
    • 功能描述:

      • 寄存器 rs 中的值与 0 扩展至 32 位的立即数 imm 按位逻辑或,结果写入寄存器 rt 中。
    • 操作定义:

      GPR[rt] ← GPR[rs] or Zero_extend(imm)
    • 外:

  7. 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
    • 功能描述:

      • 寄存器 rs 中的值与寄存器 rt 中的值按位逻辑异或,结果写入寄存器 rd 中。
    • 操作定义:

      GPR[rd] ← GPR[rs] xor GPR[rt]
    • 外:

  8. 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)

    • 外:

04-3 移位指令

  1. 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
    • 功能描述:

      • 由寄存器 rs 中的值指定移位量,对寄存器 rt 的值进行逻辑左移,结果写入寄存器 rd 中。
    • 操作定义:

      • s ← GPR[rs]4..0
      • GPR[rd] ← GPR[rt](31-s)..0 || 0s
    • 外:

  2. 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
    • 功能描述:

      • 由立即数 sa 指定移位量,对寄存器 rt 的值进行逻辑左移,结果写入寄存器 rd 中。
    • 操作定义:

      • s ← sa
      • GPR[rd] ← GPR[rt](31-s)..0 || 0s
    • 外:

  3. 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
    • 功能描述:

      • 寄存器 rs 中的值指定移位量,对寄存器 rt 的值进行算术右移,结果写入寄存器 rd 中。
    • 操作定义:

      • s ← GPR[rs]4..0
      • GPR[rd] ← (GPR[rt]31) s || GPR[rt]31..s
    • 外:

  4. 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
    • 功能描述:

      • 立即数 sa 指定移位量,对寄存器 rt 的值进行算术右移,结果写入寄存器 rd 中。
    • 操作定义:

      • s ← sa
      • GPR[rd] ← (GPR[rt]31) s || GPR[rt]31..s
    • 外:

  5. 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
    • 功能描述:

      • 寄存器 rs 中的值指定移位量,对寄存器 rt 的值进行逻辑右移,结果写入寄存器 rd 中。
    • 操作定义:

      • s ←GPR[rs]4..0
      • GPR[rd] ← 0s || GPR[rt]31..s
    • 外:

  6. 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
    • 功能描述:

      • 立即数 sa 指定移位量,对寄存器 rt 的值进行逻辑右移,结果写入寄存器 rd 中。
    • 操作定义:

      • s ← sa
      • GPR[rd] ← 0s || GPR[rt]31..s
    • 外:

04-4 分支跳转指令

  1. BEQ

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 000100 rs rt offset
      位数 6 5 5 16
    • 汇编格式:

      BEQ rs, rt, offset
    • 功能描述:

      • 如果寄存器 rs 的值等于寄存器 rt 的值则转移,否则顺序执行。转移的目标地址由立即数 offset 左移 2 位并进行有符号扩展的值加上该分支指令对应的延迟槽指令的 PC 计算得到。
    • 操作定义:

    • 外:

  2. BNE

    • 汇编格式:

      BNE rs, offset
    • 功能描述:

      • 如果寄存器 rs 的值不等于寄存器 rt 的值则转移,否则顺序执行。转移目标由立即数 offset 左移 2位并进行有符号扩展的值加上该分支指令对应的延迟槽指令的 PC 计算得到。
    • 操作定义:

    • 外:

  3. BGEZ

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 000001 rs 000001 offset
      位数 6 5 5 16
    • 汇编格式:

      BGEZ rs, offset
    • 功能描述:

      • 如果寄存器 rs 的值大于等于 0 则转移,否则顺序执行。转移目标由立即数 offset 左移 2 位并进行有符号扩展的值加上该分支指令对应的延迟槽指令的 PC 计算得到。
    • 操作定义:

    • 外:

  4. BGTZ

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 000111 rs 000000 offset
      位数 6 5 5 16
    • 汇编格式:

      BGTZ rs, offset
    • 功能描述:

      • 如果寄存器 rs 的值大于 0 则转移,否则顺序执行。转移目标由立即数 offset 左移 2 位并进行有符号扩展的值加上该分支指令对应的延迟槽指令的 PC 计算得到。
    • 操作定义:

    • 外:

  5. BLEZ

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 000110 rs 000000 offset
      位数 6 5 5 16
    • 汇编格式:

      BLEZ rs, offset
    • 功能描述:

      • 如果寄存器 rs 的值小于等于 0 则转移,否则顺序执行。转移目标由立即数 offset 左移 2 位并进行有符号扩展的值加上该分支指令对应的延迟槽指令的 PC 计算得到。
    • 操作定义:

    • 外:

  6. BLTZ

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 000001 rs 000000 offset
      位数 6 5 5 16
    • 汇编格式:

      BLTZ rs, offset
    • 功能描述:

      • 如果寄存器 rs 的值小于 0 则转移,否则顺序执行。转移目标由立即数 offset 左移 2 位并进行有符号扩展的值加上该分支指令对应的延迟槽指令的 PC 计算得到。
    • 操作定义:

    • 外:

  7. BGEZAL

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 000001 rs 100001 offset
      位数 6 5 5 16
    • 汇编格式:

      BGEZAL rs, offset
    • 功能描述:

      • 如果寄存器 rs 的值大于等于 0 则转移,否则顺序执行。转移目标由立即数 offset 左移 2 位并进行有符号扩展的值加上该分支指令对应的延迟槽指令的 PC 计算得到。无论转移与否,将该分支对应延迟槽指令之后的指令的 PC 值保存至第 31 号通用寄存器中。
    • 操作定义:

    • 外:

  8. BLTZAL

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 000001 rs 100000 offset
      位数 6 5 5 16
    • 汇编格式:

      BLTZAL rs, offset
    • 功能描述:

      • 如果寄存器 rs 的值小于 0 则转移,否则顺序执行。转移目标由立即数 offset 左移 2 位并进行有符号扩展的值加上该分支指令对应的延迟槽指令的 PC 计算得到。无论转移与否,将该分支对应延迟槽指令之后的指令的 PC 值保存至第 31 号通用寄存器中。
    • 操作定义:

    • 外:

  9. J

    • 机器格式:

      地址 31 ~ 26 25 ~ 0
      格式 000010 offset
      位数 6 16
    • 汇编格式:

      J target
    • 功能描述:

      • 无条件跳转。跳转目标由该分支指令对应的延迟槽指令的 PC 的最高 4 位与立即数 instr_index 左移2 位后的值拼接得到。
    • 操作定义:

      • I:
      • I+1: PC ← PC31..28 || instr_index || 02
    • 外:

  10. JAL

    • 机器格式:

      地址 31 ~ 26 25 ~ 0
      格式 000011 offset
      位数 6 16
    • 汇编格式:JAL target18

    • 功能描述:无条件跳转。跳转目标由该分支指令对应的延迟槽指令的 PC 的最高 4 位与立即数 instr_index 左移2 位后的值拼接得到。同时将该分支对应延迟槽指令之后的指令的 PC 值保存至第 31 号通用寄存器中。

    • 操作定义:

      • I: GPR[31] ← PC + 8
      • I+1: PC ← PC31..28 || instr_index || 02
    • 外:

  11. 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
    • 功能描述:

      • 无条件跳转。跳转目标为寄存器 rs 中的值。
    • 操作定义:

      • I: temp ← GPR[rs]
      • I+1: PC ← temp
    • 外:

  12. JALR

    • 汇编格式:

      • JALR rd, rsJALR rs (rd=31 implied)
    • 功能描述:

      • 无条件跳转。跳转目标为寄存器 rs 中的值。同时将该分支对应延迟槽指令之后的指令的 PC 值保存至寄存器 rd 中。
    • 操作定义:

      • I: temp← GPR[rs]

        ​ GPR[rd] ← PC + 8

      • I+1: PC ← temp

    • 外:

04-5 数据移动指令

  1. 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
    • 功能描述:

      • 将 HI 寄存器的值写入到寄存器 rd 中
    • 操作定义:

      GPR[rd] ← HI
    • 例外:

  2. 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
    • 功能描述:

      • 将 LO 寄存器的值写入到寄存器 rd 中。
    • 操作定义:

      GPR[rd] ← LO
    • 外:

  3. MTHI

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 6 5 ~ 0
      格式 000000 rs 000 0000 0000 0000 01 0001
      位数 6 5 15 6
    • 汇编格式:

      MTHI rs
    • 功能描述:

      • 将寄存器 rs 的值写入到 HI 寄存器中。
    • 操作定义:

      HI ← GPR[rs]
    • 外:

  4. MTLO

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 6 5 ~ 0
      格式 000000 rs 000 0000 0000 0000 01 0011
      位数 6 5 15 6
    • 汇编格式:

      MTLO rs
    • 功能描述:

      • 将寄存器 rs 的值写入到 LO 寄存器中。
    • 操作定义:

      LO ← GPR[rs]
    • 外:

04-6 自陷指令

  1. BREAK

    • 机器格式:

      地址 31 ~ 26 25 ~ 6 5 ~ 0
      格式 000000 code 001101
      位数 6 20 6
    • 汇编格式:

      BREAK
    • 功能描述:

      • 触发断点例外。
    • 操作定义:

      SignalException(Breakpoint)
    • 例外:

      • 断点例外
  2. SYSCALL

    • 机器格式:

      地址 31 ~ 26 25 ~ 6 5 ~ 0
      格式 000000 code 001100
      位数 6 20 6
    • 汇编格式:

      SYSCALL
    • 功能描述:

      • 触发系统调用例外。
    • 操作定义:

      SignalException(SystemCall)
    • 例外:

      • 系统调用例外。

04-7 访存指令

  1. LB

    • 机器指令:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 100000 base rt offset
      位数 6 5 5 16
    • 汇编格式:

      LB rt, offset(base)
    • 功能描述:

      • 取一个有符号byte
      • 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,据此虚地址从存储器中读取 1 个字节的值并进行符号扩展,写入到 rt 寄存器中。
    • 操作定义:

    • 例外:

  2. LBU

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 100100 base rt offset
      位数 6 5 5 16
    • 汇编格式:

      LBU rt, offset(base)
    • 功能描述:

      • 取一个无符号byte
      • 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,据此虚地址从存储器中读取 1 个字节的值并进行 0 扩展,写入到 rt 寄存器中。
    • 操作定义:

    • 例外:

  3. LH

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 100001 base rt offset
      位数 6 5 5 16
    • 汇编格式:

      LH rt, offset(base)
    • 功能描述:

      • 取半个有符号字( half word);
      • 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,如果地址不是 2 的整数倍则触发地址错例外,否则据此虚地址从存储器中读取连续 2 个字节的值并进行符号扩展,写入到rt 寄存器中。
    • 操作定义:

  • 例外:

    • 地址最低 1 位如果不为 0,触发地址错误例外
  1. LHU

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 100001 base rt offset
      位数 6 5 5 16
    • 汇编格式:

      LHU rt, offset(base)
    • 功能描述:

      • 取半个无符号字;
      • 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,如果地址不是 2 的整数倍则触发地址错例外,否则据此虚地址从存储器中读取连续 2 个字节的值并进行 0 扩展,写入到 rt寄存器中。
    • 操作定义:

    • 例外:

      • 地址最低 1 位不为 0,触发地址错例外
  2. LW

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 100011 base rt offset
      位数 6 5 5 16
    • 汇编格式:

      LW rt, offset(base)
    • 功能描述:

      • 取一个字;
      • 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,如果地址不是 4 的整数倍则触发地址错例外,否则据此虚地址从存储器中读取连续 4 个字节的值,写入到 rt 寄存器中。
    • 操作定义:

    • 例外:

      • 地址最低 2 位不为 0,触发地址错例外
  3. SB

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 101000 base rt offset
      位数 6 5 5 16
    • 汇编格式:

      SB rt, offset(base)
    • 功能描述:

      • 写入一个byte。
      • 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,如果地址不是 4 的整数倍则触发地址错例外,否则据此虚地址从存储器中读取连续 4 个字节的值,写入到 rt 寄存器中。
    • 操作定义:

    • 例外:

  4. SH

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 101011 base rt offset
      位数 6 5 5 16
    • 汇编格式:

      SH rt, offset(base)
    • 功能描述:

      • 写入半个字
      • 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,如果地址不是 2 的整数倍则触发地址错例外,否则据此虚地址将 rt 寄存器的低半字存入存储器中。
    • 操作定义:

    • 例外:

      • 地址最低 1 位不为 0,触发地址错误例外
  5. SW

    • 机器格式:

      地址 31 ~ 26 25 ~ 21 20 ~ 16 15 ~ 0
      格式 101011 base rt offset
      位数 6 5 5 16
    • 汇编格式:

      SW rt, offset(base)
    • 功能描述:

      • 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,如果地址不是 4 的整数倍则触发地址错例外,否则据此虚地址将 rt 寄存器存入存储器中。
    • 操作定义:

    • 例外:

      • 地址最低 2 位不为 0,触发地址错误例外

04-8 特权指令

特权指令在上一篇中仅简单提到了一次。特权指令指具有特殊权限的指令。 这类指令只用于操作系统或其他系统软件,一般不直接提供给用户使用。 在多用户、多任务的计算机系统中特权指令必不可少。

  1. 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,刷新流水线。

    • 例外:

  2. 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
    • 功能描述:

      • 从协处理器 0 的寄存器(由rd和sel组合指定)取值到通用寄存器rt中(用GPR表示),当然,有一些CP0寄存器不支持sel,这时sel=0
    • 操作定义:

      • GPR[rt] ← CP0[rd, sel]
    • 例外:

  3. 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
    • 功能描述:

      • 向协处理器 0 的寄存器存值
    • 操作定义:

      • CP0[rd, sel] ← GPR[rt]
    • 例外:

05 其他指令集简介

指令集其实太多了,比如2020年就又出了Loongarch指令集,要每种都在一篇文中讲完太过分了。其实我最想说的是×86和RISC-V指令集。后续我还打算继续了解这两方面的内容(一个经典且广泛应用,另一个新兴且优美),csapp也是×86指令集。

0417看到一个新闻,说是wave computing(MIPS的ip拥有者)转向了RISC-V。网上感慨的人还很多。

05-1 ×86

×86由16位的8088 / 8086指令系统发展而来,是32位的CISC系统。

  1. 寄存器

    共有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。

  2. 指令格式

    ×86需要向前兼容16位系统甚至再之前的8位系统,所以现在的×86极其复杂,硬件实现也很困难。从上一篇文也可以知道它是变长编码,通过类似于数据结构哈夫曼树的形式进行编码,实现前缀码不冲突。

  3. 寻址方式

    支持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

05-2 RISC - V

清华计组RISC-V

  1. 寄存器

    RISC-V的寄存器和MIPS大同小异,各种用途的寄存器各有所增减。

  2. 指令格式

    首先遵循RISC的一些要求,同时可以扩展为变长。RISC-V的特色是指令硬件实现容易,最大的特色是指令字中的各字段位置固定(这一点MIPS都没有做到,可以说更整齐了)。

    较于MIPS多了好几种格式。

  3. 寻址方式

    # 寻址方式 有效地址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

    加粗是与地址直接相关的部分。

06 简单回顾 | Review

这部分主要针对MIPS指令集本身进行了学习,主要是它上层的汇编表示和下层的机器表示,以及它的访存方式、操作数等等。

  1. 可以用的操作数;
  2. 寻址方式各种;
  3. 以指令功能分类的各种指令,方便查阅;
  4. 简单提了提其他指令集

计算机系统6-> 计组与体系结构3 | MIPS指令集(中)| MIPS汇编指令与机器表示的更多相关文章

  1. MIPS 指令集开源了

    去年年底我们报导过 MIPS 指令集将于今年第一季度开源的消息,现在 MIPS 官方已经正式将其释出. MIPS 是一种精简指令集(Reduced Instruction Set Computer,R ...

  2. MIPS 指令集将在近期开源,RISC-V 阵营慌吗?

    消息称,MIPS 指令集即将开源. eetimes 17 日报导,Wave Computing 公司表示,在明年第一季度发布最新 MIPS 指令集体系和 MIPS 最新内核 R6 的时候将开源 MIP ...

  3. 计算机系统5-> 计组与体系结构2 | MIPS指令集(上)| 指令系统

    系列的上一篇计算机系统4-> 计组与体系结构1 | 基础概念与系统评估,学习了一些计算机的基础概念,将一些基本的计算机组成部分的功能和相互联系了解了一下,其中很重要的一个抽象思想就是软硬件的接口 ...

  4. 【计组】《计算机组成与体系结构性能设计》William Stallings 第2部分 计算机系统 第3章 计算机功能和互连的顶层视图

    关键词 address bus 地址总线 asynchronous timing 异步时序 bus 总线 bus arbitration 总线仲裁 bus width 总线宽度 centralized ...

  5. 计算机系统4-> 计组与体系结构1 | 基础概念介绍

    在大二上学期学习数字逻辑的过程中,我对计算机如何运作产生了兴趣,因此开了这个系列来记录自己在这方面的学习过程,此前三篇分别是: 计算机系统->Hello World的一生 | 程序如何运行,从大 ...

  6. EYES组——软件体系结构上机规划

    EYES组——软件体系结构上机规划 考勤助手 第九周: 需求分析的详细撰写,并在此基础上探讨与完善,讨论软件的体系结构风格,画出初步的UML类图. 第十周: 选择合适的软件构架风格(3层C/S架构风格 ...

  7. 计组CPU设计实验关键材料和关键设计

    我记得这是2016春季学期搞得,参考和学习了很多别人的东西,这里小小的总结一下,逻辑性还不是太强,还需要好好整理 首先是指令集 CPU架构 外部接线架构 指令格式 机器状态自动机 这部分忘了,汗 这部 ...

  8. 用户、组或角色 '' 在当前数据库中已存在。 (Microsoft SQL Server,错误: 15023)

    SQLServer2008用户组或角色'*****'在当前数据库中已存在问题的解决办法 在迁移数据库的过程中SQLServer SDE的问题 为一个数据库添加一个用户时,提示以下信息:用户.组或角色 ...

  9. 自己动手写处理器之第一阶段(2)——MIPS指令集架构的演变

    将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第三篇.我尽量每周四篇 MIPS指令集架构自上世纪80年代出现后.一直在进行着更新换代,从最初的MIPS I到MIPS V,发 ...

随机推荐

  1. 数字IC笔试题-芯源

    前言 由于最近开始找数字IC的工作,所以准备多练笔试题,下面贴上芯源笔试题,来源微信公众号<数字IC打工人> 参考资源: 1. mu_guang_ 2.  李锐博恩 3. 长弓的坚持 4. ...

  2. Spring核心思想:IOC(控制反转)、DI(依赖注入)和AOP(面向切面编程)

    Spring有三大核心思想,分别是控制反转(IOC,Inversion Of Controller),依赖注入(DI,Dependency Injection)和面向切面编程(AOP,Aspect O ...

  3. 【基础】java环境搭建及配置--->【关注微信公众号:三叔测试笔记,及时获取干货】

    一.下载安装 Java官网下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...

  4. 知识点简单总结——BSGS与EXBSGS

    知识点简单总结--BSGS与EXBSGS BSGS 给出 $ A,B,C,(A,C)=1 $ ,要你求最小的 $ x $ ,使得 $ A^x \equiv B(mod \ C) $ . 在数论题中经常 ...

  5. 27.Java 飞机游戏小项目

    开篇 游戏项目基本功能开发 飞机类设计 炮弹类设计 碰撞检测设计 爆炸效果的实现 其他功能 计时功能 游戏项目基本功能开发 这里将会一步步实现游戏项目的基本功能. 使用 AWT 技术画出游戏主窗口 A ...

  6. Spring---Spring专题(二)

    1.Spring配置数据源 1.1 数据源(连接池)的作用 数据源(连接池)是提高程序性能而出现的 事先实例化数据源,初始化部分链接资源 使用连接资源时从数据源中获取 使用完毕后将连接资源归还给数据源 ...

  7. mac phpstorm返回文件顶部或者底部

    在Mac下,请按FN+Command+→|←,就这么简单~

  8. LIKE 声明中的%和_是什么意思?

    %对应于 0 个或更多字符,_只是 LIKE 语句中的一个字符. 如何在 Unix 和 MySQL 时间戳之间进行转换? UNIX_TIMESTAMP 是从 MySQL 时间戳转换为 Unix 时间戳 ...

  9. 什么是 Spring MVC 框架的控制器?

    控制器提供一个访问应用程序的行为,此行为通常通过服务接口实现.控制器解 析用户输入并将其转换为一个由视图呈现给用户的模型.Spring 用一个非常抽象 的方式实现了一个控制层,允许用户创建多种用途的控 ...

  10. Qunee for HTML5 v1.6新版本发布

    Qunee for HTML5 V1.6正式发布,修复了一些 BUG,增加了滚动条支持,改进了编辑器,增加了JSON 导入导出.告警冒泡.连线流动,UI 定制等扩展示例,欢迎 访问 导航面板 增加了滚 ...