RISC gp寄存器


首先说说gp寄存器出现的原因吧,由于RISC体系的CPU,每条指令都是32Bit,而地址总线也是32Bit,这样,就不可能通过一条指令来实现Memory的访问。

 C语言中有两种存储类型,自动型和静态型,自动变量是一个过程中 的局部变量。静态变量是进入和退出一个过程时都是存在的。为了简化静态数据的访问,MIPS软件保留了一个寄存器:全局指针gp(global pointer,$gp),如果没有全局指针,从静态数据去装入数据须要两条指令:一条有编译器和连接器计算的32位地址常量中的有效位;令一条才真正装 入数据。全局指针只想静态数据区中的运行时决定的地址,在存取位于gp值上下32KB范围内的数据时,只须要一条以gp为基指针的指令即可。在编译时,数据须在以gp为基指针的64KB范围内。

MIPS中,访问Memory的指令格式为:

lw r1, offset(r2)

其中,offset为16Bit,也就是说,最多能访问以r2为基地址,前后32K的空间。

于是这个时候,gp就闪亮登场了。

我们知道,GCC在编译过程,会将变量分别放在data,bss,common等段。而编译mips程序时,会将小变量放入sdata,sbss,scommon等段。这个大小由编译选项-G来决定。-G0则表示不使用小数据段。默认是-G8,表示小于或等于8 byte的数据将放入小变量区。

这样的话,在上电时给gp初始化一个值,那么,所有小变量区的变量就可以通过

lw r1, offset(gp)

来访问了。

那么,GCC怎么知道gp初始化的值呢?只要在link文件中添加_gp符号,连接器就会认为这是gp的值。我们在上电时,将_gp的值赋给gp寄存器就行了。

相关