ARM處理器的位置無關(guān)程序設(shè)計(jì)
上述匯編代碼段經(jīng)編譯后的結(jié)果為:
LDR R1, [PC, OFFSET_TO_GPIO_BASE]
LDR R0, [PC, OFFSET_TO_init_GPDR0]
STR R0, [R1, #0xc]?
GPIO_BASE
DCD 0x40e00000
GPDR0
DCD 0x00c
init_GPDR0
DCD 0xfffbfe00
可見,LDR偽指令實(shí)際上使用基于PC的偏移量來對(duì)符號(hào)常量GPIO_BASE和init_GPDR0進(jìn)行引用,因而是位置無關(guān)的。由此可以得出如下結(jié)論:使用LDR偽指令將一個(gè)常量讀取到非PC的其他通用寄存器中可實(shí)現(xiàn)位置無關(guān)的常量訪問;但將一個(gè)地址值讀取到PC中進(jìn)行程序跳轉(zhuǎn)時(shí),跳轉(zhuǎn)目標(biāo)則是位置相關(guān)的。
(2) 程序設(shè)計(jì)規(guī)范2
其他被ROPI段中的代碼引用的必須是絕對(duì)地址,或者是基于可讀寫位置無關(guān)(RWPI)段的靜態(tài)基址寄存器的可寫數(shù)據(jù)。
使用絕對(duì)地址只能引用被重定位到特定位置的代碼段中的符號(hào),通過在位置無關(guān)代碼中引入絕對(duì)地址,可以讓程序跳轉(zhuǎn)到指定位置。例如,假設(shè)Bootloader的階段1將其自身代碼拷貝到鏈接時(shí)所指定的SDRAM地址空間后,當(dāng)要跳轉(zhuǎn)到階段2的C程序入口時(shí),可以使用指令“LDR PC, =main”跳轉(zhuǎn)到程序在SDRAM中的main函數(shù)入口地址開始執(zhí)行。這是因?yàn)槌绦蛟诰幾g鏈接時(shí)給main函數(shù)分派絕對(duì)地址,系統(tǒng)通過將main函數(shù)的絕對(duì)地址直接賦給PC實(shí)現(xiàn)程序跳轉(zhuǎn)。如果使用相對(duì)跳轉(zhuǎn)指令“B main”,那么只會(huì)跳轉(zhuǎn)到啟動(dòng)ROM內(nèi)部的main函數(shù)入口。
評(píng)論