对于软件开发人员来说,一个CPU最重要的部分就是寄存器、内存布局和指令。龙芯2E
逻辑上是有
32
个定点通用寄存器
(
其中
0
号固定为
0)
,
32
个浮点寄存器,一个
hi
,一个
lo
,以及若干
cp0
控制寄存器,两个
cp1
控制寄存器。物理上是
64
个定点,
64
个浮点,和若干控制寄存器。
龙芯2E具有下面的逻辑寄存器:
l
32
个通用的64位寄存器
l
1
个PC寄存器
l
2
个保存乘除操作结果寄存器
l
32
个浮点64位寄存器
l
32
个CP0控制寄存器
l
2
个
cp1
控制寄存器
一、32个通用的64位寄存器
这32个通用寄存器,可以用作任何使用。但实际上由于编译器已经约定特定的使用,所以还是要服从特定的约定,这样可以减少麻烦,减少开发出错机会。特定使用如下:
l
$0 zero
值总是为
0
,可能主要用途是清空内存地址空间,以及做一些与或非的操作,访问速度快。
l
$1 $AT
是为编译器保留的寄存器
l
$2..$3 V0..V1
保存函数返回值用
l
$4..$11 A0..A7
函数调用时传递参数,可以传递
8
个整型参数
l
$12..$15 T0..T3
临时寄存器,用于保存临时变量的值,也是用的最多的寄存器
l
$16..$23 S0-S7
他们的值在过程调用的时候保持不变,可以用于传递参数或者返回值
l
$24..$25 T8..T9
临时寄存器,用于保存临时变量的值,也是用的最多的寄存器
l
$26..$27 K0..K1
保留给操作系统内核使用
l
$28 GP
保存全局指针
l
$29 SP
保存堆栈指针
l
$30 FP
或
S8
保存帧指针,也可以和
S0..S7
一样使用
l
$31 RA
保存返回地址
二、
专用寄存器
HI
和
LO
主要返回乘除结果,
PC
是指令计数器。
三、内存布局
在
32
位下,程序地址空间划分为
4
个大区域。每个区域有一个传统的名字。对于在这
些区域的地址,各自有不同的属性:
kuseg: 0x000 0000 - 0x7FFF FFFF (
低端
2G
)
:这些地址是用户态可用的地址。在
有
MMU
的机器里,这些地址将一概被
MMU
作转换。除非
MMU
的设置被建立好,这
2G
地址是不可用的。
对于没有
MMU
的机器,存取这
2G
地址的后依具体机器相关。你的
CPU
具体厂商提供的
手册将会告诉你关于这方面的信息。如果想要你的代码在有或没有
MMU
的
MIPS
处理器
之间有兼容性,尽量避免这块区域的存取。
kseg0: 0x8000 0000 - 0x9FFF FFFF(512M):
这些地址映射到物理地址简单的通过
把最高位清零,然后把它们映射到物理地址低段
512M
(0x0000 0000 - 0x1FFF FFFF)
。
因为这种映射是很简单的,通常称之为
“
非转换的
“
地址区域。
几乎全部的对这段地址的存取都会通过快速缓存
(cache)
。因此在
cache
设置好之前,不能随便使用这段地址。通常一个没有
MMU
的系统会使用这段地址作为其绝大多数程
序和数据的存放位置。对于有
MMU
的系统,操作系统核心会存放在这个区域。
kseg1: 0xA000 0000 - 0xBFFF FFFF(512M):
这些地址通过把最高
3
位清零的方法来
映射到相应的物理地址上,与
kseg0
映射的物理地址一样。但
kseg1
是非
cache
存取的。
kseg1
是唯一的在系统重启时能正常工作的地址空间。这也是为什么重新启动时的入口向量是
0xBFC0 0000
。这个向量相应的物理地址是
0x1FC0 0000
。
将使用这段地址空间去存取你的初始化
ROM
。大多数人在这段空间使用
I/O
寄存器。
kseg2: 0xC000 0000 - 0xFFFF FFFF (1G):
这段地址空间只能在核心态下使用并且要经过
MMU
的转换。在
MMU
设置好之前,不能存取这段区域。除非你在写一个真正的操作系统,一般来说你不需要使用这段地址空间。