2010-08-17 58 views
12

我在學習彙編語言,需要澄清一些事情。如果我對這個問題有任何疑問,請糾正我,因爲我對裝配了解不多。程序集內存分配

我看的所有教程都將彙編程序的變量分配給內存地址,如0x0000,我可以理解您必須在彙編中手動分配內存地址,但您如何知道要使用的地址?

很明顯,從最低內存地址開始是有道理的,但如果分配的變量大於0x0000處的內存,該怎麼辦?所討論的變量是否會運行到0x00010x0002?如果它確實不會把其他變量分配給具有相似編號的空格(或者你不應該把它們分配給那些關閉)?

如果我有兩個程序同時運行(在一個現代操作系統中)並且我在這兩個程序中都使用了相同的內存地址,一個程序是否會與另一個程序發生衝突,或者OS是否只分配一個可用內存地址,而不管程序中實際寫入的內容是什麼?

關於這個問題的任何信息表示讚賞。

回答

18

對第二部分問題(大多數現代操作系統)的回答是虛擬內存。

您從具有物理內存的硬件層開始。這是你可以用手指戳的東西。這就是操作系統所看到的。操作系統允許您在稱爲虛擬內存的抽象上運行進程。

每個進程都有自己的虛擬內存空間。所以它可以假裝它是唯一的進程運行,並且它有大量的內存。然後,每次訪問內存時,都會提供一個虛擬地址,將其映射到物理地址。操作系統保存哪個虛擬地址映射到RAM中哪些實際物理地址的表。通常情況下,出於性能方面的考慮,這也是通過一些特殊的硬件(MMU,內存管理單元)完成的,但您也可以在軟件中100%地完成。

所以當你在程序中說0x000時,這是一個虛擬地址。當您讀取或寫入時,它會被計算機翻譯成物理地址。所以在另一個進程中,相同的虛擬地址0x000映射到不同的物理地址。這個系統可以讓你編寫你的程序,而不必知道有多少RAM可用,或者你的程序將被加載到什麼地址。它還可以防止程序破壞屬於另一個程序的內存。

至於第一部分,絕對。不同類型的數據需要不同數量的內存。在佈置數據結構時,您必須知道需要多少空間。還要記住字節對齊問題。多字節數據類型(例如浮點數)通常必須從可以被2或4整除的地址或存儲浮點數所需的字節數開始 - 這是處理器或RAM的要求。所以你不能只把所有的數據緊密地聯繫起來,一個字節在下一個字節之後,如果你想最小化未使用的內存,你必須按照特定的順序將它們拼湊在一起,拼成一個拼圖塊。

+0

感謝您的詳細解答!在答案的最後部分,如何精確計算每一位數據需要多少空間?手動計算一個程序的數百個變量似乎不可行。用你的話說,你如何「擺脫」? – ubiquibacon 2010-08-17 00:37:54

+0

我從未在任何大型項目中使用過程序集,但在我的操作系統類中推薦的啓發式算法是按大小對變量進行排序,然後將最小的變量放在最低內存地址處。這並不總是最好的佈局 - 您可能能夠在大數據類型之間使用小數據類型。 您應該能夠從變量的類型中知道它需要多少內存 - 請參考彙編語言的文檔。請記住,一個變量在程序的整個運行過程中會佔用相同數量的內存。它不能「增長」。這就是溢出發生的原因。 – 2010-08-17 00:41:40

+1

偉大的答案,只是一個更正。正確對齊數據不是關於節省空間,因爲它的所有連續內存無論如何。它與數據總線如何映射到內存有關。前8位從地址0開始,接下來的8位連接到地址1.這意味着從地址0開始的16位整數可以在單次讀取中讀取,因爲它使用數據總線的兩側。但是,如果一個16位整數從1開始,它現在必須進行兩次讀取才能得到整個整數。對於32位整數,出於同樣的原因,它們應該在可被4整除的地址處開始。 – Despertar 2016-05-18 22:06:24

1

取決於目標和你正在談論的內存(RAM,ROM等)的類型。如果您正在討論RAM是一個小型嵌入式項目,您可能只有幾個文件需要跟蹤,微型數據表會告訴您各種存儲器區域尋址。在有多個「模塊」的情況下,您可以使用鏈接器將目標文件鏈接到可執行文件中。鏈接器可以重新分配內存地址,以便它們不重疊,也可以有一箇中心文件,其中定義了所有內存位置,其他模塊將其用作資源。抱歉。這是一個有很多答案的大問題。

5

這不完全是一個答案,但在這本書中有答案。我只能推薦它。它會教你基本知識,就像名字所說的那樣,它是從頭開始編程的。

ProgrammingGroundUp