知识
MIPS汇编语言
数量单位
MIPS架构标准寄存器
1.32个32bit的通用寄存器
寄存器编号 | 寄存器名 | 寄存器用途 |
---|---|---|
0 | zero | 永远返回0 |
1 | $at | 汇编保留寄存器(不可用作其他用途) |
2-3 | v0-v1 | (value的简写)存储表达式或者函数的返回值 |
4-7 | a0-a3 | (Argument简写)存储子程序的前4个参数,在子程序调用过程中释放 |
8-15 | t0-t7 | (temp简写)临时变量,同上调用时不保存 |
16-23 | s0-s7 | (Save or Static简)静态变量?调用时保存 |
24-25 | t8-t9 | (Temp简写)算是前面0-7的继续,属性同t0-t7 |
26-27 | k0-k1 | (break off简写)中断函数返回值,不可做其他用途 |
28 | gp | (GlobalPointer简写)指向静态数据块的中间地址 |
29 | $sp | (Stack Pointer简写)栈指针,指向栈顶 |
30 | s8/fp | (Save / Frame Pointer)帧指针 |
31 | $ra | 返回地址,目测不可用作其他用途 |
2.PC 无法直接修改,通过跳转指令可以改动
3.HI 和 LO :这两个寄存器特别用来保存乘法、除法、乘法累加的结果。
内存
除了寄存器以外,内存地址也可能作为MIPS指令的操作数,内存中每个字节有一个编号,因此连续的两个word的地址编号相差4。
MIPS架构中的地址为32位,也就是说地址编号从0 到 4,294,967,295,每个数字代表内存中的一个byte。
整数
32bits表示整数范围:0 到 +4,294,967,295(无符号数),或–2,147,483,648 到 +2,147,483,647(有符号数)。
位扩展
两种可能造成位扩展的指令
-
addi: extend immediate value
-
lb, lh: extend loaded byte/halfword
对于无符号数直接高位补0,对于有符号数高位补符号位。
指令结构
MIPS寻址方式:
(1)寄存器寻址:
(2)立即数寻址:
(3)基址偏移量寻址
通用寄存器作为基址,操作数在存储器中
(4)PC相对寻址
(5)无条件跳转寻址
寻址总结:
7条MIPS指令(关于上面的寻址)
算术运算类:ADD and SUB(R型指令的代表)
add rd, rs, rt (加法)
M[PC],PC ← PC + 4
从PC所指的内存单元中取指令。 PC加4,使PC指向下一条指令。
R[rd] ← R[rs] + R[rt]
从rs、rt 所指的寄存器中取数后相加。 若结果不溢出,则将结果送rd所指的寄存器中;若结果溢出,则不送结果,转到“溢出处理程序”执行。
sub rd, rs, rt (减法)
M[PC],PC ← PC + 4
从PC所指的内存单元中取指令。 PC加4,使PC指向下一条指令。
R[rd] ← R[rs] - R[rt]
从rs、rt 所指的寄存器中取数后相减。 若结果不溢出,则将结果送rd所指的寄存器中;若结果溢出,则不送结果,转到“溢出处理程序”执行。
逻辑运算类:OR Immediate(I型指令) 结果送rt
ori rt, rs, imm16 执行一个寄存器与立即值之间的按位OR运算
M[PC],PC ← PC + 4
从PC所指的内存单元中取指令。 PC加4,使PC指向下一条指令。
R[rt] ← R[rs] | ZeroExt(imm16)
从rs取数,与imm16零扩展(用零填充高字节位)后的值按位或。 结果送rt。
立即数
通常是指在立即寻址方式指令中给出的数。可以是8位、16位或32位,该数值紧跟在操作码之后。如果立即数为16位或32位,那么,它将按“高高低低”的原则进行存储。
偏移地址
就是计算机里的内存分段后,在段内某一地址相对于段首地址(段地址)的偏移量. 如8086存储系统中 20位的物理地址(就是数据存储的实际地址)=16位的段基地址*16+16位的偏移量
访存类:LOAD and STORE(I型指令)
lw rt, rs, imm16 从存储器取操作数到寄存器
M[PC],PC ← PC + 4
从PC所指的内存单元中取指令。 PC加4,使PC指向下一条指令。
Addr ← R[rs] + SignExt(imm16),R[rt] ← M[Addr] 计算数据地址:从rs取数,与imm16符号扩展(用符号位填充到高位字节)后的值相加; [补码加法是符号位扩展] 取数:相加结果作为访存地址(存储器地址),取数送rt(寄存器地址)。
sw rt, rs, imm16 把寄存器的数存储到存储器
M[PC],PC ← PC + 4
从PC所指的内存单元中取指令。 PC加4,使PC指向下一条指令。
Addr ← R[rs] + SignExt(imm16),M[Addr] ← R[rt]
计算数据地址:从rs取数,与imm16符号扩展后的值 相加; 存数:相加结果作为访存地址(即存储器地址,rt将值送到这),将rt中的值送存储器。
转移类(有条件转移):BRANCH (I型指令)
beq rs, rt, imm16 转移有条件
M[PC] 从PC所指的内存单元中取指令。
Cond ← R[rs] - R[rt] , if(Cond==0)PC ← PC+4+SignExt(imm16)<<2
相减比较rs和rt中值的大小,若相等则跳转; 跳转地址:下条指令地址,加上imm16符号扩展后右移2位的值。
转移类(无条件转移): JUMP (J型指令)
j target 转移无条件
M[PC]
从PC所指的内存单元中取指令。
PC < 31:2 > ← PC < 31:28 > || target < 25:0 >
跳转地址与PC高4位拼接后直接 送PC高30位。
单周期处理器设计
指令选择依据:
•选择最具代表性的MIPS指令,包含算术运算、逻辑运算、访存、有条件转移、无条件转移功能。
•格式上包含R型、I型和J型指令。
数据通路设计
取指部件(取指令)后面会说内部构造
每条指令的第一步都相同
取指令 M[PC]
更新PC
时序
每个时钟下降沿PC的值更新一次
区分顺序执行还是转移执行:
•顺序执行: PC ← PC + 4;
•转移执行:区分分支指令(Branch)和跳转指令(Jump),计算对应的转移目标地址,覆盖PC。
ADD/SUB数据通路
<span style="background-color:var(--code-block-bg-color)"><span style="color:var(--code-block-color)"> 指令 op rd rs rt
操作 R[rd] <- R[rs] op R[rt]</span></span>
控制信号: 对应取值
RegWr : 写使能 1
ALUctr : ALU操控信号(即op) add/sub
注意
Overflow 溢出控制信号 (溢出时让使能端为0,进行中断)
Result 返回的结果 busW 由 rt 控制存储位置(在这个寄存器组中)
OR Immediate 数据通路
<span style="background-color:var(--code-block-bg-color)"><span style="color:var(--code-block-color)"> 指令 ori rt rs imm16
操作 R[rt] <- R[rs] | ZeroExt(imm16)</span></span>
由 ALU 来进行按位或
控制信号: 对应取值
ExtOp 控制时零扩展还是符号位扩展 0
ALUSrc 控制是busB输出(rt,因为要与上面的add等兼容) 还是imm16 1
RegDst 控制是rd 还是rt 也是为了兼容 0
RegWr 写使能 1
ALUctr ALU操控信号(即op) or
LOAD数据通路
先对imm16进行符号位扩展,然后与rs相加得到访存地址[存储器访存地址]
将DataMemory中的数据存到rt
<span style="background-color:var(--code-block-bg-color)"><span style="color:var(--code-block-color)"> 指令 lw rt rs imm16
操作 R[rt]← M[R[rs] + SignExt (imm16)] </span></span>
控制信号: 对应取值
ExtOp 控制时零扩展还是符号位扩展 1
ALUSrc 控制是busB输出(rt,因为要与上面的add等兼容) 还是imm16 1
RegDst 控制是rd 还是rt 也是为了兼容 0
RegWr 写使能 1
ALUctr ALU操控信号(即op) lw
MemtoReg 控制是将ALU结果还是存储器读出结果返回 1
MemWr 存储使能,即能不能存储 DataIn 0
注意
result 为存储器访存地址
STORE数据通路
先对imm16进行符号位扩展,然后与rs相加得到访存地址[存储器访存地址]
将busB(rt)中的数据存到DataMemory
<span style="background-color:var(--code-block-bg-color)"><span style="color:var(--code-block-color)"> 指令 sw rt rs imm16
操作 M[R[rs] + SignExt (imm16)] ← R[rt] </span></span>
控制信号: 对应取值
ExtOp 控制时零扩展还是符号位扩展,1为符号位 1
ALUSrc 控制是busB输出(rt,因为要与上面的add等兼容) 还是imm16 1
RegDst 控制是rd 还是rt 也是为了兼容 0
RegWr 写使能 1
ALUctr ALU操控信号(即op) sw
MemtoReg 控制是将ALU结果还是存储器读出结果返回 x(随意)
MemWr 存储使能,即能不能存储 DataIn 1
MemWr 为 1 将busB 存入 DataMemory
BRANCH通路
<span style="background-color:var(--code-block-bg-color)"><span style="color:var(--code-block-color)"> 指令:beq rs, rt, imm16
操作:Cond ← R[rs] - R[rt] , if (Cond==0) PC ← PC + 4 + SignExt (imm16) <<2</span></span>
Next Addr Logic 的输入
PC
Zero标志(Cond) 根据Zero来判断是否转移
imm16
Branch控制信号
注意:
<<2 和 PC + 4 都是因为
下地址逻辑通路设计
<span style="background-color:var(--code-block-bg-color)"><span style="color:var(--code-block-color)"> 指令:顺序指令和条件转移指令
操作(控制信号:Branch):
顺序执行时:PC <31:0> ← PC<31:0> + 4
转移执行时:PC <31:0> ← PC<31:0> + 4 + SignExt[Imm16]×4</span></span>
实现原理: MIPS按字节编址,每条指令32位,占4个字节,故PC的值总是4的倍数,即后两位为00,因此PC只需要30位即可。
实现方法: 内部采用30位PC设计。 顺序执行时: PC< 31:2> ← PC< 31:2> + 1 转移执行时: PC< 31:2> ← PC< 31:2> + 1 + SignExt[Imm16] 取指令时: 指令地址 = PC< 31:2> ||00
计算转移地址用2个加法器实现。
Branch信号和Zero都为1时 转移执行
否则 顺序执行
JUMP数据通路
<span style="background-color:var(--code-block-bg-color)"><span style="color:var(--code-block-color)"> 指令:j target
操作:PC<31:2> ← PC<31:28> || target<25:0></span></span>
控制信号取值:
RegDst=ExtOp=ALUSrc=MemtoReg=Branch=ALUctr=x,
RegWr=MemWr=0, 跳转时使能信号为0
Jump=1 (为0时为BRANCH通路 , 为1时为JUMP通路)
取指令部件(Instruction Fetch Unit)的外部构造
Zero 由 ALU 给出
其他时控制IFU的控制信号单独给出
完整数据通路
ALU
SUBctr=0,做加法; SUBctr=1,做减法。
OPctr=0,算术加/减结果输出;OPctr=1,逻辑或结果输出。
OVctr=0,无需判断溢出; OVctr=1,需要判断溢出。
对ALU操作控制输入信号ALUctr的设计
控制逻辑单元设计
核心:
指令译码器 输入指令操作码op(含功能码func),输出控制信号。
设计方法:
根据每条指令的功能,分析控制信号的取值,并在表中列出。
根据列出的指令和控制信号的关系,写出每个控制信号的逻辑表达式。
硬布线实现。
控制信号取值分析:
一条指令可分为取指令和执行指令两个阶段。
每条指令的取指令阶段的操作相同。
每条指令的执行过程不同。
取值部件操作(用的刚刚设计的取指令部件)
1.取指令:Instruction ← M[PC] 从PC所指的内存单元中取指令。 所有指令该步操作均相同。> 位于指令操作的第一步。新指令还没有取出译码,所以控制信号的值还是原来指令的旧值。 新指令还没有执行,所以标志也为旧值。
2.PC取值的确实
<span style="background-color:var(--code-block-bg-color)"><span style="color:var(--code-block-color)"> 给出下一条指令地址: PC ← PC + 4; 除 Branch 和 Jump 以外(Branch = 0 Zero = x jump = 0) 或者(Branch = 1 Zero = 0 jump = 0) PC ← PC + 4 + SignExt(imm16)<<2 (zero = 1 Branth = 1 jump = 0) PC<31:2> ← PC<31:28> || target<25:0> (zero = x Branth = x jump = 1)</span></span>
执行阶段的操作
指令:add rd, rs, rt / sub rd, rs, rt
•操作:R[rd] ← R[rs] ± R[rt]
•执行路径:Registers (rs, rt) → busA, busB → ALU → Registers (rd)
•控制信号取值:Branch=0,Jump=0,RegDst=1,RegWr=1,ALUSrc=0,ALUctr=add/sub,MemtoReg=0,MemWr=0,ExtOp=x。
指令:ori rt, rs, imm16
•操作:R[rt] ← R[rs] | ZeroExt(imm16)
•执行路径:Registers (rs) → busA;imm16 → 扩展器 ;busA,扩展器→ ALU → Registers (rt)
•控制信号取值:Branch=0,Jump=0,RegDst=0,RegWr=1,ALUSrc=1,ALUctr=or,MemtoReg=0,MemWr=0,ExtOp=0。
指令:lw rt, rs, imm16
•操作:Addr ← R[rs] + SignExt (imm16),R[rt]← M[Addr]
•执行路径:Registers (rs) → busA;imm16 → 扩展器; busA, 扩展器 → ALU → 数据存储器 → Registers (rt)
•控制信号取值:Branch=0,Jump=0,RegDst=0,RegWr=1,ALUSrc=1,ALUctr=addu,MemtoReg=1,MemWr=0,ExtOp=1。
指令:sw rt, rs, imm16
•操作:Addr ← R[rs] + SignExt (imm16),M[Addr] ← R[rt]
•执行路径:Registers (rs) → busA; imm16 → 扩展器 ;busA, 扩展器 → ALU → 数据存储器; Registers (rt) → busB → 数据存储器。
•控制信号取值:Branch=0,Jump=0,RegDst=x,RegWr=0,ALUSrc=1,ALUctr=addu,MemtoReg=x,MemWr=1,ExtOp=1。
指令:beq rs, rt, imm16
•操作:Cond ← R[rs] - R[rt] , if (Cond==0) PC ← PC + 4 + SignExt (imm16) <<2
•执行路径:Registers (rs, rt) → busA, busB → ALU → 取指部件。
•控制信号取值:Branch=1,Jump=0,RegDst=x,RegWr=0,ALUSrc=0,ALUctr=subu,MemtoReg=x,MemWr=0,ExtOp=x。
指令:j target
•操作:PC< 31:2> ← PC< 31:28> || target< 25:0>
•执行路径:无
•控制信号取值:Branch=x,Jump=1,RegDst=x,RegWr=0,ALUSrc=x,ALUctr=x,MemtoReg=x,MemWr=0,ExtOp=x。
时钟周期的确定
Lw指令的时钟周期