嵌入式程序設(shè)計(jì)基礎(chǔ)GCC編譯過程CC交叉編譯器armelfgcc工程管理器_第1頁
嵌入式程序設(shè)計(jì)基礎(chǔ)GCC編譯過程CC交叉編譯器armelfgcc工程管理器_第2頁
嵌入式程序設(shè)計(jì)基礎(chǔ)GCC編譯過程CC交叉編譯器armelfgcc工程管理器_第3頁
嵌入式程序設(shè)計(jì)基礎(chǔ)GCC編譯過程CC交叉編譯器armelfgcc工程管理器_第4頁
嵌入式程序設(shè)計(jì)基礎(chǔ)GCC編譯過程CC交叉編譯器armelfgcc工程管理器_第5頁
已閱讀5頁,還剩196頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

嵌入式程序設(shè)計(jì)基礎(chǔ)GCC編譯過程CC交叉編譯器armelfgcc工程管理器第1頁/共202頁GNU集成編譯環(huán)境GCC(GNUCompilerCollection)是一種面向嵌入式領(lǐng)域、支持多種編程語言、支持多種CPU的交叉編譯工具。本章主要介紹:GCC編譯過程C/C++交叉編譯器arm-elf-gcc交叉匯編器arm-elf-as交叉連接器arm-elf-ld工程管理器make匯編語言編程混合編程第2頁/共202頁3.1GNUGCC簡介GNUGCC是一套面向嵌入式領(lǐng)域的交叉編譯工具,支持多種編程語言、多種優(yōu)化選項(xiàng)并且能夠支持分步編譯、支持多種反匯編方式、支持多種調(diào)試信息格式,目前支持X86、ARM7、StrongARM、PPC4XX、MPC8XX、MIPSR3000等多種CPU。第3頁/共202頁GNUGCC的基本功能包括:輸出預(yù)處理后的C/C++源程序(展開頭文件和替換宏)輸出C/C++源程序的匯編代碼輸出二進(jìn)制目標(biāo)文件生成靜態(tài)庫生成可執(zhí)行程序轉(zhuǎn)換文件格式第4頁/共202頁3.1.1GCC組成1.C/C++交叉編譯器arm-elf-gcc arm-elf-gcc是編譯的前端程序,它通過調(diào)用其他程序來實(shí)現(xiàn)將程序源文件編譯成目標(biāo)文件的功能。 編譯時(shí),它首先調(diào)用預(yù)處理程序(cpp)對輸入的源程序進(jìn)行處理,然后調(diào)用cc1將預(yù)處理后的程序編譯成匯編代碼,最后由arm-elf-as將匯編代碼編譯成目標(biāo)代碼。

arm-elf-gcc具有豐富的命令選項(xiàng),可以控制編譯的各個(gè)階段,滿足用戶的各種編譯需求。第5頁/共202頁2.

匯編器arm-elf-asarm-elf-as將匯編語言程序轉(zhuǎn)換為ELF(ExecutableandLinkingFormat,執(zhí)行時(shí)鏈接文件格式)格式的可重定位目標(biāo)代碼,這些目標(biāo)代碼同其它目標(biāo)模塊或函數(shù)庫易于定位和鏈接。arm-elf-as產(chǎn)生一個(gè)交叉參考表和一個(gè)標(biāo)準(zhǔn)的符號表,產(chǎn)生的代碼和數(shù)據(jù)能夠放在多個(gè)區(qū)(Section)中。第6頁/共202頁3.連接器arm-elf-ldarm-elf-ld根據(jù)鏈接定位文件Linkcmds中的代碼區(qū)、數(shù)據(jù)區(qū)、BSS區(qū)和棧區(qū)等定位信息,將可重定位的目標(biāo)模塊鏈接成一個(gè)單一的、絕對定位的目標(biāo)程序。該目標(biāo)程序是ELF格式,并且可以包含調(diào)試信息。arm-elf-ld會產(chǎn)生一個(gè)內(nèi)存映象文件Map.txt,該文件顯示所有目標(biāo)模塊、區(qū)和符號的絕對定位地址。它也產(chǎn)生交叉參考列表,顯示參考每個(gè)全局符號的目標(biāo)模塊。第7頁/共202頁arm-elf-ld支持將多個(gè)目標(biāo)模塊鏈接成一個(gè)單一的、絕對定位的目標(biāo)程序,也能夠依此對目標(biāo)模塊進(jìn)行鏈接,這個(gè)特性稱為增量鏈接(IncrementalLinking)。假如輸入文件是一個(gè)函數(shù)庫,arm-elf-ld會自動從函數(shù)庫裝載被其它目標(biāo)模塊參考的函數(shù)模塊。arm-elf-ld與其它鏈接程序相比,能提供更有幫助的診斷信息。許多鏈接器遇到第一個(gè)錯(cuò)誤即放棄鏈接,而arm-elf-ld只要有可能都繼續(xù)執(zhí)行,幫助用戶識別其它錯(cuò)誤,有時(shí)甚至能獲得輸出代碼。第8頁/共202頁4.庫管理器arm-elf-ararm-elf-ar將多個(gè)可重定位的目標(biāo)模塊歸檔為一個(gè)函數(shù)庫文件。采用函數(shù)庫文件,應(yīng)用程序能夠從該文件中自動裝載要參考的函數(shù)模塊,同時(shí)將應(yīng)用程序中頻繁調(diào)用的函數(shù)放入函數(shù)庫文件中,易于應(yīng)用程序的開發(fā)管理。arm-elf-ar支持ELF格式的函數(shù)庫文件.第9頁/共202頁5.工程管理器MAKE Make是用于自動編譯、鏈接程序的實(shí)用工具,使用make后就不需要手工的編譯每個(gè)程序文件。要使用make,首先要編寫makefile。

Makefile描述程序文件之間的依賴關(guān)系,并提供更新文件的命令。在一個(gè)程序中,可執(zhí)行文件依賴于目標(biāo)文件,而目標(biāo)文件依賴于源文件。如果makefile文件存在,每次修改完源程序后,用戶通常所需要做的事情就是在命令行敲入“make”,然后所有的事情都由make來完成。第10頁/共202頁6.其他實(shí)用程序目標(biāo)文件格式轉(zhuǎn)換工具arm-elf-objcopy支持的文件格式有H-record、S-record、ABS、BIN、COFF、ELF。例如,它能夠?qū)LF格式文件轉(zhuǎn)換為其它格式的文件,如intelH-record格式、MotorolaS-record等。arm-elf-nm程序用于顯示文件中的符號信息。第11頁/共202頁3.1.2GCC編譯程序的基本過程GCC編譯程序的基本過程如下:arm-elf-gcc根據(jù)輸入文件的后綴來確定文件的類型,然后根據(jù)用戶的編譯選項(xiàng)(包括優(yōu)化選項(xiàng)、調(diào)試信息選項(xiàng)等)將其編譯成相應(yīng)的匯編臨時(shí)文件(后綴為.s);arm-elf-as將該匯編文件編譯成目標(biāo)文件(后綴為.o);arm-elf-ld根據(jù)用戶的鏈接選項(xiàng)(包括指定鏈接命令文件等)將目標(biāo)文件和各種庫鏈接起來生成可執(zhí)行文件。圖3-1展示了該編譯過程:第12頁/共202頁3.2C/C++交叉編譯器arm-elf-gcc3.2.1概述arm-elf-gcc是編譯的前端程序,它通過調(diào)用其他程序來實(shí)現(xiàn)將程序源文件編譯成目標(biāo)文件。編譯時(shí)它首先調(diào)用預(yù)處理程序(cpp)對輸入的源程序進(jìn)行處理;然后調(diào)用cc1將預(yù)處理后的程序編譯成匯編代碼;最后由arm-elf-as將匯編代碼編譯成目標(biāo)代碼。arm-elf-gcc具有豐富的命令選項(xiàng),控制編譯的各個(gè)階段,滿足用戶的各種編譯需求

第13頁/共202頁1.命令格式arm-elf-gcc[options]file…在命令arm-elf-gcc后面跟一個(gè)或多個(gè)選項(xiàng),選項(xiàng)間用空格隔開,然后跟一個(gè)或多個(gè)目標(biāo)文件。例如,將test.c編譯成目標(biāo)文件test.o并且生成調(diào)試信息:arm-elf-gcc–g–c–otest.otest.c第14頁/共202頁2.命令選項(xiàng)列表輸出控制選項(xiàng):-c 將輸入的源文件編譯成目標(biāo)文件-S 將C/C++文件生成匯編文件-ofile將輸出內(nèi)容存于文件file-pipe在編譯的不同階段之間采用管道通訊方式-v 打印出編譯過程中執(zhí)行的命令-xlanguage 說明文件的輸入類型為language第15頁/共202頁C語言選項(xiàng):-ansi

支持所有ANSIC程序警告選項(xiàng):-w關(guān)閉所有警告-Wall打開所有警告-Wimplicit如果有隱含申明,顯示警告信息-Wno-implicit不顯示對隱含申明的警告調(diào)試選項(xiàng):-g在文件中產(chǎn)生調(diào)試信息(調(diào)試信息的文件格式有stabs、COFF、XCOFF、DWARF)第16頁/共202頁優(yōu)化選項(xiàng):-O0不優(yōu)化-O1一級優(yōu)化-O2二級優(yōu)化-O3三級優(yōu)化預(yù)處理選項(xiàng):-E運(yùn)行C的預(yù)處理器-C在運(yùn)用-E進(jìn)行預(yù)處理時(shí)不去掉注釋-Dmacro定義宏macro為1-Dmacro=defn定義宏macro為defn第17頁/共202頁匯編選項(xiàng):-Wa,option

將選項(xiàng)option傳遞給匯編器搜索路徑選項(xiàng):-Idir設(shè)置搜索路徑為dir-I-指定只對#include"file",有效的頭文件搜索目錄第18頁/共202頁3.源文件類型的識別arm-elf-gcc能夠自動根據(jù)文件名后綴識別文件類型.文件名后綴和文件類型的對應(yīng)關(guān)系如下:*.c ——C源文件*.i ——經(jīng)過預(yù)處理后的C源文件*.h ——C頭文件*.ii ——經(jīng)過預(yù)處理后的C++源文件*.cc ——C++源文件*.cxx ——C++源文件*.cpp ——C++源文件*.C ——C++源文件*.s ——不需要預(yù)處理的匯編文件*.S ——需要預(yù)處理的匯編文件第19頁/共202頁此外,用戶可通過-xlanguage說明文件的輸入類型,此時(shí)可以不用以上的后綴規(guī)則。-xlanguage其中的language可為:c ——C源文件c++ ——C++源文件c-header ——C頭文件cpp-output ——經(jīng)過預(yù)處理后的C源文件c++-cpp-output——經(jīng)過預(yù)處理后的C++源文件assembler ——不需要預(yù)處理的匯編文件assembler-with-cpp——需要預(yù)處理的匯編文件例如,編譯一個(gè)不需要預(yù)處理的C程序:arm-elf-gcc–c–g–x cpp-outputtest.c-xnone如果-x后面未跟任何參數(shù),則按照文件的后綴名做相應(yīng)處理。第20頁/共202頁3.2.2命令使用1.輸出文件名的指定-ofile將輸出內(nèi)容存于文件file,僅適用于只有一個(gè)輸出文件時(shí)。例如,將test.c編譯成匯編程序并存放于文件test.txt:arm-elf-gcc–S–otest.txttest.c第21頁/共202頁2.目標(biāo)文件的生成

-c將輸入的源文件編譯成目標(biāo)文件。例如,將test.c編譯成test.o:arm-elf-gcc–c–otest.otest.c3.將C/C++文件生成匯編文件

-S將C/C++文件生成匯編文件。例如:將test.c編譯生成匯編文件test.s:arm-elf-gcc–S–otest.stest.c第22頁/共202頁4.預(yù)處理文件的生成-E只對源文件進(jìn)行預(yù)處理并且缺省輸出到標(biāo)準(zhǔn)輸出。例如,對test.c進(jìn)行預(yù)處理并將結(jié)果輸出到屏幕:arm-elf-gcc–Etest.c例如,對test.c進(jìn)行預(yù)處理并將結(jié)果輸出到文件test.txt:arm-elf-gcc–E–otest.txttest.c第23頁/共202頁5.設(shè)置頭文件搜索路徑頭文件的引用有兩種形式:一種是#include“filename”,一種是#include<filename>。

前一種形式的路徑搜索順序是:當(dāng)前目錄、指定的搜索路徑;后一種形式只搜索指定路徑。第24頁/共202頁-Idir將目錄dir添加到頭文件搜索目錄列表的第一項(xiàng)。通過此選項(xiàng)可以使用戶頭文件先于系統(tǒng)頭文件被搜索到。如果同時(shí)用-I選項(xiàng)添加幾個(gè)目錄,目錄被搜索時(shí)的優(yōu)先級順序?yàn)閺淖蟮接?。例如,編譯test.c,在當(dāng)前目錄和/include中搜索test.c所包含的頭文件:arm-elf-gcc–I./–I/include–ctest.c第25頁/共202頁-I--I-以前用-I指定的頭文件搜索目錄只對#include“file”有效,對#include<file>無效;-I-以后指定的頭文件搜索目錄對以上兩種形式的頭文件都有效。此外,-I-會禁止對當(dāng)前目錄的隱含搜索,不過用戶可以通過使用“-I.”使能對當(dāng)前目錄的搜索。第26頁/共202頁例如:在需要編譯的test.c文件對頭文件的引用有:

#include<file1.h> #include“file2.h” #include“file3.h”

其中,file1.h在目錄/include/test下,file2.h在/include下,file3.h在當(dāng)前目錄下。在以下命令行中,只能搜索到file2.h,而不能搜索到file1.h:arm-elf-gcc–I./include/test–I––I./include–ctest.c第27頁/共202頁而在以下命令行中,可以搜索到需要的兩個(gè)頭文件file1.h和file2.h:

arm-elf-gcc–I––I./include–I./include/test–ctest.c如果要搜索到file3.h,必須要添加對當(dāng)前目錄的搜索:

arm-elf-gcc–I––I.–I./include–I./include/test–ctest.c實(shí)質(zhì)上,上述編譯命令等價(jià)于:arm-elf-gcc–I.–I./include–I./include/test–ctest.c

arm-elf-gcc–I./include–I./include/test–ctest.c第28頁/共202頁6.控制警告產(chǎn)生用戶可以使用以-W開頭的不同選項(xiàng)對特定警告進(jìn)行設(shè)定。對于每種警告類型都有相應(yīng)以-Wno-開始的選項(xiàng)關(guān)閉警告。例如:如果有隱含申明,顯示警告信息:arm-elf-gcc–c–Wimplicittest.c不顯示對隱含申明的警告:arm-elf-gcc–c–Wno–implicittest.c常用的警告選項(xiàng)有:-w

關(guān)閉所有警告信息。-Wall

打開所有警告信息。第29頁/共202頁7.實(shí)現(xiàn)優(yōu)化優(yōu)化的主要目的是使編譯生成的代碼的尺寸更小、運(yùn)行速度更快。但是在編譯過程中隨著優(yōu)化級別的升高,編譯器會相應(yīng)消耗更多時(shí)間和內(nèi)存,而且優(yōu)化生成代碼的執(zhí)行順序和源代碼有一定出入,因此優(yōu)化選項(xiàng)更多地用于生成固化代碼,而不用于生成調(diào)試代碼。第30頁/共202頁arm-elf-gcc支持多種優(yōu)化選項(xiàng),總體上劃分為三級優(yōu)化:-O1

可以部分減小代碼尺寸,對運(yùn)行速度有一定的提高。較多地使用了寄存器變量,提高指令的并行度。-O2

除了解循環(huán)、函數(shù)插裝和靜態(tài)變量優(yōu)化,幾乎包含arm-elf-gcc所有優(yōu)化選項(xiàng)。一般在生成固化代碼時(shí)使用該選項(xiàng)較為適宜。-O3

包含-O2的所有優(yōu)化,并且還包含了解循環(huán)、函數(shù)插裝和靜態(tài)變量優(yōu)化。通常情況下,該級優(yōu)化生成的代碼執(zhí)行速度最快,但是代碼尺寸比-O2大一些。第31頁/共202頁8.在命令行定義宏-Dmacro

定義宏macro為1。-Dmacro=defn

定義宏macro為defn。例如:編譯test.c并且預(yù)定義宏RUN_CACHE值為1:arm-elf-gcc–c–DRUN_CACHEtest.c編譯test.c并且預(yù)定義宏RUN_CACHE值為0:arm-elf-gcc–c–DRUN_CACHE=0test.c第32頁/共202頁

3.3交叉連接器arm-elf-ld3.3.1概述arm-elf-ld根據(jù)鏈接定位文件Linkcmds中代碼段、數(shù)據(jù)段、BSS段和堆棧段等定位信息,將可重定位的目標(biāo)模塊鏈接成一個(gè)單一的、絕對定位的目標(biāo)程序,該目標(biāo)程序是ELF格式,并且可以包含調(diào)試信息。arm-elf-ld可以輸出一個(gè)內(nèi)存映象文件,該文件顯示所有目標(biāo)模塊、段和符號的絕對定位地址,它也產(chǎn)生目標(biāo)模塊對全局符號引用的交叉參考列表。第33頁/共202頁arm-elf-ld支持將多個(gè)目標(biāo)模塊鏈接成一個(gè)單一的、絕對定位的目標(biāo)程序,也能夠依次對目標(biāo)模塊進(jìn)行鏈接,這個(gè)特性稱為增量鏈接(IncrementalLinking)。

arm-elf-ld會自動從庫中裝載被調(diào)用函數(shù)所在的模塊。第34頁/共202頁1.命令格式arm-elf-ld[option]file…命令行后跟選項(xiàng)和可重定位的目標(biāo)文件名。例如:鏈接的輸入文件為demo.o,輸出文件為demo.elf,鏈接的庫為libxxx.a,生成內(nèi)存映象文件map.txt,鏈接定位文件為linkcmds,則命令如下:arm-elf-ld-Mapmap.txt-Tlinkcmds-L./lib–odemo.elfdemo.o–lxxx第35頁/共202頁2.命令選項(xiàng)列表-eentry 指定程序入口-M 輸出鏈接信息-lar 指定鏈接庫-Ldir 添加搜索路徑-o 設(shè)置輸出文件名-Tcommandfile 指定鏈接命令文件-v 顯示版本信息-Map 制定輸出映像文件第36頁/共202頁3.3.2命令使用1.程序入口地址-eentry以符號entry作為程序執(zhí)行的入口地址,而不從默認(rèn)的入口地址開始。默認(rèn)入口地址的指定方式和其他指定方式的描述,參見3.3.3節(jié)。例如,鏈接的輸入文件為demo.o,輸出文件為demo.elf,鏈接定位文件為linkcmds,將入口地址設(shè)為_start,命令如下:arm-elf-ld–Tlinkcmds–e_start–odemo.elfdemo.o第37頁/共202頁2.輸出鏈接信息-M在標(biāo)準(zhǔn)端口打印出符號映象表和內(nèi)存分布信息。例如:鏈接的輸入文件為demo.o,輸出文件為demo.elf,在標(biāo)準(zhǔn)端口打印出符號映象表和內(nèi)存分布信息,命令如下:arm-elf-ld–M–odemo.elfdemo.o如果標(biāo)準(zhǔn)輸出設(shè)置為顯示器,運(yùn)行命令后將在顯示器上顯示內(nèi)存映象信息和符號映象表。第38頁/共202頁-Mapmapfile將鏈接的符號映象表和內(nèi)存分布信息輸出到文件mapfile里。例如:鏈接的輸入文件為demo.o,輸出文件為demo.elf,將鏈接的符號映象表和內(nèi)存分布信息輸出到文件map.txt里,命令如下:arm-elf-ld–Mapmap.txt–odemo.elfdemo.o第39頁/共202頁3.指定鏈接的庫-lar指定庫文件libar.a為鏈接的庫。可以重復(fù)使用-l來指定多個(gè)鏈接的庫。例如:鏈接的輸入文件為demo.o,指定libxxx.a為鏈接的庫,輸出文件為demo.elf,命令如下:arm-elf-ld–odemo.elfdemo.o–lxxx注意:庫的命名規(guī)則為libxxx.a,在-l指定庫名時(shí)使用的格式為-lxxx。第40頁/共202頁4.添加庫和腳本文件的搜索路徑-Ldir將dir添加到搜索路徑。搜索順序按照命令行中輸入的順序,并且優(yōu)先于默認(rèn)的搜索路徑。所有在-L添加的目錄中找到的-l指定的庫都有效。例如:鏈接的輸入文件為demo.o,輸出文件為demo.elf,將/lib添加到庫的搜索路徑,命令如下:arm-elf-ld-L./lib–odemo.elfdemo.o第41頁/共202頁5.設(shè)置輸出文件的名字-ooutput將輸出文件名字設(shè)定為output。如果不指定輸出文件名,arm-elf-ld生成文件名默認(rèn)為a.out。例如:鏈接的輸入文件為demo.o,輸出文件為demo.elf,命令如下:arm-elf-ld–odemo.elfdemo.o第42頁/共202頁3.3.3linkcmds連接命令文件arm-elf-ld的命令語言是一種描述性的腳本語言,它主要應(yīng)用于控制:有哪些輸入文件、文件的格式怎樣、輸出文件中的模塊怎樣布局、分段的地址空間怎樣分布、以及未初始化的數(shù)據(jù)段怎樣處理等。用命令語言寫成的文件(通常稱為linkcmds)具有可重用性,不必每次在命令行輸入一大堆命令選項(xiàng).并且對于不同的應(yīng)用,只需對linkcmds進(jìn)行簡單的修改就可以使用。第43頁/共202頁1.調(diào)用linkcmds首先寫一個(gè)鏈接命令文件linkcmds,然后在arm-elf-ld的命令中使用-Tlinkcmds參數(shù),就能在鏈接時(shí)自動調(diào)用linkcmds文件.例如:鏈接的輸入文件為demo.o,輸出文件為demo.elf,鏈接定位文件為linkcmds,則命令如下:arm-elf-ld–Tlinkcmds–odemo.elfdemo.o第44頁/共202頁2.編寫linkcmds(1)arm-elf-ld命令語言arm-elf-ld命令語言是一系列語句的集合,包括用簡單的關(guān)鍵字設(shè)定選項(xiàng)、描述輸入文件及其格式、命名輸出文件。其中有兩種語句對于鏈接過程起重要作用:SECTIONS語句和MEMORY語句。SECTIONS語句用于描述輸出文件中的模塊怎樣布局,MEMORY語句描述目標(biāo)機(jī)中可以用的存儲單元。第45頁/共202頁(2)表達(dá)式在linkcmds中的表達(dá)式與C語言中的表達(dá)式類似,它們具有如下的特征:表達(dá)式的值都是“unsignedlong”或者“l(fā)ong”類型常數(shù)都是整數(shù)支持C語言中的操作符可以引用或者定義全局變量可以使用內(nèi)建的函數(shù)第46頁/共202頁①整數(shù)八進(jìn)制數(shù)以‘0’開頭,例如:0234;十進(jìn)制數(shù)以非0的數(shù)字開頭,例如:567;十六進(jìn)制數(shù)以‘0x’或‘0X’開頭,例如:0x16;負(fù)數(shù)以運(yùn)算符‘-’開頭,例如:-102;以K,M為后綴分別表示以1024,1024*1024為單位,例如:var1=1K和var1=1024相等,var2=1M和var2=1024*1024相等。第47頁/共202頁②變量名以字母、下劃線和點(diǎn)開頭,可以包含任何字母、下劃線、數(shù)字、點(diǎn)和連接符。變量名不能和關(guān)鍵字一樣,如果變量名和關(guān)鍵字一樣,或者變量名中包含空格時(shí),必須將變量名包含在“”中.例如:“SECTION”=9;“withaspace”=“alsowithaspace”+10;在arm-elf-ld命令語言中,空格用于界定相鄰符號,例如:A-B表示一個(gè)變量名,而A-B表示一個(gè)減法的表達(dá)式。第48頁/共202頁③地址記數(shù)器點(diǎn)號“.”“.”是一個(gè)包含當(dāng)前輸出地址的計(jì)數(shù)器。因?yàn)椤?”總是表示某個(gè)輸出段的地址,所以總是和表達(dá)式一起在SECTIONS命令中出現(xiàn)。“.”可以在任何一般符號出現(xiàn)的地方出現(xiàn),對“.”的賦值將引起計(jì)數(shù)器所指位置的移動,而計(jì)數(shù)器位置不能反向移動。第49頁/共202頁例如:SECTIONS { output:

{ file1(.text) .=.+1000;

file2(.text) .+=1000;

file3(.text) }=0x1234;

}在左面的例子中,在file1(.text)與file2(.text)之間被空出了1000個(gè)字節(jié)的空間,file2(.text)與file3(.text)之間也被空出了1000個(gè)字節(jié)的空間,而0x1234為該分段的空間空隙的填充值。第50頁/共202頁可以將“.”賦給變量;也可以對“.”賦值。例如:

data_start=.;

.=.+2000;第51頁/共202頁(3)linkcmds的結(jié)構(gòu)linkcmds文件主要由四個(gè)部分組成:程序入口說明:用于指定程序運(yùn)行時(shí)所需要執(zhí)行的第一條指令的地址。程序頭說明:生成目標(biāo)文件類型為ELF,可以指定詳細(xì)的程序頭信息。內(nèi)存布局的說明:用于規(guī)劃內(nèi)存的布局,將內(nèi)存空間劃分為不同的部分。分段的分步說明:詳細(xì)指明各個(gè)分段的構(gòu)成以及分段的定位地址和裝載地址。

其中①和④的部分不能被省略。第52頁/共202頁(4)對程序入口的說明arm-elf-ld命令語言有一條特定命令用于指定輸出文件中第一條可執(zhí)行指令,即程序的入口點(diǎn)。該命令格式如下:

ENTRY(symbol)其中ENTRY是保留字,symbol表示程序的入口地址,通常是用一個(gè)全局地址標(biāo)號(label)來表示入口地址。例如,在程序中的開始地方有一標(biāo)號:.globaldemo_startdemo_start:movl$_stack_top,%esp……第53頁/共202頁那么在linkcmds中可以用下面的方式說明程序的入口:ENTRY(demo_start);該命令可以作為單獨(dú)的一條命令放在linkc–mds的任何位置,也可以放在SECTIONS內(nèi)關(guān)于段的定義部分,都對布局起作用。指定入口地址的方式還有很多,現(xiàn)在按優(yōu)先級遞減的順序描述如下:用‘-e’選項(xiàng)指定入口地址在linkcmds里用ENTRY(symbol)指令變量start的值,如果有變量start.text段第一字節(jié)的地址,如果存在0地址第54頁/共202頁(5)對程序頭的說明ELF格式文件需要使用程序頭,它用于描述程序應(yīng)該怎么被裝入內(nèi)存。在默認(rèn)情況下,arm-elf-ld可以自己生成一個(gè)程序頭,用戶也可以用PHDRS自己編寫程序頭,當(dāng)運(yùn)用該命令時(shí),arm-elf-ld不會生成默認(rèn)的程序頭。注意:如果沒有特殊要求,建議用戶不要自己寫程序頭。第55頁/共202頁P(yáng)HDRS{nametype[FILEHDR][PHDRS][AT(address)] [FLAGS(flags)];}其中PHDRS、FILEHDR、AT、FLAGS都是關(guān)鍵字。name表示段(Segment)的名字,而該段(Segment)裝入的內(nèi)容由SECTIONS中對分段(Section)的描述決定,例如:SECTIONS{…secnamestartBLOCK(align)(NOLOAD):AT(ldadr){contents}>region:phdr=fill…}第56頁/共202頁因此PHDRS中的name應(yīng)該和SECTIONS中的phdr保持一致。type表示段的類型,可以為下面描述的任意一種類型(括號內(nèi)表示關(guān)鍵字的值):PT_NULL(0)——空程序頭PT_LOAD(1)——描述一個(gè)可裝入的段PT_DYNAMIC(2)——表示包含動態(tài)鏈接信息的段PT_INTERP(3)——表示該段包含程序解釋器的名字PT_NOTE(4)——表示包含注釋信息的段PT_SHLIB(5)——一個(gè)保留的程序頭PT_PHDR(6)——表示該段可能包含程序頭的描述信息expression——用數(shù)值表示一個(gè)程序頭的類型,該類型沒有對應(yīng)的關(guān)鍵字第57頁/共202頁FILEHDR表示在段中包含ELF文件頭的信息。PHDRS表示在段中還要包含程序頭本身的信息。[AT(address)]表示該段的起始地址,若在SECTIONS中也有AT時(shí),程序頭中定義的AT優(yōu)先。例如:

PHDRS { headersPT_PHDRPHDRS; interpPT_INTERP; textPT_LOADFILEHDRPHDRS; dataPT_LOAD; dynamicPT_DYNAMIC; }第58頁/共202頁SECTIONS{.=SIZEOF_HEADERS;.interp:{*(.interp)}:text:interp.text:{*(.text)}:text.rodata:{*(.rodata)}/*defaultsto:text*/....=.+0x1000;/*movetoanewpageinmemory*/.data:{*(.data)}:data.dynamic:{*(.dynamic)}:data:dynamic...}第59頁/共202頁在上面的例子中,定義了5個(gè)段:headers申明一個(gè)程序頭段;interp申明一個(gè)段,段中包含了程序解釋器的名字;text申明一個(gè)可被下載的段,并且包含了文件的頭信息和各段的信息;data申明一個(gè)可被下載的段;dynamic申明一個(gè)包含動態(tài)鏈接信息的段;第60頁/共202頁在SECTIONS中可以看到,有的分段同時(shí)屬于兩個(gè)段,實(shí)質(zhì)上是這兩個(gè)段占用同一空間。.rodata也屬于.text段是由于它的上一個(gè)分段屬于.text段,而.rodata又沒有指明歸屬段。注意:如果沒有特殊要求,建議用戶不要自己寫程序頭。第61頁/共202頁(6)對內(nèi)存布局的說明arm-elf-ld的默認(rèn)配置允許將輸出程序定位到任何可用內(nèi)存。用戶也可以用MEMORY命令對內(nèi)存進(jìn)行配置。MEMORY命令可以定義目標(biāo)機(jī)內(nèi)存段的位置和大小,當(dāng)裝載的程序塊大小超出指定的內(nèi)存段大小時(shí),arm-elf-ld會提示出錯(cuò),而不會自動尋找可用的內(nèi)存段,這樣可以避免內(nèi)存分配錯(cuò)誤。第62頁/共202頁定義內(nèi)存段的方式:MEMORY {name(attr):ORIGIN=origin,LENGTH=len…}name表示內(nèi)存段的名字,可以使用任何變量名,但是不能和已有變量名、文件名和分段名(sectionname)沖突。attr沒有實(shí)際的用途,可省略。origin(可簡寫為:org或者o)表示內(nèi)存段的起始位置。Length(可簡寫為:len或者l)表示內(nèi)存段的長度.第63頁/共202頁MEMORY{rom:ORIGIN=0x3f80000,LENGTH=512Kram:org=0,l=1M}

表示定義了兩個(gè)內(nèi)存段:rom內(nèi)存段,起始地址為0x3f80000,長度為512K;ram內(nèi)存段,起始地址為0,長度為1M。第64頁/共202頁(7)對分段的說明SECTIONS命令控制如何正確地將輸入分段定位到輸出分段,包括在輸出文件中的順序,和輸入分段在輸出分段中的定位。如果不用SECTIONS命令,arm-elf-ld將對每個(gè)輸入分段生成相同名字的輸出分段,分段的順序由輸入文件中遇到的分段的先后順序決定。第65頁/共202頁SECTIONS命令的格式:SECTIONS{...secnamestartBLOCK(align)(NOLOAD):AT(ldadr){contents}>region:phdr=fill...}其中secname和contents都是必須有的。secname表示輸出分段的名字,受輸出格式的限制,一些輸出格式對段名有限制,例如a.out只允許.text,.data或.bss的分段名存在.另外arm-elf-ld不輸出空的分段。

第66頁/共202頁start,BLOCK(align),(NOLOAD),AT(ldadr),>region,:phdr,=fill都是可選項(xiàng):Start

表示分段的起始地址,該地址被稱為重定位地址;BLOCK(align)表示分段以align對齊;(NOLOAD)表示該段不能被裝載;AT(ldadr)

表示該分段裝入的起始地址為ldadr,當(dāng)沒有該參數(shù)時(shí)分段的裝入地址和重定位地址相同;第67頁/共202頁region

表示該分段地址空間在region所定義的范圍內(nèi),region就是在MEMORY命令中定義的內(nèi)存段名字;:phdr

表示該分段的裝載地址空間在phdr定義的范圍內(nèi),phdr就是在程序頭中定義的段名字;=fill

表示在該分段的空間空隙的填充值。第68頁/共202頁contents表示具體的分段內(nèi)容,主要描述該輸出分段中包含有輸入文件中的哪些分段。常見的分段名如下:.text ——表示代碼段.data ——初始化了的數(shù)據(jù)段.bss ——未初始化的數(shù)據(jù)段.rodata ——不可寫的數(shù)據(jù)段COMMON ——未初始化的數(shù)據(jù)段第69頁/共202頁用戶在匯編語言程序中可以自定義分段名,如:mycode、mydata之類。在C語言文件編譯成目標(biāo)文件后,通常包含有.text、.data、COMMON、.rodata段。其中.rodata表示不可寫的數(shù)據(jù)段,通常包含在C語言程序中定義的一些常量,如constcharversion_string[]=“Lambdax86/fpm”之類。第70頁/共202頁contents可用格式:filenamefilename(section)filename(section,section,…)filename(sectionsection…)和針對所有文件的:*(section)*(section,section,…)*(sectionsection…)第71頁/共202頁

如果在用“*”指定所有文件時(shí),以前已經(jīng)使用filename指定過一些文件,那么“*”表示剩下的文件:

filename(COMMON) *(COMMON) 指定輸入文件中名為COMMON的分段里未初始化的數(shù)據(jù)在輸出分段中的位置。 下面舉例說明contents中的具體內(nèi)容及編寫方法。第72頁/共202頁下面舉例說明contents中的具體內(nèi)容及編寫方法。例如:

.text0: {file1.ofile2.ofile3.o}

表示將file1.o、file2.o、file3.o中的所有分段都放在輸出文件的.text段中。例如:

.text0: { *(.text); }

表示將所有輸入文件中的.text分段都放在輸出文件的.text段中。第73頁/共202頁例如:

.text0: { file1.o(.text); file2.o(.text); file3.o(.text); }

表示將file1.o、file2.o、file3.o中的.text段都放在輸出文件的.text段中。第74頁/共202頁例如:text1: { file1.o(.text); }text2: { *(.text); }

表示將file1.o中的.text段放在輸出文件的text1段中,而其他輸入文件的.text段都放在輸出文件的text2段。第75頁/共202頁(8)注釋 arm-elf-ld語言中的注釋和C語言一樣。

例如:/*comments*/第76頁/共202頁3.4工程管理器MAKE3.4.1概述make是用于自動編譯、鏈接程序的實(shí)用工具。使用make后就不需要手工編譯每個(gè)程序文件。第77頁/共202頁要使用make,首先要編寫makefile,makefile描述程序文件之間的依賴關(guān)系以及提供更新文件的命令。典型地,在一個(gè)程序中,可執(zhí)行文件依賴于目標(biāo)文件,而目標(biāo)文件依賴于源文件。

如果makefile文件存在,每次修改完源程序后,用戶通常所需要做的事情就是在命令行敲入“make”,然后所有的事情都由make來完成。

第78頁/共202頁1.命令格式make[-fmakefile][option][target]…

make命令后跟-f選項(xiàng),指定makefile的名字為makefile;option表示make的一些選項(xiàng);target是make指定的目標(biāo),在3.4.3將詳細(xì)說明。例如:makefile的名字是my_hello_make:

make–fmy_hello_make第79頁/共202頁2.命令選項(xiàng)列表-f 指定makefile-e 使環(huán)境變量優(yōu)先于makefile的變量-Idir 設(shè)定搜索目錄-i 忽略make過程中所有錯(cuò)誤-n 只顯示執(zhí)行過程,而不真正執(zhí)行-r 使隱含規(guī)則無效-w 顯示工作目錄-Cdir 讀取makefile設(shè)置的工作目錄-s 不顯示執(zhí)行的命令第80頁/共202頁3.4.2

命令使用

makefile文件用來告訴make需要做的事情,通常指怎樣編譯、怎樣鏈接一個(gè)程序。以C語言程序?yàn)槔?在用make重新編譯的時(shí)候,如果一個(gè)頭文件已被修改,則包含這個(gè)頭文件的所有C源代碼文件都必須被重新編譯。而每個(gè)目標(biāo)文件都與C的源代碼文件有關(guān),如果有源代碼文件被修改過,則所有目標(biāo)文件都必須被重新鏈接生成最后的結(jié)果。編寫一個(gè)makefile將在3.4.3節(jié)詳細(xì)介紹。第81頁/共202頁1.指定makefile-fmakefile用該選項(xiàng)指定makefile的名字為makefile。如果make中多次使用-f指定多個(gè)makefile,則所有makefile將鏈接起來作為最后的makefile。如果不指定makefile,make默認(rèn)的makefile依次為“makefile”、“Makefile”。例如:make–fmy_hello_make第82頁/共202頁2.使環(huán)境變量優(yōu)先于makefile文件中的變量-e使環(huán)境變量優(yōu)先于makefile文件中的變量。例如:

make–e第83頁/共202頁3.指定包含文件的搜索路徑-Idir指定在解析makefile文件中的.include時(shí)的搜索路徑為dir。如果有多個(gè)路徑,將按輸入順序依次查找。例如:make–I/include/mk第84頁/共202頁4.忽略錯(cuò)誤-i忽略make執(zhí)行過程中的所有錯(cuò)誤。例如:

make–i5.顯示命令的執(zhí)行過程-n只顯示命令的執(zhí)行過程而不真正執(zhí)行。例如:

make–n第85頁/共202頁6.使隱含規(guī)則無效-r使make的隱含規(guī)則無效,清除后綴名規(guī)則中默認(rèn)的后綴清單。例如:

make–r7.顯示執(zhí)行過程中的工作目錄-w顯示make執(zhí)行過程中的工作目錄。例如:

make–w第86頁/共202頁8.讀取makefile文件前設(shè)置工作目錄-Cdir在讀取makefile文件以前將工作目錄改變?yōu)閐ir,完成make后改回原來的目錄。如果在一次make中使用多個(gè)-C選項(xiàng),每個(gè)選項(xiàng)都和前面一個(gè)有關(guān)系?!?Cdir0/-Cdir1”與“-Cdir0/dir1”等價(jià).例如:

make–Cbsp第87頁/共202頁9.不顯示所執(zhí)行的命令-s運(yùn)行make時(shí)用選項(xiàng)-s可以不顯示執(zhí)行的命令,只顯示生成的結(jié)果文件。例如:

make–s第88頁/共202頁3.4.3編寫一個(gè)makefile1.makefile的結(jié)構(gòu)makefile文件包含:顯式規(guī)則隱含規(guī)則變量定義指令注釋第89頁/共202頁2.編寫makefile中的規(guī)則makefile中規(guī)則的格式如下:

targets:dependencies command …

或者

targets:dependencies;command command …targets

指定目標(biāo)名,通常是一個(gè)程序產(chǎn)生的目標(biāo)文件名,也可能是執(zhí)行一個(gè)動作的名字,名字之間用空格隔開。dependency

描述產(chǎn)生target所需的文件,一個(gè)target通常依賴于多個(gè)mand

用于指定該規(guī)則的命令。注意:command必須以TAB鍵開頭。如果某一行過長可以分作兩行,用‘\’連接。第90頁/共202頁例如:smcinit:smc.oconfig.oarm-elf-ar–ruvs–osmcinit.asmc.oconfig.osmc.o:smc.cinclude.harm-elf-gcc–c–osmc.osmc.cconfig.o:config.cinclude.harm-elf-gcc–c–oconfig.oconfig.cclean:rm*.o表示目標(biāo)名的有smcinit、smc.o、config.o。smcinit依賴于smc.o和config.o,而smc.o又依賴于smc.c和include.h,config.o依賴于config.o和include.h.各目標(biāo)分別由命令arm-elf-ar–ruvs–osmcinit.asmc.oconfig.o;arm-elf-gcc–c–osmc.osmc.c;arm-elf-gcc–c–oconfig.oconfig.c來生成。clean為一動作名,刪除所有后綴為.o的文件。第91頁/共202頁3.make調(diào)用makefile中的規(guī)則在默認(rèn)情況下,make運(yùn)行不是以“.”開頭的第一條規(guī)則。在上面的例子中,make默認(rèn)執(zhí)行的是規(guī)則smcinit,此時(shí)只需要輸入命令:makemake將讀入makefile,然后執(zhí)行第一條規(guī)則,例子中該規(guī)則是鏈接目標(biāo)文件生成庫,因此必須執(zhí)行規(guī)則smcinit依賴的規(guī)則smc.o和config.o。在執(zhí)行過程中將自動更新他們所依賴的文件。有些規(guī)則不是被依賴的規(guī)則,需要make指定才能被運(yùn)行,如上面的例子中的clean規(guī)則可以這樣執(zhí)行:makeclean這兩種方式的結(jié)果一樣。只是第一種方式?jīng)]指明目標(biāo)名,第二種方式指明了目標(biāo)名。第92頁/共202頁4.設(shè)置makefile中文件的搜索路徑在makefile中,可以通過給VPATH賦值來設(shè)置規(guī)則中目標(biāo)文件和依賴文件的搜索目錄。make首先搜索當(dāng)前目錄,如果未找到依賴的文件,make將按照VPATH中給的目錄依次搜索。VPATH對makefile中所有文件都有效。例如:demo.o:demo.cdemo.hdemo.c在目錄//c/demo/中,demo.h在目錄//c/demo/head/中,則可以給VPATH變量賦值:VPATH:=//c/demo//c/demo/head或者VPATH:=//c/demo://c/demo/head也可以使用指令vpath,與VAPTH在使用上的區(qū)別是:vpath可以給不同類文件指定不同的搜索目錄。%.o表示所有以.o結(jié)尾的子串。第93頁/共202頁vpath%.c//c/demovpath%.h//c/demo/headvpath%.c——表示清除所有vpath對%.c設(shè)置的搜索目錄vpath——表示清除所有以前用vpath設(shè)置的搜索目錄這兩種方式的效果是一樣的,但是后一種要明確一些。這樣make就會根據(jù)VPATH或者vpath來搜索相應(yīng)的依賴文件。第94頁/共202頁5.如何定義變量為了簡化makefile以及減少不必要的錯(cuò)誤,可以用變量的形式來代表目標(biāo)文件名或字符串,在需要使用時(shí)直接調(diào)用變量。在makefile中變量可以被這樣定義:

CC=arm-elf-gcc AS:=arm-elf-as AR=arm-elf-ar LIBPATH:=./lib第95頁/共202頁從上面的定義中可以看出,有兩種定義變量的形式:變量名=值變量名:=值兩者的不同點(diǎn)在于,前者定義的變量是在被用到時(shí)才取它的值,而后者則是在定義變量或者給它賦值時(shí)就確定了它的值。第96頁/共202頁例如:

var1=hellofirst var2=${var1} var1=hellosecond test_echo:

echo${var2}執(zhí)行的結(jié)果是顯示:hellosecond var1=hellofirst var2:=${var1} var1=hellosecond test_echo:

echo${var2}執(zhí)行的結(jié)果是顯示:hellofirst第97頁/共202頁例如:var1=hellofirstvar1=${var1}andsecondecho_test:echo${var1}會陷入死循環(huán)中。var1:=hellofirstvar1:=${var1}andsecondecho_test:echo${var1}會顯示:hellofirstandsecond第98頁/共202頁6.引用變量有兩種方式:${VarName}$(VarName)

兩種方式的效果一樣。VarName表示變量名。第99頁/共202頁7.make提供的常用變量$@——表示目標(biāo)名$^——表示所有的依賴文件$<——第一個(gè)依賴文件例如:demo.o:demo.cdemo.h${CC}${CFLAGS}$<-o$@$<的值為demo.c,$@的值為demo.o,而$^的值為demo.cdemo.h。第100頁/共202頁8.make里的常用函數(shù)函數(shù)的使用方式有兩種:$(functionarguments)${functionarguments}常用的函數(shù)有:(1)$(substfrom,to,text)將字text中的from子串替換為to子串。例如:STR:=$(substIam,Heis,Iamanengneer)與STR:=Heisanengneer相同。第101頁/共202頁(2)$(patsubstpattern,replacement,text)按模式pattern替換text中的字串。例如:

OBJS=init.omain.ostring.o STR:=$(patsubst%.o,%.c,${OBJS}) STR的值為:init.cmain.cstring.c%.o表示所有以.o結(jié)尾的子串。$(wildcardpattern...)表示與pattern相匹配的所有文件。例如:在當(dāng)前目錄中有文件init.c、main.c和string.c:

SRCS:=$(wildcard*.c)則SRCS的值為init.cmain.cstring.c第102頁/共202頁9.隱含規(guī)則隱含規(guī)則是指由make自定義的規(guī)則,常用的有:由*.c的文件生成*.o的文件由*.s的文件生成*.o的文件 例如,下面是某makefile的一部分:

CC=arm-elf-gcc AS=arm-elf-as LD=arm-elf-ld CFLAGS=-c-ansi-nostdinc-I--I./ ASFLAGS= LDFLAGS=-Mapmap.txt-N-Tlinkcmds-L./lib第103頁/共202頁 OBJS=i386ex-start.oi386ex-get-put-char.oi386ex-io.o OBJCOPY=arm-elf-objcopy OBJCOPYFLAG=-Oihex All:monitor.elf ${OBJCOPY}${OBJCOPYFLAG}monitor.elfmonitor.hex monitor.elf:${OBJS} ${LD}${LDFLAGS}-omonitor.elf${OBJS}-lmonitor clean:

rm-rf*.o*.elf

在該makefile中的i386ex-start.o、i386ex-get-put-char.o、i386ex-io.o都是由隱含規(guī)則生成的。第104頁/共202頁實(shí)際上使用的隱含規(guī)則如下所示:對*.c-->*.o的隱含規(guī)則為:%.o:%.c${CC}${CFLAGS}$<-o$@對于*.s-->*.o的隱含規(guī)則為:%.o:%.s${AS}${ASFLAGS}$<-o$@第105頁/共202頁3.5交叉匯編器arm-elf-as3.5.1概述arm-elf-as將匯編語言程序轉(zhuǎn)換為ELF(ExecutableandLinkingFormat執(zhí)行時(shí)鏈接文件格式)格式的可重定位目標(biāo)代碼,這些目標(biāo)代碼同其它目標(biāo)模塊或庫易于定位和鏈接。arm-elf-as產(chǎn)生一個(gè)交叉參考表和一個(gè)標(biāo)準(zhǔn)的符號表,產(chǎn)生的代碼和數(shù)據(jù)能夠放在多個(gè)段(Section)中。第106頁/共202頁1.命令格式arm-elf-as[option…][asmfile…]在命令arm-elf-as后面跟一個(gè)或多個(gè)選項(xiàng),以及該選項(xiàng)的子選項(xiàng),選項(xiàng)間用空格隔開,然后跟匯編源文件名。例如,將demo.s編譯成目標(biāo)文件,并且設(shè)置頭文件的搜索目錄為C:\demo\include:arm-elf-as–I//c/demo/includedemo.s第107頁/共202頁2.命令選項(xiàng)列表-a[dhlns] 顯示arm-elf-as信息-f 不進(jìn)行預(yù)處理-Ipath 設(shè)置頭文件搜索路徑-o 設(shè)定輸出文件名-v 顯示版本信息-W 不顯示警告提示-Z 不顯示錯(cuò)誤提示第108頁/共202頁3.5.2命令使用1.生成目標(biāo)文件每次運(yùn)行arm-elf-as只輸出一個(gè)目標(biāo)文件,默認(rèn)狀態(tài)下名字為a.out。可以通過-o選項(xiàng)指定輸出文件名字,通常都以.o為后綴。例如:編譯demo.s輸出目標(biāo)文件demo.o:

arm-elf-as–odemo.odemo.s第109頁/共202頁2.設(shè)置頭文件搜索路徑-Ipath添加路徑path到arm-elf-as的搜索路徑,搜索.include”file”指示的文件。-I可以被使用多次以添加多個(gè)目錄,當(dāng)前工作目錄將最先被搜索,然后從左到右依次搜索-I指定的目錄。例如:編譯demo.s時(shí)指定兩個(gè)搜索目錄,當(dāng)前目錄和C:\demo\include:arm-elf-as–I../–I//c/demo/includedemo.s第110頁/共202頁3.顯示arm-elf-as信息內(nèi)容-a[dhlns]打開arm-elf-as信息顯示。dhlns為其子選項(xiàng),分別表示:d ——不顯示調(diào)試信息h ——顯示源碼信息l ——顯示匯編列表n ——不進(jìn)行格式處理s ——顯示符號列表第111頁/共202頁在不添加子選項(xiàng)時(shí),-a表示顯示源碼信息,顯示匯編列表,顯示符號列表。添加子選項(xiàng)時(shí)將選項(xiàng)直接加在-a以后可以添加一個(gè)或多個(gè)。缺省時(shí)顯示的信息輸出到屏幕,也可用重定向輸出到文件。例如:編譯demo.s生成不進(jìn)行格式處理的匯編列表,輸出到文件a.txt:arm-elf-as–aln–odemo.odemo.s>a.txt第112頁/共202頁4.設(shè)置目標(biāo)文件名字-ofilename每次運(yùn)行arm-elf-as只輸出一個(gè)目標(biāo)文件,默認(rèn)輸出文件為a.out??梢酝ㄟ^-o選項(xiàng)指定輸出文件名字,通常都以.o為后綴。如果指定輸出文件的名字和現(xiàn)有某個(gè)文件重名,生成的文件將直接覆蓋已有的文件。例如:編譯demo.s輸出目標(biāo)文件demo.o:arm-elf-as–I/include–odemo.odemo.s第113頁/共202頁5.如何取消警告信息-W加選項(xiàng)-W以后,運(yùn)行arm-elf-as就不輸出警告信息。例如:編譯demo.s輸出目標(biāo)文件demo.o,不輸出警告信息:arm-elf-as–W–odemo.odemo.s第114頁/共202頁6.設(shè)置是否進(jìn)行預(yù)處理arm-elf-as內(nèi)部的預(yù)處理程序,完成以下工作:調(diào)整并刪除多余空格,刪除注釋,將字符常量改成對應(yīng)的數(shù)值。arm-elf-as不執(zhí)行arm-elf-gcc預(yù)處理程序能完成的部分,如宏預(yù)處理和包含文件預(yù)處理。可以通過.include“file”對指定文件進(jìn)行預(yù)處理。arm-elf-gcc可以對后綴為.S匯編程序進(jìn)行其他形式的預(yù)處理。第115頁/共202頁如果源文件第一行是#NO_APP或者編譯時(shí)使用選項(xiàng)-f將不進(jìn)行預(yù)處理。如果要保留空格或注釋,可以在需要保留部分開始加入#APP,結(jié)束的地方加#NO_APP。例如:編譯demo.s輸出目標(biāo)文件demo.o,并且編譯時(shí)不進(jìn)行預(yù)處理,則命令如下:arm-elf-as–f–odemo.odemo.s第116頁/共202頁3.6匯編語言編程在ARM匯編語言程序里,有一些特殊指令助記符,這些助記符與指令系統(tǒng)的助記符不同,沒有相對應(yīng)的操作碼,通常稱這些特殊指令助記符為偽指令,它們所完成的操作稱為偽操作。偽指令在源程序中的作用是為完成匯編程序作各種準(zhǔn)備工作的,這些偽指令僅在匯編過程中起作用,一旦匯編結(jié)束,偽指令的使命就完成了。在ARM的匯編程序中,有如下幾種偽指令:符號定義偽指令、數(shù)據(jù)定義偽指令、匯編控制偽指令、宏指令以及其他偽指令。第117頁/共202頁3.6.1匯編語言1.基本元素(1)字符集 匯編中使用下列字符組成源程序的各種語法元素:大寫字母A~Z;小寫字母a~z;數(shù)字0~9;符號+-*/=[]();,.:‘@$&#<>{}%_“\-|^?!。其中大小寫字母作用不同。第118頁/共202頁(2)約定的名字包括寄存器名、指令名字和偽操作符。每一個(gè)偽操作符表示一定功能的操作。偽操作的功能由匯編系統(tǒng)實(shí)現(xiàn),沒有目標(biāo)代碼對應(yīng)。這一點(diǎn)是偽操作符與操作符的不同之處。偽操作符是由匯編系統(tǒng)約定的名字,不用定義就能實(shí)現(xiàn)。第119頁/共202頁

偽操作符可以分為六類:數(shù)據(jù)定義偽操作符符號定義偽操作符程序結(jié)構(gòu)偽操作符條件匯編偽操作符宏偽操作符其他偽操作符第120頁/共202頁(3)定義的名字匯編程序中的標(biāo)號、分段名、宏定義名都是用戶可以定義的名字。

①標(biāo)號標(biāo)號只能由a~z、A~Z、0~9、.、_等字符組成,標(biāo)號的長度不受限制,大小寫字母有區(qū)別。第121頁/共202頁當(dāng)標(biāo)號為0~9的單個(gè)數(shù)字時(shí)表示該標(biāo)號為局部標(biāo)號,局部標(biāo)號可以多次重復(fù)出現(xiàn)。在引用時(shí),使用方法如下(N代表0~9的數(shù)字):

Nf——在引用處的地方向前(程序地址增長的方向)的N標(biāo)號。

Nb——在引用處的地方向后(程序地址增長的方向)的N標(biāo)號。 標(biāo)號在最終的絕對定位的代碼中表示所在處的地址,因此在匯編中的標(biāo)號可以在C/C++程序中當(dāng)作變量或者函數(shù)來使用。第122頁/共202頁②分段名

匯編系統(tǒng)中預(yù)定義的分段名有:.text.bss.data.sdata.sbss等,但是用戶可以自己定義段名,語法如下:

.sectionsection_nameattribute

例如:定義一個(gè)可以執(zhí)行的代碼段.mytext .section".mytext","ax" mycode …第123頁/共202頁③宏定義名宏定義的語法如下:.macromacro_nameparm1…parmNmacrobody.endm第124頁/共202頁(4)常數(shù)二進(jìn)制數(shù)由0b或者0B開頭,如:0b1000101、0B1001110;十六進(jìn)制數(shù)以0x或者0X開頭,如:0x4567、0X10089;八進(jìn)制數(shù)由0開頭,如:0345、09870;十進(jìn)制數(shù)以非零數(shù)開頭,如:345、12980例如:.byte74,0112,092,0x4A,0X4a,'J,'\J

.ascii"Ringthebell\7"第125頁/共202頁(5)當(dāng)前地址數(shù)

當(dāng)前的地址數(shù)用點(diǎn)號“.”表示,在匯編程序中可以直接使用該符號。第126頁/共202頁(6)表達(dá)式在匯編程序中可以使用表達(dá)式,在表達(dá)式中可以使用常數(shù)和數(shù)值??梢允褂玫倪\(yùn)算符有: ①前綴運(yùn)算符號

-——取負(fù)數(shù)

~——取補(bǔ)數(shù) ②中綴運(yùn)算符號 */%<<<>>>|&^!+-第127頁/共202頁(7)注釋符號不同芯片的匯編程序中,注釋的符號有所不同,ARM以“@”開頭的程序行是注釋行。第128頁/共202頁2.語句(1)語句類型匯編語句按其作用和編譯的情況分為兩大類:執(zhí)行性語句和說明性語句。執(zhí)行性語句是在編譯后有目標(biāo)程序與之對應(yīng),按其編譯后目標(biāo)程序的對應(yīng)情況又可以分為:一般執(zhí)行性語句和宏語句。一般執(zhí)行性語句與目標(biāo)程序是一一對應(yīng)的,即一個(gè)一般執(zhí)行語句只產(chǎn)生一條目標(biāo)代碼指令。宏語句由偽操作符定義,包括宏定義、宏調(diào)用及宏擴(kuò)展語句。一個(gè)宏語句對應(yīng)了一組目標(biāo)代碼程序,可以看成是一般執(zhí)行性語句的擴(kuò)展。第129頁/共202頁說明性語句由偽操作符定義,它用于用戶以源程序方式和匯編程序通信。用戶使用說明性語句表示源程序的終止說明、分段定義、數(shù)據(jù)定義、內(nèi)存結(jié)構(gòu)等信息。數(shù)據(jù)定義語句用于描述數(shù)據(jù)和給數(shù)據(jù)賦初值.列表控制語句用于說明源程序的格式要求。程序結(jié)構(gòu)語句用于說明源程序的結(jié)構(gòu)和目標(biāo)程序的結(jié)構(gòu)。條件匯編語句用于說明匯編某部分語句時(shí)的條件,滿足條件則編譯,否則跳過這部分不予編譯.第130頁/共202頁(2)數(shù)據(jù)語句一字節(jié)數(shù)據(jù)定義語句語法:.byteexpressions例子:.byte0x89,0x45,56,‘K,‘M,023,0B101011兩字節(jié)數(shù)據(jù)定義語句語法:.shortexpressions例子:.short0x6789,0b101110111四字節(jié)數(shù)據(jù)定義語句語法:.longexpressions例子:.long0x78896676,02356243563456八字節(jié)數(shù)據(jù)定義語法:.quadexpressions例子:.quad0x1122334455667788第131頁/共202頁單個(gè)字串定義語法:.string“string”例子:.string“thisisanexample”多個(gè)字串1語

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論