1、原因
发现串口初始化了,但是debug的时候串口外设寄存器值都是0

2、RISC-V汇编指令解释
指令含义
加载 / 存储指令
指令 | 功能描述 |
---|---|
lw (Load Word) | 从内存加载一个字 (32 位) 到寄存器 |
lb (Load Byte) | 从内存加载一个字节 (8 位) 到寄存器,符号扩展 |
lbu (Load Byte Unsigned) | 从内存加载一个无符号字节到寄存器 |
lh (Load Half) | 从内存加载一个半字 (16 位) 到寄存器,符号扩展 |
lhu (Load Half Unsigned) | 从内存加载一个无符号半字到寄存器 |
sw (Store Word) | 将寄存器中的字 (32 位) 存储到内存 |
sb (Store Byte) | 将寄存器中的字节 (8 位) 存储到内存 |
sh (Store Half) | 将寄存器中的半字 (16 位) 存储到内存 |
算术指令
指令 | 功能描述 |
---|---|
add | 两个寄存器相加 |
addi | 寄存器与立即数相加 |
sub | 两个寄存器相减 |
mul | 两个寄存器相乘 |
div | 两个寄存器相除 |
逻辑指令
指令 | 功能描述 |
---|---|
and | 两个寄存器按位与 |
andi | 寄存器与立即数按位与 |
or | 两个寄存器按位或 |
ori | 寄存器与立即数按位或 |
xor | 两个寄存器按位异或 |
xori | 寄存器与立即数按位异或 |
sll | 逻辑左移 |
srl | 逻辑右移 |
sra | 算术右移 |
分支 / 跳转指令
指令 | 功能描述 |
---|---|
beq | 相等时分支 |
bne | 不相等时分支 |
blt | 小于时分支 |
bge | 大于等于时分支 |
bltu | 无符号小于时分支 |
bgeu | 无符号大于等于时分支 |
jal | 跳转并链接 (保存返回地址) |
jalr | 寄存器跳转并链接 |
其他常用指令
指令 | 功能描述 |
---|---|
lui (Load Upper Immediate) | 加载立即数到寄存器高位 |
auipc (Add Upper Immediate to PC) | 将立即数加到 PC 上 |
li (Load Immediate) | 伪指令,加载立即数到寄存器 |
mv (Move) | 伪指令,寄存器间移动 |
nop (No Operation) | 无操作 |
ret | 函数返回,实际是 jalr x0, 0 (x1) 的伪指令 |
系统指令
指令 | 功能描述 |
---|---|
ecall | 环境调用 |
ebreak | 环境断点 |
fence | 内存和 I/O 同步屏障 |
csrr | 读控制状态寄存器 |
csrw | 写控制状态寄存器 |
3、实际代码解释
0x0000023a lui a5,0x40014 # 加载0x40014到a5高位,形成0x40014000
0x0000023e lhu a4,-2040(a5) # 从地址0x40013808(0x40014000-0x7F8)读取半字到a4
0x00000242 lui a2,0x4 # 加载0x4到a2高位,形成0x4000(未使用)
0x00000244 lui a0,0x2 # 加载0x2到a0高位,形成0x2000(未使用)
0x00000246 ori a4,a4,15 # a4 = a4 | 0xF,执行按位或操作
0x0000024a sh a4,-2040(a5) # 将修改后的a4写回地址0x40013808
寄存器说明
- a0 - a7:在 RISC - V 架构里,这些属于参数寄存器(argument registers),主要在函数调用时用于传递参数。
- a4、a5:在这段代码中当作临时寄存器使用,用于存储计算过程中的中间结果。
- a2:此寄存器被加载了数值,但在这段代码里并未使用,推测可能是编译器生成的冗余代码。
地址和指令解释
0x0000023a lui a5,0x40014
- 指令地址:0x0000023a 为该指令在程序中的地址,也就是程序计数器的值。
- 指令操作:"lui a5,0x40014" 指令会把立即数 0x40014 加载到 a5 寄存器的高 20 位,同时将低 12 位清零。
- 操作结果:a5 寄存器的值变为 0x40014000。
0x0000023e lhu a4,-2040(a5)
- 指令地址:0x0000023e 是该指令的地址。
- 指令操作:"lhu a4,-2040 (a5)" 指令会从地址 (a5 - 2040) 处加载一个无符号半字(16 位)到 a4 寄存器。
- 地址计算:经过计算,0x40014000 - 0x7F8 = 0x40013808,这个地址对应的是 USART1->BRR。
- 操作结果:a4 寄存器的值为内存地址 0x40013808 处的 16 位值。
0x00000242 lui a2,0x4
- 指令地址:0x00000242 是该指令的地址。
- 指令操作:"lui a2,0x4" 指令会把 0x4 加载到 a2 寄存器的高 20 位。
- 操作结果:a2 寄存器的值变为 0x4000,不过在这段代码中该值未被使用。
0x00000244 lui a0,0x2
- 指令地址:0x00000244 是该指令的地址。
- 指令操作:"lui a0,0x2" 指令会把 0x2 加载到 a0 寄存器的高 20 位。
- 操作结果:a0 寄存器的值变为 0x2000,在这段代码中此值未被使用。
0x00000246 ori a4,a4,15
- 指令地址:0x00000246 是该指令的地址。
- 指令操作:"ori a4,a4,15" 指令会将 a4 寄存器的值与立即数 15(即 0xF)进行按位或操作。
- 操作结果:a4 寄存器的值更新为 a4 | 0xF,也就是将 a4 寄存器的低 4 位设置为 1。
0x0000024a sh a4,-2040(a5)
- 指令地址:0x0000024a 是该指令的地址。
- 指令操作:"sh a4,-2040 (a5)" 指令会把 a4 寄存器中的半字(16 位)存储到地址 (a5 - 2040) 处。
- 地址计算:同样,0x40014000 - 0x7F8 = 0x40013808。
- 操作结果:内存地址 0x40013808 处的值被更新为 a4 寄存器的值,即将修改后的值写回到 USART1->BRR。