CS61C Lecture08: RISC-V lw, sw, Decision 1¶
约 724 个字 23 行代码 预计阅读时间 4 分钟 共被读过 次
一、RISC-V 内存操作指令¶
1. 寄存器与内存特性¶
- 32个寄存器(x0-x31)速度比内存快约50倍
- 特殊用途寄存器:
- x0 (zero): 恒为0
- sp (x2): 栈指针
- ra (x1): 返回地址
- a0-a7 (x10-x17): 函数参数/返回值
- s0-s11 (x8-x9, x18-x27): 保存寄存器
- t0-t6 (x5-x7, x28-x31): 临时寄存器
2. 内存访问指令¶
指令 | 格式 | 功能 | 特点 |
---|---|---|---|
lw | lw rd, offset(rs1) | 从内存加载32位字 | 偏移量必须是4的倍数 |
sw | sw rs2, offset(rs1) | 存储32位字到内存 | 数据流向:寄存器 → 内存 |
lb | lb rd, offset(rs1) | 加载字节(符号扩展) | 用于char类型处理 |
lbu | lbu rd, offset(rs1) | 加载字节(零扩展) | 处理无符号字符 |
sb | sb rs2, offset(rs1) | 存储字节 | 仅存储低8位 |
内存对齐原则:
- 32位字必须位于4字节对齐地址
- 示例:int数组访问时,地址偏移量总是4的倍数(假设int为4字节)
二、立即数操作¶
1. addi 指令¶
- 立即数范围:12位有符号数(-2048 ~ 2047)
- 扩展机制:符号扩展到32位
2. 大立即数处理¶
- 使用lui(Load Upper Immediate)指令加载高20位:
三、条件分支指令¶
1. 基础分支指令¶
指令 | 功能 | 伪代码表示 |
---|---|---|
beq | 相等时跳转 | if (rs1 == rs2) PC += offset |
bne | 不等时跳转 | if (rs1 != rs2) PC += offset |
blt | 有符号小于时跳转 | if (rs1 < rs2) PC += offset |
bltu | 无符号小于时跳转 | if (rs1 < rs2) PC += offset |
bge | 有符号大于等于时跳转 | if (rs1 >= rs2) PC += offset |
2. 分支指令特点¶
- 地址范围限制:±4KB范围(12位立即数 × 4字节)
- 延迟槽:RISC-V无延迟槽,直接顺序执行
3. 条件判断模式¶
if-else结构示例:
四、内存层次结构与优化¶
1. 存储技术对比¶
类型 | 速度 | 容量 | 用途 |
---|---|---|---|
SRAM | 最快 | 最小 | CPU缓存 |
DDR SDRAM | 中等 | 大 | 主内存 |
HBM | 较高 | 较大 | GPU/高性能计算 |
2. 局部性原理¶
- 时间局部性:最近访问的数据可能再次被访问
- 空间局部性:相邻内存位置可能被访问
- 编程实践:优化数据访问模式(如行优先遍历数组)
五、编译器优化策略¶
1. 寄存器分配优化¶
- 优先使用临时寄存器(t0-t6)
- 减少保存寄存器(s0-s11)的溢出操作
- 循环展开减少分支指令
2. 典型优化案例¶
C
// 原始代码
for (int i=0; i<100; i++) {
sum += array[i];
}
// 优化后汇编可能使用:
// 1. 指针算术替代数组索引
// 2. 循环展开4次减少分支判断
// 3. 寄存器保留sum避免内存访问
六、重点概念对比¶
概念 | 有符号处理 | 无符号处理 |
---|---|---|
加载字节 | lb(符号扩展) | lbu(零扩展) |
比较指令 | blt/bge | bltu/bgeu |
溢出处理 | 补码运算 | 模运算 |
七、常见问题解析¶
-
为什么偏移量要是4的倍数?
- RISC-V采用32位字长,4字节对齐提高访问效率
- 非对齐访问需要多次内存操作 -
如何处理超过12位的立即数?
- 使用lui加载高20位
- 配合addi/add处理低12位
- 示例:加载0x12345678 → lui + addi -
如何实现switch语句?
- 使用跳转表(Jump Table)
- 通过slli计算偏移量