复习
Lui指令
Lui a5,0x200====>Lui a5,0x00200,补成20位。然后再向左移动三位形成0x00200000,然后加载到a5寄存器中。
Lui a5,0x200表示将0x200
这个值加载到a5
寄存器的高20位中。但0x200
只是一个12位的数值。为了将其展开为20位的形式,我们需要在它的前面补足相应数量的零。
立即数表示形式
imm(8):一个立即数
im[1:10]:一段立即数
编码的思想
假设你有四个可能的值:6、12、16和20。为了表示这四个值,只需要两位二进制,即
00
、01
、10
和11
。当你传输或存储这两位的时候,接收方解码这两位以得到原始的值。
例如:
00
-> 601
-> 1210
-> 1611
-> 20
编码除二,解码乘二
这个策略是基于一个观察:如果所有地址都是偶数,那么最低有效位(LSB)总是0。
最低有效位 (LSB)
最低有效位是一个二进制数的最右边的位。例如,在二进制数
101010
中,最右边的位(即0
)就是最低有效位。
为什么地址都是偶数最低有效位都是零?
当我们说一个数字是2的倍数(即偶数),这意味着它可以被2整除。在二进制表示中,能够被2整除的数字的最低有效位总是
0
。这是因为在二进制系统中,每一位代表的是2的一个幂次。如果最低有效位是1
,就说明一定有1,其他的都是2,4,8,16……,那么数字之和就一定是奇数;如果最低有效位是0
,那么数字就是偶数。
因此,我们可以在存储或传输时忽略这个位,从而节省一位。编码时除以2实际上是移除最低位(因为它总是0),而解码时乘以2则是恢复这个位。
例如:
- 地址:8 -> 编码:4
- 地址:10 -> 编码:5
- 地址:12 -> 编码:6
- ...以此类推
当接收方收到编码值时,它会乘以2来得到原始的地址。
这种方法的缺点是,它只在所有地址都是偶数的情况下有效。如果存在奇数地址,这种策略就不能使用。
RISC-V(和许多其他的处理器体系结构)的指令地址都是偶数。这主要是因为RISC-V的最小指令长度是16位,也就是2字节,因此指令的起始地址总是2的倍数。这确保了指令对齐于它们的自然长度边界,这在硬件中可以提高访问速度和效率。
伪指令
1. 伪指令的定义
伪指令并不是硬件真正执行的指令,而是为了简化汇编语言编程而提供的。这些指令在汇编过程中会被转换成一个或多个真实的硬件指令。伪指令通常用于简化编程,使程序员不必记住每一个具体的硬件指令。
2. li
伪指令
li
是一个常用的伪指令,表示“load immediate”。其作用是将一个立即数值加载到寄存器中。在RISC-V中,li
可能会被编译成addi rd, r0, imm
,其中r0
是一个始终为0的寄存器,imm
是需要加载的立即数。
如果
imm
的值大于可以由一个addi
指令表示的范围(例如,超过5位),那么需要使用lui
和addi
联合来表示,不能再用li表示了,因为li命令不能直接加载一个超过12位的立即数到寄存器,因为addi
指令的立即数字段是12位。在这种情况下,lui
负责加载高位,而addi
则负责加载低位。
3. RISC的设计理念
RISC(精简指令集计算)的核心思想是使用更小、更快速、更简单的指令,这样可以更高效地使用硬件资源。通过组合简单指令,执行复杂指令。与CISC(复杂指令集计算)相比,RISC重视硬件的简化和指令的执行速度。
例如,mv rd,rs
伪指令实际上是add rd,rs,r0
的简化形式,因为它仅仅是将rs
寄存器的值移动(或复制)到rd
寄存器,没有其他操作。
4. nop
指令
nop
是“no operation”的缩写,表示没有任何操作的指令。在RISC-V中,nop
实际上是addi r0,r0,0
的简写,即对0号寄存器执行加0的操作,这显然没有任何效果。但它仍然使程序计数器(PC)自增,使指令流程继续前进。
nop
指令常用于延迟、代码填充或其他需要空操作的场合。
ILM
作者看连接脚本时,发现除了ROM和RAM的地址声明,脚本中还声明了一段地址:
/*--------------------- ILM RAM Configuration ---------------------------
* <h> ILM RAM Configuration
* <o0> ILM RAM Base Address <0x0-0xFFFFFFFF:8>
* <o1> ILM RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__ILM_RAM_BASE = 0x80000000;
__ILM_RAM_SIZE = 0x00010000;
/*--------------------- Embedded RAM Configuration ---------------------------
* <h> RAM Configuration
* <o0> RAM Base Address <0x0-0xFFFFFFFF:8>
* <o1> RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__RAM_BASE = 0x20000000;
__RAM_SIZE = 0x00005000;
这个ILM_RAM是什么东西?于是作者进行查询:
ILM 通常指的是 Instruction Local Memory,而 RAM 一般指的是 Random Access Memory。这里的 ILM 和 RAM 的配置似乎是为某个嵌入式系统或特定的硬件平台设置的。在某些嵌入式系统或处理器设计中,ILM 是为了提供一个更快速的,专门用于存放指令的存储区域,以优化代码的执行性能。
让我们深入了解一下这两者:
- ILM (Instruction Local Memory):
- 专门用于存储和快速访问程序指令。
- 通常位于与处理器核心更接近的位置,以减少取指时延。
- 可能是一个专门的、速度很快的存储区,设计用于存放热点代码或经常执行的代码片段。
- RAM (Random Access Memory):
- 用于存储程序的数据,包括变量、数组、堆栈等。
- 是一个更通用的存储空间。
- 根据具体的设计和应用,其速度可能会慢一些,或者与ILM相近。
从代码片段来看,这两种内存都有基址(Base Address)和大小(Size)。这是为了在系统中为它们分配物理空间。例如,ILM 的基址被设置为 0x80000000
,大小为 0x00010000
(或64KB),而 RAM 的基址是 0x20000000
,大小为 0x00005000
(或20KB)。
具体的区别和用途会取决于特定的硬件设计和应用需求。在某些场景中,ILM 可能是非常有用的,因为它可以帮助提高程序的执行速度,特别是在实时应用或性能要求高的应用中。