加载和存储:寻址方式
MIPS 只有一种寻址方式。任何加载或存储机器指令可以写成
lw $1, offset($2)
你可以使用任何寄存器来作为目标和源寄存器。offset 偏移量是一个有符号的16 位的数字(因此可以是在-32768 与32767 之间的任何一值)。用来加载的程序地址是源寄存器与偏移量的和所构成的地址。这种寻址方式一般已足够存取一个C 语言的结构(偏移量是这个结构的起始地址到所要存取的结构成员之间的距离)。这种寻址方式实现了一个通过一个常量来索引的数组;并足够使得可以存取堆栈上的函数变量或桢指针;可以提供一个比较合适大小的以gp 为基址的全局空间以存取静态和外部数据。
汇编器提供一个简单直接存取方式的汇编格式从而可以加载一个在连接时刻才能决定地址的变量的值。
相对GP的寄存器的寻址
基本地址空间:
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 寄存器。如果你的硬件工程师要把这段地址空间映射到非低段512M 空间,你得劝说他。
kseg2: 0xC000 0000 - 0xFFFF FFFF (1G): 这段地址空间只能在核心态下使用并且要经过MMU 的转换。在MMU 设置好之前,不能存取这段区域。除非你在写一个真正的操作系统,一般来说你不需要使用这段地址空间。
要注意的是64 位内存映象是包含在32 位内存映象里面的。这是个有点奇怪的方法。当模拟一个32 位指令集时,寄存器存放的是其32 位的带符合位扩展的64 位值。因此,一个32 位程序存取的是64 位程序空间的最低和最高的2G。换句话说,64 位CPU 的地址空间的最低和最高区域是和32 位情况下一样的,64 位扩展的地址部分在这两者之间。
阅读(1189) | 评论(0) | 转发(0) |