看過《STM32入門學(xué)習(xí)第一或二階段視頻教程》,對(duì)STM32有一定的基礎(chǔ);或沒有基礎(chǔ),先看此文再去看《STM32入門學(xué)習(xí)第一或二階段視頻教程》
1,C程序到可執(zhí)行程序的四個(gè)步驟:
預(yù)處理(Preprocessing),編譯(Compilation),匯編(Assemble),鏈接(Linking)
2,回顧GCC編譯過程(以doubixiaohanhan.c舉例)
(參考 逗比小憨憨的《gcc零基礎(chǔ)入門學(xué)習(xí)教程》)
//doubixiaohanhan.c
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int i=0;
if(argc < 2)
{
printf("parameters is not enough\n");
exit(1);
}
while(argv[i])
{
printf("argv[%d]=%s\n",i,argv[i]);
i++;
}
return 0;
}
(1)預(yù)處理
以“#”號(hào)開頭的預(yù)處理指令,比如包含#include,宏定義指定#define等。在源程序中這些指令都放在函數(shù)之外,而且一般放在源文件的前面。使用預(yù)處理器把源文件doubixiaohanhan.c經(jīng)過預(yù)處理生成doubixiaohanhan.i文件。(簡(jiǎn)單來說就是展開程序中的宏等)
預(yù)處理的命令為:
gcc -E doubixiaohanhan.c -o doubixiaohanhan.i
(2)編譯
指將經(jīng)過預(yù)處理文件(doubixiaohanhan.i)之后的程序轉(zhuǎn)換成特定匯編(doubixiaohanhan.s)代碼的過程。
命令:gcc -S doubixiaohanhan.i -o doubixiaohanhan.s
備注:Linux下,命令stat可以查看匯編代碼和代碼大小;命令file可以查看文件類型
(3)匯編
匯編過程將上一步生成的匯編代碼轉(zhuǎn)換成機(jī)器碼,這一步產(chǎn)生的文件叫做目標(biāo)文件,是二進(jìn)制格式。
命令:gcc -c doubixiaohanhan.s -o doubixiaohanhan.o
(4)鏈接
鏈接過程使用鏈接器將上述目標(biāo)文件與其它目標(biāo)文件、庫文件、啟動(dòng)文件等鏈接起來生成可執(zhí)行文件。附加的目標(biāo)文件包括靜態(tài)連接庫和動(dòng)態(tài)連接庫。
命令: gcc doubixiaohanhan.o -o doubixiaohanhan
備注:指定庫文件路徑 gcc -L xxx(參考 逗比小憨憨的《gcc零基礎(chǔ)入門學(xué)習(xí)教程》)
(1) 編譯(匯編):MDK 軟件使用的編譯器是 armcc 和 armasm,它們根據(jù)每個(gè) c/c++ 和匯編源文件編譯成對(duì)應(yīng)的以“.o”為后綴名的對(duì)象文件 (Object Code,也稱目標(biāo)文件),其內(nèi)容主要是從源文件編譯得到的機(jī)器碼,包含了代碼、數(shù)據(jù)以及調(diào)試使用的信息。
(2) 鏈接:鏈接器 armlink 把各個(gè).o文件和相應(yīng)的庫文件鏈接成一個(gè)映像文件“.axf”或“.elf”;
(3) 格式轉(zhuǎn)換:一般來說 Windows 或 Linux 系統(tǒng)使用鏈接器直接生成可執(zhí)行映像文件elf 然后,內(nèi)核根據(jù)該文件的信息加載后,就可以運(yùn)行程序了,但在單片機(jī)平臺(tái)上,需要把該文件的內(nèi)容加載到芯片上,所以還需要對(duì)鏈接器生成的 elf 映像文件利用格式轉(zhuǎn)換器 fromelf 轉(zhuǎn)換成“.bin”或“.hex”文件,交給下載器下載到芯片的 FLASH 或 ROM 中。
擴(kuò)展知識(shí)點(diǎn):hex文件與bin文件的主要區(qū)別?
hex文件包含了地址信息,bin文件格式只包括了數(shù)據(jù)本身,沒有包含地址。
回顧《單片機(jī)實(shí)踐視頻教程》課程:
在用ISP方式(通過串口下載)燒寫51程序時(shí)的步驟:
從上述步驟可知:我們并沒有選擇要把程序下載到單片機(jī)的哪塊內(nèi)存中,即不需要設(shè)置地址。因?yàn)镠EX文件內(nèi)部的信息已經(jīng)包括了地址。而燒寫下載bin文件時(shí)需要選擇內(nèi)存的起始地址和終止地址,即要把bin文件下載到指定的內(nèi)存空間。通常需要指定程序內(nèi)存地址的芯片為ARM芯片和DSP芯片。
打開Keil MDK軟件安裝目錄,可以找到上述提高的armasm,armlink等文件。
具體方法:
(1)打開任意一個(gè)《STM32入門視頻教程第一或二階段》工程文件,然后編譯keil工程,出現(xiàn)一下提示信息:
上圖找到: *** Using Compiler 'V5.06 update 3 (build 300)', folder: 'E:\keilmdk5Setup\ARM\ARMCC\Bin'
(2)打開這個(gè)文件夾:E:\keilmdk5Setup\ARM\ARMCC\Bin
解釋:
備注:每個(gè) C 文件都對(duì)應(yīng)生成了.o、.d 及.crf 后綴的文件,還有一些額外的.dep、.hex、.axf、.htm、.lnp、.sct、.lst 及.map 文件。
擴(kuò)展知識(shí)點(diǎn):Linux段管理(這一部分可以自行百度看看,這里只是簡(jiǎn)單講解)
在Linux下內(nèi)存分配是以頁為單位的,而頁是通過段管理,各個(gè)段之間是獨(dú)立的,方便管理。一個(gè)簡(jiǎn)單的程序被編譯成目標(biāo)文件后的大致結(jié)構(gòu)如下:
各個(gè)段位的簡(jiǎn)單說明
程序初始化入口代碼,在main()之前運(yùn)行
通常是指用來存放程序中未初始化的全局變量和未初始化的局部靜態(tài)變量。未初始化的全局變量和未初始化的局部靜態(tài)變量默認(rèn)值是0。bss段屬于靜態(tài)內(nèi)存分配。
數(shù)據(jù)段(data segment)通常是指用來存放程序中已初始化的全局變量和已初始化的靜態(tài)變量的一塊內(nèi)存區(qū)域。數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配。
代碼段(code segment / text segment)通常是指用來存放程序執(zhí)行代碼的一塊內(nèi)存區(qū)域。這部分區(qū)域的大小在程序運(yùn)行前就已經(jīng)確定,并且內(nèi)存區(qū)域通常屬于只讀,某些架構(gòu)也允許代碼段為可寫,即允許修改程序。在代碼段中,也有可能包含一些只讀的常數(shù)變量,例如字符串常量等。
存放的是只讀數(shù)據(jù),比如字符串常量,全局const變量和#define定義的常量。本段又稱為常量區(qū)。并不是所有的常量都放在rodata段的,其特殊情況如下:
1) 有些立即數(shù)和指令編譯在一起直接放在代碼段;
2) 對(duì)于字符串常量,編譯器會(huì)去掉重復(fù)的常量,讓程序的每個(gè)字符串常量只有一份
3) 有些系統(tǒng)中rodata段是多個(gè)進(jìn)程共享的,目的是為了提高空間的利用率
存儲(chǔ)的是變量名、函數(shù)名等
存儲(chǔ)bss、text、data等段名。
針對(duì)text段的重定位表,還有rel.data(針對(duì)data段的重定位表)
堆是用于存放進(jìn)程運(yùn)行中被動(dòng)態(tài)分配的內(nèi)存段,它的大小并不固定,可動(dòng)態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc()等函數(shù)分配內(nèi)存時(shí),新分配的內(nèi)存就被動(dòng)態(tài)添加到堆上(堆被擴(kuò)張);當(dāng)利用free()等函數(shù)釋放內(nèi)存時(shí),被釋放的內(nèi)存從堆中被剔除(堆被縮減)。
是用戶存放程序臨時(shí)創(chuàng)建的局部變量和在函數(shù)被調(diào)用時(shí),其參數(shù)也會(huì)被壓入發(fā)起調(diào)用的進(jìn)程棧中,并且待到調(diào)用結(jié)束后,函數(shù)的返回值也會(huì)被存放回棧中。由于棧的先進(jìn)后出特點(diǎn),所以棧特別方便用來保存/恢復(fù)調(diào)用現(xiàn)場(chǎng)。從這個(gè)意義上講,我們可以把棧看成一個(gè)寄存、交換臨時(shí)數(shù)據(jù)的內(nèi)存區(qū)。
重點(diǎn)了解:
bss段,data段,text段,rodata段,heap堆,stack棧
備注:ZI-data 的棧空間 (Stack) 及堆空間 (Heap):在 C 語言中,函數(shù)內(nèi)部定義的局部變量屬于棧空間,進(jìn)入函數(shù)的時(shí)候從向棧空間申請(qǐng)內(nèi)存給局部變量,退出時(shí)釋放局部變量,歸還內(nèi)存空間。而使用 malloc(在C++程序中的new) 動(dòng)態(tài)分配的變量屬于堆空間。在程序中的棧空間和堆空間都是屬于ZI-data 區(qū)域的,這些空間都會(huì)被初始值化為 0 值。編譯器給出的 ZI-data 占用的空間值中包含了堆棧的大小 (經(jīng)實(shí)際測(cè)試,若程序中完全沒有使用 malloc 動(dòng)態(tài)申請(qǐng)堆空間,編譯器會(huì)優(yōu)化,不把堆空間計(jì)算在內(nèi))。
使用malloc動(dòng)態(tài)分配內(nèi)存,則使用free釋放其內(nèi)存;使用new動(dòng)態(tài)分配內(nèi)存,則使用delete釋放其內(nèi)存。
總結(jié):
一般情況下,LMA和VMA都是相等的,不等的情況主要發(fā)生在一些嵌入式系統(tǒng)上
參考資料:MDK 的幫助手冊(cè)《ARM Development Tools》,點(diǎn)擊 MDK 界面的“help->uVision Help”菜單可打開該文件
此文還沒寫完,待更新。。。。。。
特別聲明:軟件只用于學(xué)習(xí),商業(yè)用途請(qǐng)大家購(gòu)買正版。
軟件介紹:
Keil C51是51系列兼容單片機(jī)C語言軟件開發(fā)系統(tǒng),與匯編相比,C語言在功能上、結(jié)構(gòu)性、可讀性、可維護(hù)性上有明顯的優(yōu)勢(shì),因而易學(xué)易用。Keil提供了包括C編譯器、宏匯編、鏈接器、庫管理和一個(gè)功能強(qiáng)大的仿真調(diào)試器等在內(nèi)的完整開發(fā)方案,通過一個(gè)集成開發(fā)環(huán)境(μVision)將這些部分組合在一起。如果你使用C語言編程,那么Keil幾乎就是你的不二之選,即使不使用C語言而僅用匯編語言編程,其方便易用的集成環(huán)境、強(qiáng)大的軟件仿真調(diào)試工具也會(huì)令你事半功倍。
安裝步驟:
1.選中【Keil uvision4 C51版】壓縮包,鼠標(biāo)右擊選擇【解壓到Keil uvision 4 C51版】。
解壓到Keil uvision 4 C51版
2.雙擊打開【Keil uvision4 C51版】文件夾。
Keil uvision4 C51版
3.選中【KeiluVision4】可執(zhí)行文件,鼠標(biāo)右擊選擇【以管理員身份運(yùn)行】。
以管理員身份運(yùn)行
4.點(diǎn)擊【Next>>】。
點(diǎn)擊【Next>>】
5.勾選【I agreeto all terms…】然后點(diǎn)擊【Next>>】。
勾選【I agreeto all terms…】然后點(diǎn)擊【Next>>】
6.使用默認(rèn)路徑即可,點(diǎn)擊【Next>>】。
使用默認(rèn)路徑即可,點(diǎn)擊【Next>>】
7.填寫信息,然后點(diǎn)擊【Next>>】。
填寫信息,然后點(diǎn)擊【Next>>】
8.安裝中。
安裝中
9.取消勾選【ShowRelease Notes】和【Add example…】然后點(diǎn)擊【Finish】。
取消勾選【ShowRelease Notes】和【Add example…】然后點(diǎn)擊【Finish】
10.在桌面雙擊打開【KeiluVision4】。
在桌面雙擊打開【KeiluVision4】
11.點(diǎn)擊【File】菜單下面的【License Management】。
點(diǎn)擊【File】菜單下面的【License Management】
12.雙擊打開之前解壓后的【Keiluvision 4 C51版】文件夾
雙擊打開之前解壓后的【Keiluvision 4 C51版】
13.選中【crack】可執(zhí)行文件,鼠標(biāo)右擊選擇【以管理員身份運(yùn)行】。溫馨提示:如果在該文件夾里面沒有找到【crack】可執(zhí)行文件請(qǐng)關(guān)閉殺毒軟件和防火墻重新解壓壓縮包。
【crack】可執(zhí)行文件
14.使用快捷鍵Ctrl+C復(fù)制軟件許可證管理器中的【CID】在注冊(cè)機(jī)的【CID】框中使用快捷鍵Ctrl+V粘貼。
快捷鍵Ctrl+C復(fù)制軟件許可證管理器中的【CID】
15.點(diǎn)擊【Generate】并使用快捷鍵Ctrl+C復(fù)制上面框中生成的激活碼。
快捷鍵Ctrl+C復(fù)制軟件許點(diǎn)擊【Generate】并使用快捷鍵Ctrl+C復(fù)制上面框中生成的激活碼可證管理器中的【CID
16.在【NewLicense ID Code】框里面使用快捷鍵Ctrl+V粘貼注冊(cè)碼,然后點(diǎn)擊【添加LIC】。
在【NewLicense ID Code】框里面使用快捷鍵Ctrl+V粘貼注冊(cè)碼
17.激活成功,如果嫌激活的時(shí)間短可以換個(gè)激活碼,然后點(diǎn)擊【Close】。
激活的時(shí)間短可以換個(gè)激活碼,然后點(diǎn)擊【Close】
18.雙擊打開之前解壓后的【Keiluvision4 C51版】文件夾里面的【Keil uVision4漢化補(bǔ)丁】文件夾。
雙擊打開之前解壓后的【Keiluvision4 C51版】文件夾里面的【Keil uVision4漢化補(bǔ)丁】
19.選中所有文件,鼠標(biāo)右擊選擇【復(fù)制】。
選中所有文件,鼠標(biāo)右擊選擇【復(fù)制】
20.打開軟件的安裝目錄,雙擊打開【UV4】文件夾。
打開軟件的安裝目錄,雙擊打開【UV4】文件夾
21.在空白處鼠標(biāo)右擊選擇【粘貼】。
在空白處鼠標(biāo)右擊選擇【粘貼】
22.勾選【對(duì)于所有沖突執(zhí)行此操作】然后點(diǎn)擊【復(fù)制和替換】。
勾選【對(duì)于所有沖突執(zhí)行此操作】然后點(diǎn)擊【復(fù)制和替換】
23.在桌面雙擊打開【KeiluVision4】。
在桌面雙擊打開【KeiluVision4】
24.安裝完成。
安裝完成