地址有關碼和地址無關碼

幾個地址的說明:
   (cpu看來)    (程序員看來)
1、運行地址<---->鏈接地址
2、加載地址<---->存儲地址
他們對應等價,只是從不同的角度說。
進一步闡述:
運行地址:程序在SRAM、SDRAM中執行時的地址。就是執行這條指令時,PC應該等於這個地址,換句話說,PC等於這個地址時,這條指令應該保存在“這個地址”內,在這個地址cpu可以得到要的指令,不管中間有沒有映射關係。
加載地址:程序保存在Flash中的地址,拿一個函數來說就是燒到Flash的鏡像文件中它相對於鏡像起始地址的偏移位置。通常情況都是cpu在運行前期根據某個加載地址把這段代碼拷貝到SDRAM中運行。

地址無關碼:B、BL、MOV都是位置無關碼。這是一種相對於當前pc指針的跳轉。
地址有關碼:LDR PC,=LABEL等類似的代碼都是位置有關碼。這是一種絕對地址跳轉,LABLEL是程序員指定的運行地址。
                       還有一個地址相關的取地址指令不得不說一下,就是“ADR”,舉個例子:
                       ADR R0 _start ;相當於add r0, pc, #(_start<->pc地址偏移),假設_start是代碼起始地址,若運行於SRAM,pc是0x0打頭的;若運行於SDRAM,pc是0x3打頭的
總之,一句話概括爲地址無關碼是靠相對於參考對象的偏移量來工作的,而地址有關碼總是固執地認爲代碼放在那個地方找不到就罷工。

若鏡像文件的鏈接地址不是統一指向0x00000000,在開啓MMU之前,要實現函數調用或跳轉只能使用B、BL和MOV地址無關碼來實現。


幾個容易混淆的指令:注意等號的使用
(1)ldr r0, _start 這是一個讀取_start地址處內存單元的內容,過程是根據相對於當前pc的offset來找到_start地址,當然這個offset是編譯程序時固定的相對偏移量
(2)ldr r0, =_start 取絕對地址_start給r0,絕對地址cpu看來就是運行地址
(3)adr r0, _start r0=相對於當前pc的offset(這個值在編譯時已經固定下來,有“+”“-”)+_start

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章