gp ,g lobal pointer,全局指針寄存器,RISC-V 32個寄存器之一,為了優化±2KB內全局變量的訪問。
gp寄存器在啟動代碼中加載為__global_pointer$
的地址,并且之后不能被改變。
linker時使用 __global_pointer$ 來比較全局變量的地址,如果在范圍內,就替換掉lui或puipc指令的 absolute/pc-relative尋址, 變為gp-relative尋址,使得代碼效率更高。 該過程被稱為 linker relaxation (鏈接器松弛),也可以使用-Wl,--no-relax
來關閉此功能。
如:需要讀取全局變量 tao_global的值,地址位 0x20000100 ,gp指針地址為 0x20000800 ;
- 普通調用方式為:
lui a5,0x20000 /* 將0x20000100高20位0x20000 左移12位賦給a5寄存器 */ lw a5,256(a5) /* 加載a5+256(0x100,0x20000100低12位)的值至a5寄存器 */
- gp指針優化調用方式:
lw a5,-1792(gp) /* 加載gp-1792地址處的值至a5,即0x20000100處的值*/
通過gp指針,訪問其值±2KB,即4KB范圍內的全局變量,可以節約一條指令。
4KB區域可以位于尋址內存中任意位置,但是為了使優化更有效率,最好覆蓋最頻繁使用的RAM區域。 對于標準的newlib應用程序,這是分配.sdata部分的區域,因為它包含了諸如_impure_ptr、malloc_sbrk_base等變量。 因此,定義應該被放在.sdata部分之前。 以RISC-V MCU CH32V103 ld文件為例:
.data :
{
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 ); /* __global_pointer地址*/
*(.sdata .sdata.*)
*(.sdata2.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(4);
PROVIDE( _edata = .);
} >RAM AT>FLASH
gp指針優化代碼空間---
通常情況下,gp指針定義在data區,有時候為了優化代碼密度,可以根據實際情況修改gp指針的位置,如工程中定義了大量的初始化為0或未初始化的全局數組作為緩沖區,可以將gp指針的位置定義到bss段。
-
mcu
+關注
關注
146文章
17317瀏覽量
352631 -
寄存器
+關注
關注
31文章
5363瀏覽量
121156 -
指針
+關注
關注
1文章
481瀏覽量
70608 -
變量
+關注
關注
0文章
613瀏覽量
28463 -
RISC-V
+關注
關注
45文章
2322瀏覽量
46589
發布評論請先 登錄
相關推薦
擁抱RISC-V的開發世界 兆易創新推GD32VF103系列RISC-V MCU
國產RISC-V MCU推薦
RISC-V的MCU與ARM對比
RISC-V的MCU關于USB高速通信設計的難點
risc-v的mcu對RTOS兼容性如何
RISC-V MCU開發 (一):集成開發環境
RISC-V MCU開發相關資料分享
RISC-V MCU開發相關資料分享
RISC-V的相關資料分享
RISC-V MCU開發的相關資料分享
RISC-V gp全局指針寄存器說明
RISC-V MCU開發(一):集成開發環境
![<b class='flag-5'>RISC-V</b> <b class='flag-5'>MCU</b>開發(一):集成開發環境](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論