鏈接文件簡要說明

鏈接文件格式.lds
在最終生成可執行文件的時候,會確定各個段的位置

SECTIONS {
        .text 0 : {*(.text)}//所有文件的.text段都放在地址0開始的位置
        .rodata :{*(.rodata)}//所有文件的.rodata段都放在地址.text地址之後
        .data 0x30000000 : AT(0x800)//數據段 運行的地址是0x30000000 : 加載的地址是0x800
        {   
                data_load_addr = LOADADDR(.data); //讓變量data_load_addr 等於數據的起始地址
                . = ALGN(4) //讓data段開始的位置在4字節對齊的地址
                data_start = . ; //變量data_start 等於當前地址
                *(.data)//存放所有數據段,當前地址會根據data的大小而進行增加
                data_end = . ; //變量data_end 等於當前地址, 這個當前的地址是data_start+*(.data)後的位置
        }
        . = ALIGN(4); //讓bss段開始的位置在4字節對齊的地址
        bss_start = .; //變量bss_start 等於當前地址
        .bss :{*(.bss) *(.COMMON)} //存放所有bss和commen段,bss沒有寫運行地址和加載地址,所以默認是data段之後的位置。 當前地址會根據bss和comment的大小而增加
        bss_end = .;//變量bss_start 等於當前地址, 這個當前地址是bss_start+*(.bss) +*(.COMMON)後的位置
}


語法格式:
主要分成下面四個部分,中間用:間隔

段名 運行地址或者重定位後的地址 : 加載地址 {內容}

  1. 加載地址如果沒有,就默認和前面的運行地址一致
  2. 運行地址或者重定位後的地址沒有,就表明這個段和緊跟上面段後面
  3. 內容由{ }包起來,裏面可以有多條語句

關於存放4字節對齊:ALIGN(4)
以下面代碼爲例

char g_Char = 'A';
char g_Char3 = 'a';
int g_A = 0;
int g_B;

int main(void)
{
	...
}

上面的代碼如果不進行對齊存放的話,加載到內存會是這樣的情況,如果要對整型數據g_A進行操作,那麼其實地址是0x30000002, 對於32位的CPU,當它對整型數據操作時,會默認從4字節對齊的位置操作,也就是,你要操作0x30000002,那麼,cpu會自動把地址更換成0x3000000 。這樣的話你就會改動g_char 和 g_char3這兩個數據和g_A的前2個字節。
發生的

如果在鏈接的時候使用 ALIGN(4)進行字節對齊存放,會變成下面的樣子。如果要對整型數據g_A進行操作,那麼其實地址是0x30000004,對於32位cpu來說,是符合4字節對齊的地址。那麼就能正確的操作g_A的4個字節數
在這裏插入圖片描述

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