執行時域和載入時域(執行位址和載入位址)

2021-10-18 23:15:14 字數 1047 閱讀 4373

看乙個簡單的例子:

sections    

second 0x30000000 : at(4096)    

以上,head.o放在0x00000000位址開始處,init.o放在head.o後面,他們的執行位址也是0x00000000,即連線和儲存位址相同(沒有at指定);main.o放在4096(0x1000,是at指定的,儲存位址)開始處,但是它的執行位址在0x30000000,執行之前需要從0x1000(載入處)複製到0x30000000(執行處),此過程也就用到了讀取nand flash。這就是儲存位址和連線(執行)位址的不同,稱為載入時域和執行時域,可以在.lds連線指令碼檔案中分別指定。

編寫好的.lds檔案,在用arm-linux-ld連線命令時帶-tfilename來呼叫執行,如arm-linux-ld –tnand.lds x.o y.o –o xy.o。也用-ttext引數直接指定連線位址,如arm-linux-ld –ttext 0x30000000 x.o y.o –o xy.o。

總之:連線位址<==>執行位址

儲存位址<==>載入位址

既然程式有了兩種位址,就涉及到一些跳轉指令的區別,下面就來具體看看這些跳轉指令。

arm彙編中,常有兩種跳轉方法:b跳轉指令、ldr指令向pc賦值。

(1)       b step1 :b跳轉指令是相對跳轉,依賴當前pc的值,偏移量是通過該指令本身的bit[23:0]算出來的,這使得使用b指令的程式不依賴於要跳到的**的位置,只看指令本身。

(2)       ldr pc, =step1 :該指令是從記憶體中的某個位置(step1)讀出資料並賦給pc,同樣依賴當前pc的值,但是偏移量是那個位置(step1)的連線位址(執行時的位址),所以可以用它實現從flash到ram的程式跳轉。

我們以後會經常用到「儲存位址和連線位址不同」(術語上稱為載入時域和執行時域)的特性:大多機器上電時是從位址0開始執行的,但是從位址0執行程式在效能方面總有很多限制,(執行位址和載入位址不同時,只能用相對跳轉)所以一般在開始的時候,使用與位置無關的指令將程式本身複製到它的連線位址處,然後使用向pc暫存器賦值的方法跳到連線位址開始的記憶體上去執行剩下的**。

執行時域和載入時域(執行位址和載入位址)

執行時域和載入時域 執行位址和載入位址 參考文獻 雲邊日的空間 mr raptor的專欄 在連線目標 時 會提到執行位址和載入位址。載入時位址就是程式放置的位址,執行位址就是程式定位的絕對位址,也即在編譯連線時定位的位址。如果程式是在 flash 裡執行,則執行位址和載入位址是相同的。如果程式是在 ...

執行位址和載入位址

在連線目標 時,會提到執行位址和載入位址。這兩者有什麼區別呢?載入時位址就是程式放置的位址,執行位址就是程式定位的絕對位址,也即在編譯連線時定位的位址 如果程式是在flash裡執行,則執行位址和載入位址是相同的。如果程式是在ram裡執行,但程式是儲存在flash裡,則執行位址指向ram,而載入位址是...

執行位址和載入位址

在連線目標 時,會提到執行位址和載入位址。這兩者有什麼區別呢?載入時位址就是程式放置的位址,執行位址就是程式定位的絕對位址,也即在編譯連線時定位的位址 如果程式是在flash裡執行,則執行位址和載入位址是相同的。如果程式是在ram裡執行,但程式是儲存在flash裡,則執行位址指向ram,而載入位址是...