『壹』 arm-linux程序的鏈接地址和原先地址
連接器腳本xxx.lds文件中指定的地址,就是鏈接地址,程序運行時必須位於它的鏈接地址處,匯編文件中的各個標號或者c文件中的各個函數名(函數的入口地址)對應的鏈接地址就是由鏈接腳本中的起始鏈接地址和各個目標文件(.s或.c文件編譯但還為鏈接的文件)的排放順序有關。這些鏈接地址可以通過查看可執行文件的反匯編文件即xxx.dis文件來獲得.
如果你不使用全局變數或者靜態變數,訪問這些變數時要使用到鏈接地址,重定位完成之前不能使用這些類型的變數,adr、b和bl指令都是屬於相對跳轉指令,即在當前pc值的基礎上加減一個偏移值,跳轉去執行。如果只使用adr、b或者bl指令,並且不訪問全局變數或者靜態變數,這類代碼被稱為「位置無關碼」,即代碼的存儲位置可以不在其鏈接地址處。如果當使用全局跳轉指令ldr時就只能使用鏈接地址了,如ldr pc,_reset。程序運行時,pc指針的內容是不區分原本地址(存儲地址)或鏈接地址的,只要是」位置無關碼「,存儲地址可以與鏈接地址不同,不是位置無關碼就要使用到鏈接地址,即存儲地址與鏈接地址必須相同。即使用之前必須完成代碼的重定位。
ps:望採納!
『貳』 c語言程序載入到內存時,程序內各段之間的地址是連續的嗎
不聯續吧,編譯器會按一定組織,載入到內存時以一定方式映射,有本《加密解密內幕》的書講這個很好
『叄』 C語言的&運算符取的是邏輯地址還是物理地址 每次重新編譯運行後 輸出變數的地址值都一樣 怎麼理解
您需要了解一下操作系統的虛擬內存機制。
操作系統會為新建立的每一個進程開辟一個獨立卻完整的地址空間(32位機器是4GB),其中除了一部分地址要交給操作系統的內核或用於某些特殊功用,程序可以自由地使用這些內存,就好像每個進程可以獨自使用一台4GB內存的機器一樣。但是要注意這是由操作系統虛擬出來的,系統的內存管理器要負責把這些虛擬的內存映射到真實的物理內存中。系統往往同時運行很多進程,要把真實的內存給每個進程都分配4GB當然不可能,所以系統往往還要借用硬碟來存放物理內存存不下的內容,協助虛擬內存的實現。實際的物理內存的狀況是:零散無規律地分布著各個進程的內存頁面。
當一個新進程啟動時,操作系統首先為該進程創建虛擬內存空間,然後把程序的代碼段和一部分數據放在固定的虛擬內存地址上。你說的那個變數A就是被包含這部分數據中,每次啟動程序都可以看到它在一個固定的地址上,但是這個地址是在虛擬內存中的,實際它所對應的真實物理內存的地址是未知的,只有管理內存的系統內核知道。
當然,還有一部分數據在你的虛擬內存空間的地址也是未知的,這就是堆,堆允許程序在運行過程中動態分配和釋放內存(其他的內存分配方式在程序啟動時就在固定位置分配,不能改變),堆的分配和釋放由C運行時庫和操作系統協同管理,分配的內存地址是隨機的。你說的那個變數A不是堆中的。
你說的邏輯地址就是在虛擬內存中的地址,物理地址就是在真實的物理內存中的地址。
對於以上有不懂的概念名詞可網路查資料。
『肆』 C程序:關於編譯的問題。。。(回答好的可繼續加分)
1、是,obj文件裡面有段信息
2、沒有,堆是運行的時候由運行庫給你分配的(windows下vc運行庫其實用的是系統提供的堆),棧式運行的時候系統給你分配的,編譯後的obj裡面甚至連棧段有多大這樣的信息都沒有(這是鏈接的時候加上去的)
全局變數的邏輯地址是不變的這說法在沒開啟動態基地址的時候是正確的,每次exe載入到內存中以後,同一個全局變數都在同一個位置。不過windows下開啟動態基地址之後每次exe都可能被載入到不同的地址上,這個時候全局變數的內存地址就會變化了。
『伍』 請問程序在編譯和鏈接的時候,邏輯地址是否是連續的請高手解答。謝謝。
函數內部是連續的吧,因為一起分配的棧; 不同函數的棧可能就不連續了啊
『陸』 程序變數每次運行,申請的內存地址一樣么
我們所看到的這個地址並不是真正物理地址的值,每個程序在windows開始運行都需要開辟空間,這個空間根據當前系統中運行的程序的多少和先後順序都會有所不同,我們看到的這個變數地址其實是相對於本程序進程的起始地址的偏移量。舉個例子來說,你寫了個a.exe程序,這一次運行a.exe程序系統分配給他的起始內存空間地址是4012ff00,那麼這個變數在開辟空間的時候,可能之前已經定義了一些變數或者其它結構佔用了7c的空間,則這個變數地址為4012ff7c,偏移地址為0012ff7c;關掉這個程序,再開它,則可能進程地址變為了5012ff00,那麼這個變數的物理地址就為5012ff00,偏移地址仍舊為0012ff7c。
但是也不是說這個偏移地址是一成不變的,這涉及到這個變數的開辟時是不是總是固定在一個順序上,例如
我寫個函數像這樣:
void
aa(int
m)
{
if(m>5)
{
int
x=2;int
y=3;int
z=0;z=x+z;
}
else
{
int
z=2;int
x=3;int
y=0;y=x+z;
}
}
那麼顯然x這個變數的開辟時間點取決於變數m的大小,則開辟的先後也決定了x這個變數的地址,所以這些變數是動態變化的,如果涉及到結構和類的成員變數,還需要考慮這個結構或類對象的創建次序,這需要涉及到一些底層的思想
『柒』 4、同一個程序在不同編譯器(比如VC或TC)下第一個變數的地址是否相同,均為ox12ff7c如果相同,為什麼
不一定形同 因為C語言在編譯程序時 通常會根據你的內存來進行選擇 並進行優化 這和你的硬體還有關
『捌』 計算機內存是動態分配的,程序每次運行的物理地址都不一樣,但偏移地址是不變的。偏移地址是誰分配的
一般程序的偏移地址,相對於其實地址 比較固定吧,沒弄成話和程序編譯相關。之後在根據實際操作系統分配的內存空間進行偏移。,地址沖突,是靠操作系統控制,4G地址空間,程序使用的是虛擬地址,進過操作系統翻譯後才是實際地址。一般程序是通過操作系統中介才能放到內存數據。不能直接訪問。
『玖』 為什麼C語言變數的地址每一次運行都是一樣的,在360隔離沙箱里運行也是一樣的
變數地址是由編譯器決定的
360隔離沙箱是不讓程序寫入磁碟,不是不讓程序載入內存
『拾』 我用visual studio 2019,為什麼每次輸出相同變數的地址都不一樣的
建議先研究一下數據結構,在內存中每次程序聲明變數時,都會順序從地址空間中找一塊大小足夠的空間,不同時間編譯,因為系統各種後台等佔用的內存有變化,所以地址會不同