Appearance
题目
对于题 43 中的计算机 M,C 语言程序 P 包含的语句 sum+=a[i];,在 M 中对应的指令序列 S 如下:
slli r4, r2, 2 // R[r4] <- R[r2]<<2
add r4, r3, r4 // R[r4] <- R[r3]+R[r4]
lw r5, 0(r4) // R[r5] <- M[R[r4]+0]
add r1, r1, r5 // R[r1] <- R[r1]+R[r5]已知变量 i,sum 和数组 a 都为 int 型,通用寄存器 r1 - r5 的编号为 01H-05H。请回答下列问题。
(1)根据指令序列 s 中每条指令的功能,写出存放数组 a 的首地址、变量 i 和 sum 的通用寄存器编号(3 分)
(2)已知 M 为小端方式,计算机采用页式存储管理方式。页大小为 4KB。若执行到指令序列 s 中第 1 条指令时,i=5 且 r1 和 r3 的内容分别为 0000 1332H 和 0013 DFF0H。从地址 0013 DFF0H 开始存储单元内容如题 44 图所示。则执行 sum+=a[i]; 语句后。a[i] 的地址、a[i] 和 sum 的机器数分别是什么(用十六进制表示)?a[i] 所在页的页号是多少?在此次执行中,数组 a 至少存放在几页中?(5 分)

(3)指令 slli r4, r2, 2 的机器码是什么(用十六进制表示)?若数组 a 改为 short 类型,则指令序列存到 S 中 slli 指令的汇编形式应是什么?
解析
本题在 2024-43 的 RISC-V 指令集上执行 sum += a[i] 的指令序列,考查 从汇编反推寄存器分配、小端字节序读数、页号判定、slli 机器码生成 4 件事。
阅读思路:先把每条指令对应到 C 语义,反推每个寄存器装的"角色";然后做地址计算和数据读出。
(1) a 首地址 / i / sum 各在哪个寄存器 [3 分]
逐条匹配指令与 C 语义:
| 指令 | 含义 | 推断 |
|---|---|---|
slli r4, r2, 2 | r4 = r2 << 2 = r2 × 4 | 对应 i*4(int = 4B 步长)→ r2 = i |
add r4, r3, r4 | r4 = r3 + r4 = a + i*4 | 计算 &a[i] → r3 = a 的首地址 |
lw r5, 0(r4) | r5 = M[r4 + 0] | 读 a[i] 到 r5 |
add r1, r1, r5 | r1 = r1 + r5 = sum + a[i] | 累加 → r1 = sum |
| 角色 | 寄存器 | 编号 |
|---|---|---|
| 数组 a 首地址 | r3 | 03H |
| 变量 i | r2 | 02H |
| 变量 sum | r1 | 01H |
(2) a[i] 地址 / a[i] / sum / 所在页号 / 数组跨页数 [5 分]
Step 1. 算 a[i] 地址。
题给 r3 = a 的首地址 = 0013 DFF0H,i = 5:
Step 2. 按小端方式读 a[i]。
题图给出从 0013 DFF0H 起的内存内容。a[i] 占 4 字节,从 0013E004H 到 0013E007H。按图读出该 4 字节序列(低地址 → 高地址)= DC EC FF FF。
小端方式下,低字节存于低地址,所以 32 位整数 = 高字节 / 中高 / 中低 / 低字节 = FF FF EC DC:
按补码读为 −4900。
Step 3. 算 sum。
题给执行前 r1(即 sum)= 0000 1332H。执行 sum += a[i]:
0000 1332H
+ FFFF ECDCH
------------
1 0000 000EH (33 位)按 32 位截断 → 丢弃最高位的 1:
实际意义:原 sum = 0x1332 = 4914,加上 −4900 = 14 = 0x0E。✓
Step 4. a[i] 所在页号。
页大小 4KB → 页号 = 高 20 位(虚拟地址前 20 位):
Step 5. 数组跨几页。
数组首地址 0013 DFF0H 落在页 0013DH,末地址(数组占 8KB? 题目未明说,但 a[5] 已跨页)落在页 0013EH。
判定:a[0] 在页 0013D (0013 DFF0H 的高 20 位),而 a[5] 在页 0013E。所以数组 至少跨 2 页。
易错点(小端读法): 题图给的字节顺序是 内存物理顺序(低地址 → 高地址),不是数值的可读形式。要想得出 32 位数值,必须从最高地址(最高字节)开始往低地址(最低字节)"反着拼"。本题 4 字节序列
DC EC FF FF反过来读得FFFFECDC。
(3) slli r4, r2, 2 的机器码 + short 类型时的汇编 [3 分]
机器码生成。 按 slli 的 I 型字段([31:25] funct7 | [24:20] shamt | [19:15] rs1 | [14:12] funct3 | [11:7] rd | [6:0] opcode):
| 字段 | 二进制 | 来源 |
|---|---|---|
| funct7 [31:25] | 0000000 | slli 固定 |
| shamt [24:20] | 00010 | 移 2 位 |
| rs1 [19:15] | 00010 | r2 = 2 |
| funct3 [14:12] | 001 | slli 固定 |
| rd [11:7] | 00100 | r4 = 4 |
| opcode [6:0] | 0010011 | I 型固定 |
拼接:0000 0000 0010 0001 0010 0010 0001 0011B → 分组:
short 类型的汇编。
short 占 2 字节 = B → 索引乘 2 而非 4 → 左移 1 位:
编者注(生僻术语): "数组下标 ↔ 字节地址" 的换算是数据类型决定的。int = 4B → 左移 2;short = 2B → 左移 1;double = 8B → 左移 3;char = 1B → 不需要移。这种"sizeof 决定 shift 量"是编译器生成代码的常见模式。