这个教程是PLCT推出的,强烈推荐。在这篇文章中,我们就简单记录下这个学习重点。
这里是课程的github
01
计算机硬件组成: 自己画出来。
02 指令集
基本介绍: ISA是底层电路向上提供编程接口的一套规范; 指定规则和规范,让上层用户忽略下层电路的具体实现。IBM 360是第一个提供ISA的。
CISC:
RISC:
ISA的宽度:
ISA riscv 命名规范:
HART: Hardware Thread: 硬件线程。一个hart是虚拟的cpu,单独的thread. 资源的概念与cpu的功能类似。
特权级别: 三个级别: U(user) S(supervisor) M(Machine) 不同级别特权级别下分别对应各自一套的CSR。高级别的特权可以访问低级别的特权指令。
内存保护: 物理内存保护模式 PMP(physical Memory Protection)
异常(exception): 如不可访问的内存。调到特殊的地址来对异常进行处理;处理完之后会继续回到造成异常的指令地址。
中断:中断执行完成后,回到下一条地址。(外设,让你感觉没有发生一样)。
02 编译与连接
03 汇编
label: 冒号开始, 也是地址。
指令: 原指令。
伪指令:
directive: .xx
的形式。只有在汇编器里看到这个概念。
macro: 采用 .macro
和 .endm
自定义的宏。
04 总览-编码格式
要熟悉 域 的格式。 opcode不能唯一决定指令的类型。需要会看表。
主机字节序: Host Byte Order (HBO)
HEX: 0x11 22 33 44. Big-Endian: 低地址保存高位(0x11)
R: 三个field是, 每个5 bits。
I: Immediate: 12 bits.
B:
U:
J:
05
算法运算指令
add: add
addi: addi rd, rs1, imm[31:20]
衍生的伪指令: neg rd,rs; == sub rd, 0, rs.
mv rd, rs; == addi rd, rs, 0
nop == addi x0, x0, 0
addi局限性: 一个寄存器的数值范围只有 [-2048, 2047),如果是大数的话(32位的话),需要自己构造一个: 先使用命令设置高20位,存放在rs1,然后复用现有addi命令补上剩余的低12位。
lui (Load Upper Immediate): imm[31:12] ==> 高20位, rd[11:7], opcode[6:0] lui x5, 0x12345 (x5 = 0x12345 « 12).
练习: 利用LUI+ADDi来加载0x12345678.
# 1
lui x1, 0x12345 # x1 = 0x12345000
addi x1, x1, 0x678
# 2 加载0x12345fff
lui x1, 0x12346 # x1 = 0x12346000
addi x1, x1, -1 # x1 = 0x12345fff(?)
li: li x5, 0x12345678
auipc: auipc x5, 0x12345 (x5=0x12345 « 12 + pc)
la:
逻辑运算指令
and
or
xor
andi
ori
xori
移位运算指令
逻辑左移和右移都会自动补0.
算术右移是根据符号位决定的。(没有左移)
内存读写指令
load: 内存读指令, 将数据从内存读入寄存器。
store: 内存写指令, 将数据从内存写入寄存器。
LB:
LBU:
LH:
LHU:
LW:
SB:
SH:
SW.