.lds鏈接腳本以及編譯流程分析

鏈接腳本.lds文件

作用:控制輸出文件在內存中的排布


最簡單的連接腳本

SECTIONS{
	. = 0X10000000;
	.text : {*(.text)}
	. = 0X30000000;
	.data ALIGN(4) : { *(.data) }
	.bss ALIGN(4) : { *(.bss) }
}

SECTIONS中定義輸出文件的內存佈局,編譯出的代碼一般是有text段、data段、bss段、和rodata段。代碼段連接到0X10000000,數據段連接到0X30000000上。

  • '.'爲賦值符號
  • .text : 是段名
  • *(.text) ,星號表示通配符,表示所有輸入文件的.text段都放入.text中。
  • ALIGN(4),表示4字節對齊

以IMX6U處理器爲例

SECTIONS{
	. = 0X87800000;
	.text :
	{
		start.o
		*(.text)
	}
	.rodata ALIGN(4) : {*(.rodata*)}
	.data ALIGN(4) : { *(.data) }
	__bss_start = .;
	.bss ALIGN(4) : { *(.bss) *(COMMON) }
	__bss_end = .;
}

start.o包含一個需要執行的指令,所以要鏈接在前面:

  • __bss_start 保存bss段的起始地址
  • __bss_end 保存bss段的結束地址

源代碼編譯成可執行程序經歷的過程

在這裏插入圖片描述

1.預編譯的過程gcc -E main.c -o main.i

  • 處理所有的#define #if #endif #ifdef #elif #else
  • 去掉所有的註釋
  • 保留#pragma編譯器指令
  • 產生行數和文件標識,有利於編譯器拋出錯誤提示
  • .c文件預編譯生成.i文件
  • .cpp文件預編譯生成.ii文件

2.編譯的過程gcc -s main.c -o main.s

  • 詞法分析:分解生成一系列的記號
  • 語法分析:生成語法樹,分析語法錯誤
  • 語義分析:對表達式是否有意義做判斷
  • 優化: 調整指令,優化
  • 目標代碼生成: 將中間代碼轉變成彙編
  • 目標代碼優化:尋找合適的尋址方式,用位移代替乘法,刪除多餘的指令
  • 生成.s文件的彙編代碼

3.彙編的過程gcc -c main.c -o main.o

  • 將彙編文變成機器指令(根據對照表轉化)——通過彙編器AS完成
  • 生成.o文件

4.鏈接的過程gcc main.o -o main

  • 代碼是模塊化的
  • 通過鏈接鏈接在一起,將各個.o文件鏈接起來(windows是obj文件)
  • 重新分配section空間,每個.o文件都有自己獨立的.text段和.data段,鏈接器生成的可執行文件中需要對text段和data段空間進行劃分。
  • 目標文件.o通過和庫進行鏈接可以得到.out文件
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章