27 26 25 24
第 3 版 · OCR 辅助 · 原书检索 · 文字用于定位,公式与图表请回原页核验 · 本次导入快照
### 27 26 25 24
20
19
15
1412
11
7
6
0
R
funct7
rs2
rsl
funct3
rd
opcode
1
imm[11:0]
rsl
funct3
rd
opcode
S
imm[11:5]
rs2
rsl
funct3
imm[4:0]
opcode
B
imm[12]10:5]
rs2
rsl
funct3
imm[4:1|11]
opcode
u
imm[31:12]
rd
opcode
J
imm[2010:1|11|19:12]
rd
opcode
图4.12 32位 RISC-V 指令格式
从图4.12可看出,所有格式中低7位都是操作码字段 opcode;字段 rd、rs1和 rs2 给出
的是通用寄存器编号。因为32位RISC-V架构共有32个32位通用寄存器x0~x31(编号
为0~31),因而通用寄存器编号占5位,0号寄存器x0的内容永远是0;imm字段给出的是
一个立即数,其位数在中括号([])中表示;字段 funct3和 funct7分别表示3位功能码和7
位功能码,它们和 opcode字段一起定义指令的操作功能。
为了缩短程序的二进制代码的长度,RISC-V提供了压缩指令集RVC,其中,每条指令
的长度都是16位。与32位指令相比,16位指令中的一部分寄存器编号还是占5位,但操
作码、功能码、立即数和部分寄存器编号的位数都减少了。
·4.4.3基础整数指令集
为简化对指令功能的说明,本节将采用寄存器传送级(register transfer level,RTL)语
言描述指令功能。这里RTL语言约定:R[r]表示通用寄存器r的内容,M[addr]表示存
储单元addr的内容;M[R[r]]表示寄存器r的内容所指存储单元的内容;PC表示 PC的
内容,M[PC]表示 PC所指存储单元的内容;SEXT[imm]表示对 imm进行符号扩展,
ZEXT[imm]表示对imm进行零扩展;传送方向用一表示,即传送源在右,传送目的在左。
RISC-V基础整数指令集 RV32I中包含整数运算、控制转移、存储器访问和系统控制几
大类指令。
1.整数运算类指令
指令集 RV32I中的整数运算类指令包括移位、算术运算、逻辑运算和比较指令,共21
条。图4.13 给出了这些整数运算指令的格式以及操作码及功能码的编码。
U-型指令共有两条,一条是“lui rd,imm20”指令,其功能为将立即数imm20存到 rd寄
存器的高20位,并使rd低12位为0。该指令和“addi rd,rs1,imm12”指令结合,可以实现
对一个32位变量赋初值。另一条U-型指令为“auipc rd,imm20”,其功能为将20位立即数
imm20加到PC的高20位上,结果存rd。可用指令“auipc x10,0”将当前PC的内容存入寄
存器x10中。该指令采用相对寻址方式,可用于生成动态链接所需的共享库中的位置无关
代码(PIC),实现动态库代码等公共子程序的浮动。
I-型指令助记符都带i,表示一个操作数为立即数。例如,I-型加法指令“addi rd,rs1,
imm12”的功能为将12位立即数imm12符号扩展到32位,再与rsl寄存器内容相加,结果
存rd,用RTL语言描述为R[rd]-R[rs1]+SEXT[imm?2]。因为addi指令可以直接加一
第4章
119
<!-- page: 137 -->
计算机组成与系统结构(第3版)
31
2524
2019
1514
1211
76
0
imm[31:12]
rd
0110111
U lui
imm[31:12]
rd
0010111
U auipc
120
imm[11:0]
rsl
000
rd
0010011
### 1 addi
imm[11:0]
rsl
010
rd
0010011
I slti
imm[11:0]
rsl
011
rd
0010011
### 1 sltiu
imm[11:0]
rsl
100
rd
0010011
### 1 xori
imm[11:0]
rsl
110
rd
0010011
### 1 ori
imm[11:0]
rsl
111
rd
0010011
l andi
0000000
shamt
rsl
001
rd
0010011
I slli
0000000
shamt
rsl
101
rd
0010011
I srli
0100000
shamt
rsl
101
rd
0010011
### 1 srai
0000000
rs2
rsl
000
rd
0110011
R add
0100000
rs2
rsl
000
rd
0110011
R sub
0000000
rs2
rsl
001
rd
0110011
R sll
0000000
rs2
rsl
010
rd
0110011
R slt
0000000
rs2
rsl
011
rd
0110011
R sltu
0000000
rs2
rsl
100
rd
0110011
R xor
0000000
rs2
rsl
101
rd
0110011
R srl
0100000
rs2
rsl
101
rd
0110011
R sra
0000000
rs2
rsl
110
rd
0110011
R or
0000000
rs2
rsl
111
rd
0110011
R and
图4.13 整数运算类指令
个负数,因而无须提供subi指令。
R-型指令的两个操作数所在寄存器总是rs1和rs2,结果寄存器为rd。例如,减法指令
“sub rd,rsl,rs2”的功能为:R[rd]-R[rsl]-R[rs2]。
例4.11 假定变量x分配在寄存器x5中,请给出C语句“int x=—8191;”所对应的
RISC-V机器级代码。
解:因为无法在 RISC-V指令中直接给出一个32位立即数,所以需要将常数—8191分
解为两个立即数。—8191对应的32位机器数为1111 1111 1111 1111 1110 0000 0000 0001,
因此,可以先将其高20位11111111 111111111110装入x5的高20位(低12位清0),再在 x5
中加上低 12 位0000 0000 0001。
C语句“int x=—8191;”对应的 RISC-V机器指令和汇编指令为
### 1111 1111 1111 1111 1110 00101 0110111 lui ×5,1048574 #R[×5]*FFFF E00OH
### 0000 0000 0001 00101 000 00101 0010011 addi x5,x5,1
#R[x5]*-R[x5]+SExT[001H]
RV321指令集提供了与(and、andi)、或(or、ori)和异或(xor、xori)三种共6条逻辑运算
指令。
移位指令“sll rd,rsl,rs2”和“slli rd,rsl,shamt”的opcode字段编码不同,前者属于
R-型格式,指令的24~20位为5位寄存器编号;而后者为I型格式,指令的24~20位为5
位立即数。两条指令的功能都是将rs1的内容左移若干位后存到rd中。前者用rs2 存放左
移位数,后者用立即数shamt指定左移位数。
<!-- page: 138 -->
指令系统
因为逻辑左移和算术左移的结果完全相同,因而RV32I中没有算术左移指令。而逻辑
右移和算术右移分别采用高位补0和高位补符方式,移位后结果不同,因而需分别提供两种
右移指令。右移位数的指定和左移位数一样,可用寄存器或立即数两种方式指定。
例4.12 假定变量x分配在寄存器x5中,请给出C语句“int x=8191;”所对应的
RISC-V机器级代码。
解:8191对应的32位机器数为0000 0000 0000 0000 0001 1111 1111 1111,这里,低 12
位中最高位为1,是一个负数,addi指令按符号扩展进行立即数相加,若采用以下两条指令
实现,则x5中的结果为4095,而不是8191。
### 0000 0000 0000 0000 0001 00101 0110111 lui x5,1
*R[x5]-0000 1000H
### 1111 1111 1111 00101 000 00101 0010011 addi x5,x5,-1
#R[×5]-R[×5]+SEXT[FFFH]
事实上,可以利用addi进行符号扩展的特性来完成该立即数的分配。先通过lui指令
装入一个距离目标常数小于2048的数,然后通过addi的符号扩展特性,对结果进行加法或
减法操作来修正。由于需要修正的范围小于2048,位于12 位立即数的范围内,因此总是可
以修正成功。在本例中,由于8191=8192-1,因此可以先将8192(其高20位为00002H)装
人x5,再通过addi对x5减1即可。
C语句“intx=8191;”对应的RISC-V机器指令和汇编指令为
### 0000 0000 0000 0000 0010 00101 0110111 lui x5,2
#R[x5]*-0000 2000H
### 1111 1111 1111 00101 000 00101 0010011 addi x5,x5,-1
#R[×5]R[x5]+SEXT[FFFH]
RV32I提供了4条比较指令,它们是带符号整数小于(slt、slti)和无符号整数小于
(sltu、sltiu)指令。这里,slti和sltiu指令中的12位立即数imm12都按符号扩展。例如,
“sltiu rd,rsl,imm12”的功能为将rs1寄存器中的内容与imm12 的符号扩展结果按无符
号整数比较,若小于,则1存入rd中;否则,0存入rd中。因此,sltiu指令中imm12的值应
小于2048。若需比较的数据大于或等于2048,则应先将该数存入某寄存器,然后用sltu指
令实现比较。
例4.13 假定变量x、y和z都是long long型,占64位,x的高、低32位分别存放在寄
存器 x13、x12中;y的高、低32位分别存放在寄存器x15、x14中;z的高、低32位分别存放
在寄存器x11、x10中,请写出C语句“z=x+y;”所对应的32位字长 RISC-V机器级代码。
解:可通过sltu指令将低32位的进位加入到高32位中。“z=x+y;”所对应的机器级
代码如下:
add x10,x12,x14*R[x10]-R[x12]+R[x14]
### 0000000 01110 01100 000 01010 0110011
### 0000000 01100 01010 011 01011 0110011 s1tux11,x10,x12#若R[×10]<R[x12]则 R[x11]-1
### 0000000 01111 01101 000 10000 0110011 add x16,×13,x15#R[x16]*-R[x13]+R[x15]
add x11,x11,x16#R[x11]-R[x11]+R[x16]
### 0000000 10000 01011 000 01011 0110011
2.控制转移类指令
RV32I中的控制转移(也称顺序控制)类指令包括6条分支指令和两条无条件跳转并
链接指令。图4.14给出了控制转移类指令的格式以及操作码的编码。
从图4.14可看出,控制转移类指令中,6条分支指令采用B-型格式,其功能如下:若rsl
和rs2两个寄存器内容比较的结果满足条件,则跳转到转移目标地址处执行;否则执行下条
第4章
121
<!-- page: 139 -->
计算机组成与系统结构(第3版)
31
2524
2019
1514
1211
76
0
imm[20|10:1|11|19:12]
rd
1101111
imm[11:0]
rsl
000
rd
1100111
Jjal
l jalr
imm[12|10:5]
rs2
rsl
000
imm[4:1|11]
1100011
imm[12|10:5]
rs2
rsl
001
imm[4:1|11]
1100011
B beq
B bne
imm[12|10:5]
rs2
rsl
100
imm[4:1|11]
1100011
B blt
imm[12|10:5]
rs2
rsl
101
imm[4:1|11]
1100011
B bge
imm[12]10:5]
rs2
rsl
110
imm[4:1|11]
1100011
B bltu
imm[12|10:5]
rs2
rsl
111
imm[4:1|11]
1100011
B bgeu
图 4.14 控制转移类指令
指令。比较条件包括相等(beq)、不等(bne)、带符号整数小于(blt)、带符号整数大于或等于
(bge)、无符号整数小于(bltu)、无符号整数大于或等于(bgeu)。因为指令的宽度总是4字
节(对于RV32G)或2字节(对于RV32C),因而总是2的倍数,即指令地址最低位总是0。
转移目标地址采用相对寻址方式,其偏移量为imm[12:1]乘2,相当于在imm[12:1]后面添
一个0,再符号扩展为32位,因此,转移目标地址=PC+SEXT[imm[12:1]<<1]。
RISC-V硬件不包含整数算术运算的溢出检测电路,因而也不会生成溢出标志OF,需
由编译器确定是否检测溢出,并生成溢出检测的机器级代码。
例4.14 假定变量x、y、z分别存放在寄存器x5、x6、x7中,写出x、y、z都为int类型
时,C语句“z=x+y;”所对应的RISC-V机器级代码,要求检测是否溢出。
解:当x、y为int类型时,若y<0且x+y≥r或者y≥0且x+y<x,则x+y溢出。
实现“z=x+y;”并判溢出的 RISC-V机器指令、汇编指令及注释如下:
### 0000000 00110 00101 000 00111 0110011 add ×7,x5,x6 #R[×7]~-R[x5]+R[×6]
### 0000 0000 0000 00110 010 11100 0010011 slti x28,x6,0 #若R[x6]<0,则R[x28]~-1
### 0000000 00101 00111 010 11101 0110011 slt x29,x7,x5 #若 R[x7]<R[x5],则 R[×29]*-1
### 0000010 11101 11100 001 10000 1100011 bne x28,x29,overflew
#若 R[x28]≠R[x29],则转溢出处理
⋯⋯
overflew:
这里,假定标号为overflew的指令与“bne x28,x29,overflew”之间相距 20条指令,每
条指令为32位,则“bne x28,x29,overflew”指令中的偏移量应为80,因此,指令中的立即数为
40=0000 0010 1000B,按照 B-型格式,该指令的机器码为0000010 11101 11100 001 10000 1100011。
RV32I中的两条跳转并链接(jump and link)指令jal和jalr分别采用J-型和I-型格式。
指令“jal rd,imm20”的功能如下:PC-PC+SEXT[imm[20:1]<<1];R[rd]-PC+
4。它具有双重功能:①若将返回地址(PC+4)保存到寄存器x1,则可实现过程调用;②若
目的寄存器rd指定为x0,则可实现无条件跳转,因为x0不能更改。过程调用或无条件跳
转的转移目标地址为PC+SEXT[imm[20:1]<<1]。
指令“jalr rd,rsl,imm12”的功能如下:PC-R[rs1]+SEXT[imm12];R[rd]-PC+
4。指令“jalr x?,x1,0”可以实现过程调用的返回。将目的寄存器rd设为x0时,可以用
jalr指令实现 switch-case语句的地址跳转。若先通过U-型指令装入rs1,则可实现 32 位地
址空间的绝对或相对跳转。
<!-- page: 140 -->
指令系统
3.存储器访问指令
RV32I中的存储器访问类指令包括5条取数(load)指令和3条存数(store)指令。图 4.15
给出了存储器访问类指令的格式以及操作码的编码。
31
2524
2019
1514
1211
76
0
imm[11:0]
rs1
000
rd
0000011
I 1b
imm[11:0]
rsl
001
rd
0000011
### 1 1h
imm[11:0]
rsl
010
rd
0000011
11w
imm[11:0]
rsl
100
rd
0000011
### 1 lbu
imm[11:0]
rsl
101
rd
0000011
### 1 1hu
imm[11:5]
rs2
rsl
000
imm[4:0]
0100011
Ssb
imm[11:5]
rs2
rsl
001
imm[4:0]
0100011
Ssh
imm[11:5]
rs2
rsl
010
imm[4:0]
0100011
S sw
图 4.15 存储器访问类指令
RV32I除了提供32位字的取数(lw)和存数(sw)指令外,还支持带符号整数的字节、半
字取数(Ib、Ih)和无符号整数的字节、半字取数(Ibu、lhu)指令,以及字节、半字存数(sb、sh)
指令。对于64位架构,RISC-V还具有支持64位双字为单位的存储器读写操作。
取数指令的功能如下:R[rd]-M[R[rs1]+SEXT[imm12]]。带符号整数的字节、半
字取数指令,对取出数据按符号扩展为32位后,再写入目的寄存器rd中;无符号整数的字
节、半字取数指令,对取出数据按0扩展为32位后,再写入目的寄存器rd中。
存数指令的功能如下:M[R[rsl]+SEXT[imm12]]-R[rs2]。字节、半字存数指令分
别将源寄存器 rs2中的低8位、低16位写入存储单元中。采用小端方式存放。
取数指令和存数指令的汇编形式中,存储器操作数的存储地址可以写成imm12(rsl),
例如,指令“lw rd,rsl,imm12”的汇编形式也可以写成“lw rd,imm12(rsl)”;指令“sw
rs1,rs2,imm12”的汇编形式也可以写成“sw rs2,imm12(rsl)”。
与ARM和MIPS内存数据按自然边界对齐的要求不同,RISC-V没有边界对齐要求,
处理器可以根据性能要求选择是否支持按边界对齐。
此外,为了不增加ISA的复杂性,与x86不同,RISC-V没有专门的入栈(push)和出栈
(pop)指令,而是使用普通的取数(相当于出栈)和存数(相当于入栈)指令实现栈操作。为
了降低处理器设计难度,RISC-V的load和store 指令不支持地址自增和自减模式。
4.系统控制类指令
RV32I提供了相应的系统控制类指令,用于指令执行流和数据流的同步、控制从用户
程序陷入调试环境或操作系统内核执行,以及对控制状态寄存器(control and status
register,CSR)的读写等方面。
RISC-V架构支持多核(multi-core)及多线程(multi-threading)技术。一个 CPU 芯片
中可以有多个 RISC-V处理器核(core),每个处理器核中可设计多个硬件线程(hardware
thread,hart),每个 hart有自己独立的程序计数器、通用寄存器组等用于存放现场信息的资
源,运算资源是核内所有 hart共享,而主存储器则是所有处理器核共享。因此,对于这种共
享存储器的硬件多线程处理器,就存在与多核系统和多处理器系统相同的存储器一致性模
型(memory consistency model)问题。所以需要有支持同步等机制的指令。
第4章
123
<!-- page: 141 -->
计算机组成与系统结构(第3版)
124
控制状态寄存器 CSR用于配置或记录程序性能和状态信息,是处理器核的内部寄存
器,使用内部地址编码空间,和主存地址的编码没有关系,也与通用寄存器的编码没有关系。
程序可以通过执行6条专用的CSR指令(csrrw、csrrs、csrrc,csrrwi,csrrsi、csrrci),设置相
应的控制信息或读取状态信息。对这些系统控制类指令的理解涉及机器特权级、硬件线程、
异常、中断、存储管理和输入/输出等与操作系统相关的概念。有关系统控制类指令涉及的
概念已超出本书涵盖的范围,感兴趣的读者可以查阅相关资料。
4.5本 章 小 结
指令系统设计包括指令格式、操作数类型、数据在存储器中的存放方式、寻址方式、操作
类型和操作码编码、异常和中断处理机制、指令系统风格等内容。采用定长指令字和定长操
作码,可以方便指令地址计算、取指和译码操作,而采用变长指令字和变长操作码,则指令各
字段编码紧凑,且程序占空间少。
指令类型主要包括数据传送、算术逻辑运算、字符串处理、I/O操作、程序流控制和系统
控制等;指令涉及的操作数类型主要有无符号整数、带符号整数、浮点数、位串等;常用指令
寻址方式有立即、直接、间接、寄存器直接、寄存器间接、栈寻址和偏移(包括相对、变址和基
址)寻址方式。
对应高级语言程序中的选择结构和循环结构,相应的机器代码中需要有条件转移(分
支)指令,它们根据不同的标志信息来改变程序的执行顺序。常用的标志有CF(进/借位标
志)、ZF(零标志)、OF(溢出标志)、SF(符号标志)等。实现过程调用需要指令系统提供调用
指令和返回指令,并要确定过程之间如何传递参数,哪些寄存器为调用者保存寄存器,哪些
是被调用者保存寄存器等。
习题
1.给出以下概念的解释说明。
指令
指令集体系结构(ISA)
操作码
地址码
程序计数器(PC)
指令指针(IP)
程序状态字(PSW)
程序状态字寄存器
标志寄存器
寻址方式
有效地址
立即寻址
直接寻址
间接寻址
寄存器寻址
寄存器间接寻址
变址寻址
变址寄存器
相对寻址
基址寻址
基址寄存器
通用寄存器(GPR)
CISC
RISC
内部异常
外部中断
故障
陷阱
断点
中断请求
伪指令
叶子过程
栈指针寄存器
帧指针寄存器栈帧
2.简单回答下列问题。
(1)一条指令中应该显式或隐式地给出哪些信息?
(2)什么是汇编过程?什么是反汇编过程?这两个操作都需要用到什么信息?
(3)CPU如何确定指令中各个操作数的类型、长度以及所在地址?
(4)哪些寻址方式下的操作数在寄存器中?哪些寻址方式下的操作数在存储器中?
(5)基址寻址方式和变址寻址方式有何相同点和不同点?
(6)为何分支指令的转移目标地址通常用相对寻址方式?
<!-- page: 142 -->
指令系统
(7)RISC处理器的特点有哪些?
(8)CPU中标志寄存器的功能是什么?有哪几种基本标志?
(9)转移指令和转子(调用)指令的区别是什么?返回指令是否需要有地址码字段?
3.假定某计算机中有一条转移指令,采用相对寻址方式,共占两字节,第一字节是操作码,第二字节是
相对位移量(用补码表示),CPU每次从内存只能取一字节。假设执行到某转移指令时 PC的内容为200,
执行该转移指令后要求转移到100开始的一段程序执行,则该转移指令第二字节的内容应该是多少?
4.假设地址为1200H的内存单元中的内容为12FCH,地址为12FCH的内存单元的内容为38B8H,而
38B8H单元的内容为88F9H。说明以下各情况下操作数的有效地址是多少?
(1)操作数采用变址寻址,变址寄存器的内容为252,指令中给出的形式地址为1200H。
(2)操作数采用一次间接寻址,指令中给出的地址码为1200H。
(3)操作数采用寄存器间接寻址,指令中给出的寄存器编号为8,8号寄存器的内容为1200H。
5.通过查资料了解Intel 80x86 微处理器和 MIPS处理器中各自提供了哪些加法指令,说明每条加法
指令的汇编形式、指令格式和功能,并比较加、减运算指令在这两种指令系统中不同的设计方式,包括不同
的溢出处理方式。
6.某计算机指令系统采用定长指令字格式,指令字长16位,每个操作数的地址码长6位。指令分二
地址、单地址和零地址3类。若二地址指令有k2条,零地址指令有k0条,则单地址指令最多有多少条?
7.某计算机字长16位,每次存储器访问宽度16位,CPU中有8个16位通用寄存器。现为该机设计
指令系统,要求指令长度为字长的整数倍,至多支持64种不同操作,每个操作数都支持4种寻址方式:立
即(1)、寄存器直接(R)、寄存器间接(S)和变址(X),存储器地址位数和立即数均为16位,任何一个通用寄
存器都可作变址寄存器,支持以下7种二地址指令格式:RR型、RI型、RS型、RX型、XI型、SI型、SS型。
请设计该指令系统的7种指令格式,给出每种格式的指令长度、各字段所占位数和含义,并说明每种格式
指令需要几次存储器访问。
8.某计算机字长为16位,主存地址空间大小为128KB,按字编址。采用单字长定长指令格式,指令各
字段定义如下:
15
1211
65
0
OP
Ms
Rs
Md
Rd
源操作数
目的操作数
转移指令采用相对寻址方式,相对位移量用补码表示,寻址方式定义如下表所示。
Ms/Md
寻址 方式
助记符
含 义
000B
寄存器直接
Rn
操作数=R[Rn]
001B
寄存器间接
(Rn)
操作数=M[R[Rn]]
010B
寄存器间接、自增
(Rn)+
操作数=M[R[Rn]],R[Rn]-R[Rn]+1
011B
相对
D(Rn)
转移目标地址=PC+R[Rn]
注:M[x]表示存储器地址x中的内容,R[x]表示寄存器x中的内容。
请回答下列问题:
(1)该指令系统最多可有多少条指令?最多有多少个通用寄存器?存储器地址寄存器(MAR)和存储
器数据寄存器(MDR)至少各需要多少位?
(2)转移指令的目标地址范围是多少?
(3)若操作码0010B表示加法操作(助记符为add),寄存器 R4和R5的编号分别为100B和101B,R4
的内容为1234H,R5的内容为5678H,地址1234H中的内容为5678H,地址5678H中的内容为1234H,则
汇编语句“add(R4),(R5)+”(逗号前为第一源操作数,逗号后为第二源操作数和目的操作数)对应的机器
第4章
125
<!-- page: 143 -->
计算机组成与系统结构(第3版)
126
码是什么(用十六进制表示)?该指令执行后,哪些寄存器和存储单元的内容会改变?改变后的内容是
什么?
9.有些计算机提供了专门的指令,能从一个32位寄存器中抽取其中任意一个位串置于另一个寄存器
的低位有效位上,并在高位补0,如下图所示。MIPS指令系统中没有这样的指令,请写出最短的一个
MIPS指令序列来实现这个功能,要求i=5,j=22,操作前后的寄存器分别为$s0和$s2。
31
J
i
0
31一位
j一位
i+1位
31
0
0
⋯
000
32-(j-i)位
j一位
10.以下程序段是某个过程对应的指令序列。入口参数int a和intb分别置于$a0和$al中,返回参
数是该过程的结果,置于$v0中。要求为以下MIPS指令序列加注释,并简单说明该过程的功能。
add
St0, $zero, 5zero
1oop:
beq
Sal, Szero, finish
S+0.St0,Sad
add
sub
Sal,Sal, 1
j
1oop
finish:addi
5t0, st0,100
add
5v0,st0,szero
11.下列指令序列用来对两个数组进行处理,并产生结果存放在$v0中,两个数组的基地址分别存放
在$aO和$al中,数组长度分别存放在$a2和$a3中。要求为以下 MIPS指令序列加注释,并简单说明
该过程的功能。假定每个数组有2500个字,其数组下标为0~2499,该指令序列运行在一个时钟频率为
2GHz的处理器上,add、addi和sll指令的CPI为1;lw和bne指令的CPI为2,则最坏情况下运行所需时间
是多少秒?
s11
s1l
add
add
outer:add
lw
add
inner;add
lw
bne
addi
skip:
addi
bne
addi
bne
Sa2, sa2, 2
$a3, 5a3, 2
$v0,$zero,szero
$t0, szero, szero
$t4,5a0, sto
5+4.0(St4)
$t1, S zero,szero
$t3,Sa1,st1
st3, 0($t3)
St3.St4,skip
Sy0,Sv0,1
$t1, $t1,4
5t1, $a3, inner
$t0,$t0,4
5t0, $a2, outer
12.用一条MIPS指令或最短的 MIPS指令序列实现以下C语言语句:b=25la。假定编译器将a和b
分别分配到$t0和$t1中。如果把25换成65536,即b=65536|a,则用MIPS指令或指令序列如何实现?
13.以下程序段是某个过程对应的MIPS指令序列,其功能为复制一个存储块数据到另一个存储块
中,存储块中每个数据的类型为float,源数据块和目的数据块的首地址分别存放在$a0和$al中,复制的
数据个数存放在$v0中,作为返回参数返回给调用过程。假定在复制过程中遇到0就停止复制,最后一个
<!-- page: 144 -->
指令系统
0也需要复制,但不被计数。已知程序段中有多个错误,请找出它们并修改之。
loop:
addi
1w
sw
addi
addi
beq
$v0, s zero,0
Syl,0(sad)
$v1,0(Sa1)
Sa0, Sa0,4
Sa1, Sa1,4
$v1,5zero, loop
14.说明beq指令的含义,并解释为什么汇编程序在对下列汇编源程序中的beq指令进行汇编时会遇
到问题,应该如何修改该程序段?
here: beq⋯
there: addi
ss0, 5s2, there
5s1,5s0,4
15.以下C语言程序段中有两个函数 sum_array和 compare,假定sum_array 函数先被调用,全局变量
sum分配在寄存器$sO中。要求按照MIPS过程调用协议写出每个函数对应的MIPS汇编语言程序,并
画出每个函数调用前、后栈中的状态、帧指针和栈指针的位置。
int sum=0;
int sum_array(int array[], int num)
int i;
for(1=0; i<num;1++)
if compare(num,1+1)sum+=array[1];
return sum;
int compare(int a, int b)
(
if(a>b)
return 1;
else
return 0;
1
16.以下是一个计算阶乘的C语言递归过程,请按照 MIPS 过程调用协议写出该递归过程对应的
MIPS 汇编语言程序,要求目标代码尽量短(提示:乘法运算可用乘法指令“mul rd,rs,rt”来实现,功能为
rd*-(rs)×(rt))。
int fact (int n)
if(n<1)
}
return(1);
else
return(n*fact(n-1));
17.假定编译器将a和b分别分配到t0和tl中,用一条RV321指令或最短的 RV321指令序列实现以
下C语言语句:b=31&a。如果把31换成65535,即b=65535&a,则用RV32I指令或指令序列如何实现?
对比第 12题 RV32I与 MIPS之间在立即数处理上有何不同?
18.某C语言源程序中的一个 while语句为“while(save[i]==k)i+=1;”,若对其编译时,编译器将
i和k分别分配在寄存器s3和s5中,数组save的基址存放在s6中,则生成的RV321汇编代码段如下。
第4章
127
<!-- page: 145 -->
计算机组成与系统结构(第3版)
128
1ooP
exit:
s113
t1,s3,2
#R[t1]-R[s3]<<2,即R[t1]=i×4
add
t1,t1,s6
#R[t1]*-R[t1]+R[s6],即 R[t1]-address of save[i]
1w
t0,0(t1)
#R[tO]*-M[R[t1]+0],即R[t0]=save[i]
bne
t0,s5,exit
#1f R[tO]≠R[s5]=k then goto exit
addi
s3,s3,1
#R[s3]-R[s3]+1,即i=i+1
1oop
#goto 1oop
J
假设从loop处开始的指令存放在内存40000处,上述循环对应的RV321机器码如下图所示。
7位
5位
5位
3位
5位
7位
40000
0
2
19
1
6
19
40004
0
22
6
0
6
51
40008
0
6
2
5
3
40012
0
21
5
1
12
99
40016
1
19
0
19
19
40020
1043967
0
111
40024
根据上述叙述,回答下列问题,要求说明理由或给出计算过程。
(1)RISC-V的编址单位是多少?数组 save每个元素占多少字节?
(2)为什么指令“slli t1,s3,2”能实现4×i的功能?
(3)该指令序列中,哪些指令是R-型?哪些是1-型?哪些是B型?哪些是 J-型?
(4)10和s6的编号各为多少?
(5)指令jloop是哪条指令的伪指令?其操作码的二进位表示是什么?
(6)标号 exit 的值是多少?如何根据40012处的指令计算得到?
(7)标号loop的值是多少?如何根据40020处的指令计算得到?
提示:1043 967=1024×1024-1-512-4096。