GNU工具鏈編譯器

1. 獲取 GNU 工具鏈

因爲是用 GNU 工具鏈編譯能在 Cortex-m3 上跑的程序,因此在 ARM 官網上找到 GNU 的工具鏈,GNU 工具鏈下載

注:EABI 是嵌入式應用程序二進制接口的簡稱。可執行目標文件必須符合該規則,從而可以跨開發工具鏈使用。

2. 開發流程

GNU 工具鏈也包含了編譯器、彙編器和鏈接器等等工具,所以我們的代碼可以使用 C/C++ 語言,也可以使用彙編語言,流程如下所示:

在這裏插入圖片描述

3. 示例程序

接下來我們使用 GNU 工具鏈編譯可以在 Cortex-m3 內核上跑的代碼。

3.1 第一個程序

3.1.1 計算 10+9+8…+1 的值,彙編程序如下:

//example1.s
/* 定義常數 */
	.equ	STACK_TOP, 0x20000800
    .text                //預定義的關鍵字,表示後面內容是代碼
    .global _start       // 聲明標號 _start 爲全局標號, 可以被其它目標文件使用 
    .code 16             //指示程序代碼使用 thumb 編寫
    .syntax unified      //指示使用統一彙編語言語法
  
_start:
	.word	STACK_TOP, start     // 定義 MSP 的初始值爲 0x2000_0800
	.type	start, function      //start 爲復位向量,聲明爲function 是爲了不讓彙編器清除 LSB,因爲 LSB 如果爲 0, 則表示要進入 ARM 狀態, 這是不允許的
	
start:
	movs	r0, #10
	movs    r1, #0

loop:
	adds 	r1, r0
	subs 	r0, #1
	bne		loop
	
deadloop:
	b		deadloop
	
	.end			//指示程序文件的結束

3.1.2 GNU 工具鏈編譯

//1. 使用 GNU 的彙編器編譯 .s 文件, -mcpu 和 -mthumb 決定使用的指令集
$ arm-none-eabi-as -mcpu=cortex-m3 -mthumb example1.s -o example1.o

//2. 使用 GNU 的鏈接器進行鏈接  -Ttext 0x0 表示將鏈接到 0 地址
$ arm-none-eabi-ld -Ttext 0x0 -o example1.out example1.o

//3. 使用 GNU 的二進制產生器 產生二進制文件
$ arm-none-eabi-objcopy -Obinary example1.out example1.bin

//4. 使用 GNU 的反彙編器 反彙編代碼,結果如下圖所示
$ arm-none-eabi-objdump	-S example1.out > example1.list

反彙編後的 example1.list 文件內容:

在這裏插入圖片描述

3.2 鏈接多個文件

通常工程包含多個目標文件,需要鏈接在一起,生成最終的可執行文件。這裏,我們新建 2 個彙編文件,分別爲 example2a.s 和 example2b.s 。前者只包含向量表,後者包含正常的代碼。這裏,**.global 關鍵字就有用了—在文件中傳遞全局符號。

3.2.1 example2a.s 和 example2b.s ,彙編程序如下:

//example2a.s

	.equ STACK_TOP, 0x20000800
    .global vectors_table
    .global start
    .global nmi_handler
    .code 16
    .syntax unified

vectors_table:
	.word	STACK_TOP, start, nmi_handler, 0x00000000
    .end    
//example2b.s
	.text
	.global _start
	.global start
	.global nmi_handler
	.code 16
    .syntax unified
    .type start, function
    .type nmi_handler, function

start:    
    
_start:
	movs	r0, #10
	movs 	r1, #0
	
loop:
	adds 	r1, r0
	subs 	r0, #1
	bne 	loop
	
deadloop:
	b		deadloop
	
nmi_handler:
	bx	lr
	
	.end	

3.2.2 GNU 工具鏈編譯鏈接

//1. 使用 GNU 的彙編器編譯分別編譯 .s 文件, -mcpu 和 -mthumb 決定使用的指令集
$ arm-none-eabi-as -mcpu=cortex-m3 -mthumb example2a.s -o example2a.o
$ arm-none-eabi-as -mcpu=cortex-m3 -mthumb example2b.s -o example2b.o

//2. 使用 GNU 的鏈接器將 2 個目標文件進行鏈接  -Ttext 0x0 表示將鏈接到 0 地址
$ arm-none-eabi-ld -Ttext 0x0 -o example2.out example2a.o example2b.o

//3. 使用 GNU 的二進制產生器 產生二進制文件
$ arm-none-eabi-objcopy -Obinary example2.out example2.bin

//4. 使用 GNU 的反彙編器 反彙編代碼,結果如下圖所示
$ arm-none-eabi-objdump	-S example2.out > example2.list

反彙編後的 example2.list 文件內容:

在這裏插入圖片描述

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