版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第4章ARM7TDMI匯編語言4.1匯編語言的基本概念4.2ARM匯編程序的組成與結(jié)構(gòu)4.3匯編語言程序設(shè)計(jì)的基本方法4.4匯編語言和C語言交叉編程本章小結(jié)習(xí)題4.1匯編語言的基本概念
所謂語言就是信息交流的載體。生活中的自然語言及本書使用的文字語言,宗旨都是進(jìn)行信息的交流和傳送。人們希望計(jì)算機(jī)按照某種策略自動(dòng)工作,也需要人機(jī)信息交流,將計(jì)算機(jī)能夠理解的語言稱為計(jì)算機(jī)語言。人們使用計(jì)算機(jī)語言編寫程序,告知計(jì)算機(jī)做什么、怎么做。
不同的應(yīng)用場(chǎng)合、不同的應(yīng)用目的差別極大,有不同的系統(tǒng)描述需求,也就派生出了多種計(jì)算機(jī)語言。計(jì)算機(jī)語言可分為三種不同的層次,即機(jī)器語言、匯編語言和高級(jí)語言。
1.機(jī)器語言(MachineLanguage)
機(jī)器語言是一種用二進(jìn)制代碼表示指令和數(shù)據(jù),能被機(jī)器直接識(shí)別的計(jì)算機(jī)語言。不同的處理器具有不同的機(jī)器語言。其缺點(diǎn)是不直觀,不易理解和記憶,因此編寫、閱讀和修改機(jī)器語言程序比較繁瑣。但機(jī)器語言程序是計(jì)算機(jī)唯一能夠直接理解和執(zhí)行的程序,具有執(zhí)行速度快、占用內(nèi)存少等特點(diǎn)。
2.匯編語言(AssemblyLanguage)
二進(jìn)制代碼形式的機(jī)器語言人們難以記憶,編程時(shí)難以使用。人們將機(jī)器語言的基本元素——機(jī)器指令符號(hào)化,使用英文單詞縮寫形式的助記符一一對(duì)應(yīng)表示機(jī)器指令,以便于記憶和編程使用。這種助記符形式的計(jì)算機(jī)語言稱為匯編語言。將使用匯編語言編寫的源程序稱為匯編語言源程序。匯編語言源程序與其經(jīng)過匯編所產(chǎn)生的目標(biāo)代碼程序之間有明顯的一一對(duì)應(yīng)關(guān)系,故也稱匯編語言為符號(hào)語言。
匯編語言是一種采用助記符表示的程序設(shè)計(jì)語言,使用助記符來表示指令的操作碼和操作數(shù),用標(biāo)號(hào)或符號(hào)代表地址、常量或變量。匯編語言是一種面向物理層操作的計(jì)算機(jī)語言。不同的處理器類型,具有不同的匯編語言。使用匯編語言編寫程序能夠直接利用硬件系統(tǒng)的特性(如寄存器、標(biāo)志、中斷系統(tǒng)等),可直接對(duì)位、字節(jié)、字寄存器或存儲(chǔ)單元、I/O端口進(jìn)行處理,同時(shí)也能直接使用CPU指令系統(tǒng)提供的各種尋址方式,編制出高質(zhì)量的程序,這樣的程序不但占用內(nèi)存空間少,而且執(zhí)行速度快。當(dāng)然,由于匯編語言不直接支持復(fù)雜的抽象數(shù)據(jù)類型,因此在描述目標(biāo)系統(tǒng)數(shù)學(xué)模型時(shí),還需要程序員在存儲(chǔ)器單元組織各種抽象數(shù)據(jù)類型的存儲(chǔ)方式,使得匯編語言程序設(shè)計(jì)較高級(jí)語言困難得多,需要較多的軟件開發(fā)時(shí)間,也增加了程序設(shè)計(jì)過程中出錯(cuò)的可能性,程序維護(hù)亦變得困難。用匯編語言編寫的源程序需要翻譯成目標(biāo)程序(機(jī)器語言程序)才能被機(jī)器執(zhí)行。這種翻譯過程稱為匯編,完成匯編任務(wù)的系統(tǒng)程序稱為匯編程序,如圖4-1所示。圖4-1匯編程序的功能示意圖匯編程序是最早也是最成熟的一種系統(tǒng)軟件。它除了能夠?qū)R編語言源程序翻譯成機(jī)器語言程序這一主要功能外,還能夠根據(jù)用戶的要求自動(dòng)分配存儲(chǔ)區(qū)域(包括程序區(qū)、數(shù)據(jù)區(qū)、暫存區(qū)等);自動(dòng)地把各種進(jìn)位制數(shù)轉(zhuǎn)換成二進(jìn)制數(shù),把字符轉(zhuǎn)換成ASCII碼,計(jì)算表達(dá)式的值等;自動(dòng)對(duì)源程序進(jìn)行語法檢查,給出錯(cuò)誤信息(如非法語句格式、未定義的助記符等),等等。
3.高級(jí)語言(HighLevelLanguage)
如果說機(jī)器語言、匯編語言是面向機(jī)器的,那么高級(jí)語言(如BASIC、C等)則是面向過程的計(jì)算機(jī)語言。使用這些語言編程,程序員可以不考慮機(jī)器的結(jié)構(gòu)特點(diǎn),不必了解和熟悉機(jī)器的指令系統(tǒng),僅使用一些接近人們書寫習(xí)慣的英語和數(shù)學(xué)表達(dá)式形式的語言去編制程序。這種程序與目標(biāo)系統(tǒng)的數(shù)學(xué)模型之間有著良好的對(duì)應(yīng)關(guān)系,可在各種機(jī)器上通用(不同機(jī)器之間僅作少量修改)。但是,機(jī)器不能直接執(zhí)行這種用高級(jí)語言編寫的源程序,需要先將它翻譯成對(duì)應(yīng)的目標(biāo)程序(即機(jī)器語言程序),而后才能運(yùn)行。把具有這種翻譯作用的系統(tǒng)程序稱為編譯程序,這個(gè)翻譯過程稱為編譯,如圖4-2所示。圖4-2編譯程序的功能示意圖由于高級(jí)語言程序未考慮機(jī)器的結(jié)構(gòu)特點(diǎn),因而它不能充分利用某種具體CPU所具有的某些特性,而通過編譯或解釋程序生成的目標(biāo)程序往往比較冗長(zhǎng),占有較多的內(nèi)存空間,執(zhí)行時(shí)間也比較長(zhǎng)。因此,系統(tǒng)中那些高頻率使用的系統(tǒng)功能程序通常還是使用匯編程序編寫,以獲得系統(tǒng)的高效率,如PC機(jī)的BIOS;再就是必須與硬件相關(guān)的應(yīng)用場(chǎng)合,如與具體的處理器硬件密切相關(guān)的系統(tǒng)啟動(dòng)代碼等,一般還是要用匯編語言編寫。
4.2ARM匯編程序的組成與結(jié)構(gòu)
首先看一個(gè)簡(jiǎn)單的ARM匯編程序,代碼如程序清單4-1所示。
程序清單4-1數(shù)據(jù)塊的拷貝
AREA Word,CODE,READONLY
;代碼段的名字Word
num EQU 20;宏定義,設(shè)置拷貝字的個(gè)數(shù)
ENTRY;程序的入口
CODE32 ;聲明下面的代碼是ARM指令
start
LDR R0,=src ;?R0指向源數(shù)據(jù)塊
LDRR1,=dst ;?R1指向目的數(shù)據(jù)塊
MOVR2,#num;?R2需要拷貝的數(shù)據(jù)個(gè)數(shù)
1.段
ARM匯編語言源程序由段組成。段是相對(duì)獨(dú)立的程序塊單位,每個(gè)段由匯編器偽指令A(yù)REA定義,并定義段的屬性:READONLY(只讀)或READWRITE(讀寫)。它用于定義一個(gè)代碼段或數(shù)據(jù)段,若段名以非字母開頭,則該段名需要用“|”括起來,如程序清單4-1中的?|.extra|。
在匯編程序中,至少包含一個(gè)或多個(gè)代碼段、0個(gè)或多個(gè)初始化數(shù)據(jù)段以及0個(gè)或多個(gè)未初始化數(shù)據(jù)段。如果程序太長(zhǎng),也可以將程序分成多個(gè)代碼段和數(shù)據(jù)段。
程序清單4-1由3個(gè)段構(gòu)成,分別為代碼段Word、數(shù)據(jù)段BlockData和未初始數(shù)據(jù)段.extra。
2.標(biāo)識(shí)符
匯編程序中標(biāo)識(shí)符(label)用于表示指令或數(shù)據(jù)的地址,如程序清單4-1中的start、stop或src、dst等。它是由字母或下劃線開頭的字母數(shù)字串。
需注意的是:
①所有的標(biāo)識(shí)符必須在一行的開頭頂格寫,前面不能留空格;標(biāo)號(hào)以空格結(jié)束,后面也不能像C語言中的標(biāo)簽?zāi)菢蛹由稀埃骸薄?/p>
②ARM匯編器對(duì)標(biāo)識(shí)符的大小寫敏感,標(biāo)識(shí)符定義與使用時(shí)字母的大小寫要一致,同名的大、小寫標(biāo)識(shí)符會(huì)被編譯器認(rèn)為是不同的標(biāo)識(shí)符。
3.程序入口
ARM匯編語言中,用ENTRY指示程序的入口。
4.程序結(jié)束
ARM匯編語言中,用END表示程序的結(jié)束。在每一個(gè)匯編源程序文件里,必須有一個(gè)END。4.2.1匯編器偽指令
ARM匯編語言程序中,有一些特殊的指令助記符,稱為匯編器偽指令。它們無論表示形式或其在程序中所處的位置都與指令相似,它們?cè)谠闯绦蛑卸颊紦?jù)一行,但二者之間有著重要的區(qū)別:
(1)指令是供CPU執(zhí)行的操作命令,每條指令對(duì)應(yīng)CPU的一種特定操作,在用戶代碼運(yùn)行期間執(zhí)行;而匯編器偽指令是供匯編器處理的命令,在匯編過程中由匯編器進(jìn)行處理,例如定義數(shù)據(jù)、分配存儲(chǔ)區(qū)、定義段、定義宏等。
(2)匯編以后,每條指令產(chǎn)生一一對(duì)應(yīng)的二進(jìn)制目標(biāo)代碼;而匯編器偽指令則不產(chǎn)生與之對(duì)應(yīng)的目標(biāo)代碼。4.2.2
ARM匯編程序中的數(shù)據(jù)定義
數(shù)據(jù)定義的目的是為目標(biāo)系統(tǒng)數(shù)學(xué)模型的各種抽象數(shù)據(jù)類型分配存儲(chǔ)單元,同時(shí)進(jìn)行初始化。
1.DCB、DCW和DCD匯編器偽指令
(1)?DCB用于分配一片連續(xù)的字節(jié)存儲(chǔ)單元,并用指定的表達(dá)式值初始化。其中,表達(dá)式可以是0~255的數(shù)字或字符串。DCB也可用“=”代替。ARM匯編語言程序中,這是定義一個(gè)字符串的好方法。例如:
string DCB "HelloWorld!"
;分配一片連續(xù)的字節(jié)存儲(chǔ)單元并初始化
(2)?DCW用于分配一片連續(xù)的半字存儲(chǔ)單元,并用指定的表達(dá)式值初始化。其中,表達(dá)式可以是程序標(biāo)號(hào)或數(shù)值表達(dá)式。用DCW分配的存儲(chǔ)單元是半字對(duì)齊的。例如:
halfword DCW 1,2,3
;分配一片連續(xù)的半字存儲(chǔ)單元并初始化
(3)?DCD用于分配一片連續(xù)的字存儲(chǔ)單元,并用指定的表達(dá)式值初始化。其中,表達(dá)式可以是程序標(biāo)號(hào)或數(shù)值表達(dá)式。DCD也可用“&”代替。用DCD分配的存儲(chǔ)單元是字對(duì)齊的。示例參見程序清單4-1。
2.SPACE匯編器偽指令
SPACE用于分配一片連續(xù)的存儲(chǔ)區(qū)域并初始化為0。其中,表達(dá)式是要分配的字節(jié)數(shù)。SPACE也可以用“%”代替。示例參見程序清單4-1。
3.LTORG匯編器偽指令
LTORG用于聲明一個(gè)文字池(literalpool),用于存放常量。當(dāng)一般的ARM數(shù)據(jù)處理指令的操作數(shù)為立即數(shù)時(shí),這個(gè)立即數(shù)必須是一個(gè)8?bit位圖立即數(shù),否則就認(rèn)定“不合法”。但是,在實(shí)際應(yīng)用中,我們需要的操作數(shù)往往很難符合這個(gè)要求。
ARM匯編語言提供了LDR加載指令附加文字池的方法,文字池中可以存放任意的32比特?cái)?shù),LDR加載指令相對(duì)尋址文字池,以實(shí)現(xiàn)對(duì)任意立即數(shù)的訪問。匯編過程中,匯編器會(huì)默認(rèn)地在每一個(gè)段的末尾添加一個(gè)文字池。需要注意的是,文字池不能遠(yuǎn)離文字池使用者(LDR指令),因?yàn)長(zhǎng)DR指令的尋址范圍是指令位置的前后4?KB。如果用戶程序比較大,則可能使程序段的末尾超出4?KB范圍,此時(shí)需要在程序中的適當(dāng)位置,使用LTORG偽指令顯式聲明文字池。一般總可以在LDR偽指令前后4?KB的范圍內(nèi)找到分支指令,文字池可聲明在分支(B)指令之后的緊鄰位置,不會(huì)影響代碼的正常執(zhí)行,因?yàn)锽指令總是會(huì)將程序的執(zhí)行轉(zhuǎn)移到其他地方。
1.缺省文字池
ARM匯編語言的匯編器會(huì)在每一個(gè)段的末尾開辟一個(gè)缺省的文字池,示例如程序清單4-2所示。實(shí)際的二進(jìn)制調(diào)試代碼如程序清單4-3所示。圓圈部分表示匯編器自動(dòng)添加的文字池。
2.自定義文字池
匯編器在每一個(gè)程序段的末尾附加缺省文字池,如果程序段較長(zhǎng),這個(gè)缺省的文字池和LDR指令的距離有可能超出4?KB,那么LDR指令也就不能正確加載數(shù)據(jù)了,示例代碼如程序清單4-4所示,編譯信息如圖4-3所示。當(dāng)這種情況發(fā)生時(shí),可以在程序段的適當(dāng)位置顯式地聲明一個(gè)文字池,使該文字池在LDR指令的前后4?KB范圍內(nèi)即可。圖4-3
LDR失去加載能力的編譯信息在程序清單4-4中,使用SPACE偽指令開辟了4096個(gè)字節(jié)(4096=212=4
KB)的存儲(chǔ)區(qū)域other,這樣匯編器在本段末添加的文字池與指令“LDRR1,=0xABCDEF”和“LDRR2,=0x101”的距離就大于4096個(gè)字節(jié),超出了LDR指令的4
KB尋址范圍,此時(shí)LDR指令失效。
匯編器輸出結(jié)果如圖4-3所示,圖中顯示了匯編器彈出文字池太遠(yuǎn)的錯(cuò)誤信息以及使用LTORG來編譯4?KB距離的代碼的建議。
可以在匯編程序的適當(dāng)位置顯式地聲明文字池,自定義文字池的代碼如程序清單4-5所示,實(shí)際的二進(jìn)制調(diào)試代碼如程序清單4-6所示。在程序清單4-5中,通過在距LDR指令前后4?KB范圍之內(nèi)(本程序中在B指令后面)添加一條LTORG偽指令,自定義一個(gè)文字池,這樣LDR指令就會(huì)使用自定義的文字池加載“不合法”數(shù)據(jù),而匯編器也不會(huì)彈出文字池距離太遠(yuǎn)的錯(cuò)誤提示。4.3匯編語言程序設(shè)計(jì)的基本方法
4.3.1結(jié)構(gòu)化程序設(shè)計(jì)的基本概念
結(jié)構(gòu)化程序設(shè)計(jì)由迪杰斯克拉(E.W.Dijkstra)于1969年提出,是以模塊化設(shè)計(jì)為中心,將待開發(fā)的軟件系統(tǒng)分解成若干個(gè)相互獨(dú)立的模塊,這樣使每一個(gè)模塊的設(shè)計(jì)編程工作變得單純而明確,為設(shè)計(jì)復(fù)雜的軟件系統(tǒng)打下了良好的基礎(chǔ)。由于模塊間相互獨(dú)立,在設(shè)計(jì)其中一個(gè)模塊時(shí),不會(huì)受到其他模塊的牽連,因而可將原來較復(fù)雜的軟件系統(tǒng)設(shè)計(jì)化簡(jiǎn)為一系列簡(jiǎn)單模塊的設(shè)計(jì)。模塊的獨(dú)立性還為擴(kuò)充已有的系統(tǒng)、建立新系統(tǒng)帶來了不少的方便,因?yàn)槲覀兛梢猿浞掷矛F(xiàn)有的模塊作積木式的擴(kuò)展。
按照結(jié)構(gòu)化程序設(shè)計(jì)的觀點(diǎn),任何算法功能都可以通過四種基本程序結(jié)構(gòu)即順序結(jié)構(gòu)、分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)和子程序的組合來實(shí)現(xiàn)。結(jié)構(gòu)化程序設(shè)計(jì)的基本思想是采用“自頂向下,逐步求精”的程序設(shè)計(jì)方法和“單入口單出口”的控制結(jié)構(gòu)。“自頂向下、逐步求精”程序設(shè)計(jì)方法的主導(dǎo)思想是從問題本身開始,對(duì)問題進(jìn)行分解,將解決問題的方法步驟逐步細(xì)化,分解為由基本程序結(jié)構(gòu)模塊組成的結(jié)構(gòu)化程序框圖;“單入口單出口”的思想認(rèn)為一個(gè)復(fù)雜的程序,如果它僅由順序、分支、循環(huán)和子程序四種基本程序結(jié)構(gòu)的組合、嵌套構(gòu)成,那么這個(gè)新構(gòu)造的程序一定是一個(gè)單入口單出口的程序。根據(jù)結(jié)構(gòu)化程序設(shè)計(jì)的基本思想編寫出結(jié)構(gòu)良好、易于調(diào)試和維護(hù)的程序。4.3.2匯編語言程序設(shè)計(jì)的流程
使用計(jì)算機(jī)通過編程解決某一問題時(shí),通常按以下步驟進(jìn)行。
1.分析問題并建立數(shù)學(xué)模型
研討目標(biāo)系統(tǒng)的本質(zhì)特性,用數(shù)學(xué)方法對(duì)其本質(zhì)特性進(jìn)行抽象描述,建立目標(biāo)系統(tǒng)的數(shù)學(xué)表示模型(也稱為數(shù)據(jù)結(jié)構(gòu)模型)。
2.確定算法
在已建立的目標(biāo)系統(tǒng)數(shù)學(xué)表示模型的基礎(chǔ)上,進(jìn)一步研討目標(biāo)系統(tǒng)的內(nèi)在規(guī)則,設(shè)計(jì)相應(yīng)的處理法則方案(算法分析與描述)。
3.設(shè)計(jì)程序流程圖
把解題的方法、步驟用框圖形式表示。如果要解決的問題比較復(fù)雜,那么可以逐步細(xì)化,直到每一框圖易于編程為止。流程圖不僅便于程序的編制,且對(duì)程序邏輯正確性也比較容易查找和修改。流程圖主要由以下幾種框圖符號(hào)組成,框圖符號(hào)如圖4-4所示。
(1)處理框:用于說明一程序段(或一條指令)所完成的功能。這種框圖通常有一個(gè)入口及一個(gè)出口。
(2)判斷框:表示程序的分支流向判斷,框內(nèi)進(jìn)行條件判斷。這種框圖通常有一個(gè)入口、兩個(gè)或兩個(gè)以上的出口。在每個(gè)出口上要注明分支流向的條件。
(3)起止框:表示一個(gè)程序或一個(gè)程序模塊的開始和結(jié)束。起始框內(nèi)通常用程序名(如過程名)、標(biāo)號(hào)或“開始”字符來表示。終止框內(nèi)通常用“結(jié)束”、“返回”等字符來表示。
(4)連接框:當(dāng)一個(gè)程序比較復(fù)雜,需要分別描述且又要表示出其相互關(guān)系時(shí),可用連線框表示兩條流向線的連接關(guān)系。所以連接框中常用字母或數(shù)字來表示其對(duì)應(yīng)關(guān)系??騼?nèi)有相同字母或數(shù)字就表示它們有連線關(guān)系。它只有一個(gè)入口或出口。
(5)流向線:表示程序的流向,即程序執(zhí)行的順序關(guān)系。帶箭頭的連線指明程序的流向。圖4-4程序流程圖的框圖符號(hào)
4.合理分配寄存器、存儲(chǔ)空間和外設(shè)資源
合理地分配存儲(chǔ)器資源,將前述的目標(biāo)系統(tǒng)數(shù)據(jù)結(jié)構(gòu)模型表示到各存儲(chǔ)器單元。
CPU寄存器數(shù)量有限,而在程序中,大多數(shù)操作都要使用寄存器,并且有的操作使用特定的寄存器(如堆棧操作使用SP/R13等),程序中要合理分配各寄存器的用途。
5.編制程序
根據(jù)程序流程框圖,使用指令和偽指令逐條編制源程序。用計(jì)算機(jī)語言(在此是匯編語言)對(duì)數(shù)據(jù)結(jié)構(gòu)模型和流程圖表示的算法進(jìn)行準(zhǔn)確的描述。
6.調(diào)試程序
源程序的調(diào)試主要包含兩部分:語法調(diào)試和功能調(diào)試。
(1)語法調(diào)試:排除程序中的語法錯(cuò)誤。當(dāng)源程序進(jìn)行編譯時(shí),編譯器(或匯編器)會(huì)進(jìn)行語法檢查,并指出其中的語法出錯(cuò)語句,程序員更正即可。
(2)功能調(diào)試:保證程序的邏輯功能正確性。計(jì)算機(jī)完全按照程序執(zhí)行,程序功能的正確性完全由程序設(shè)計(jì)者保證。軟件開發(fā)環(huán)境會(huì)為程序員提供一些調(diào)試手段,如設(shè)斷點(diǎn)、跟蹤、單步執(zhí)行,查閱變量、內(nèi)存和寄存器等;調(diào)試程序時(shí),設(shè)計(jì)師觀察實(shí)際運(yùn)算數(shù)據(jù)情況并與預(yù)期值比對(duì),查找差別的原因,逐漸調(diào)試整個(gè)程序使之達(dá)到預(yù)期效果。
7.形成文檔
用文檔形式記錄說明程序的功能、使用方法、程序結(jié)構(gòu)、算法流程等每一個(gè)階段的工作。4.3.3順序程序設(shè)計(jì)
順序程序是一種最簡(jiǎn)單的程序結(jié)構(gòu),也稱為直線程序,它的執(zhí)行自始自終按照語句的先后順序進(jìn)行。從這種結(jié)構(gòu)的流程圖(如圖4-5所示)來看,除了有一個(gè)起始框和一個(gè)終止框外,就是若干執(zhí)行框。
例4.1
試編制一程序,完成10+3的操作。流程圖如圖
4-5所示,參考源程序如程序清單4-7所示。圖4-5順序程序流程圖4.3.4分支程序設(shè)計(jì)
順序程序的特點(diǎn)是從程序的第一條指令開始,按順序逐條執(zhí)行每條指令,直到執(zhí)行完最后一條指令。然而,許多實(shí)際問題需要根據(jù)不同的情況作出不同的處理。在程序中,把不同的處理方法編制成各自的處理程序段,運(yùn)行時(shí)由機(jī)器根據(jù)不同的條件自動(dòng)作出判斷,選擇執(zhí)行相應(yīng)的處理程序段。這樣的程序結(jié)構(gòu)中,計(jì)算機(jī)不再完全按指令存儲(chǔ)的順序執(zhí)行,稱這樣的程序?yàn)榉种С绦?。分支程序使用子程序調(diào)用指令BL、轉(zhuǎn)移指令B或帶狀態(tài)轉(zhuǎn)移指令BX來實(shí)現(xiàn)。
例4.2
給定以下符號(hào)函數(shù):任意給定值,假定為?-25,存放在x單元,函數(shù)值存放在y單元,要求根據(jù)x中的值來確定y的值。程序流程圖如圖4-6所示,參考源代碼如程序清單4-8所示。圖4-6符號(hào)函數(shù)程序的流程圖說明:圖4-6中Address(x)表示取單元x的地址;Value(x)表示取單元x中的值。4.3.5循環(huán)程序設(shè)計(jì)
順序程序和分支程序中的指令每次運(yùn)行最多只執(zhí)行一次。在實(shí)際應(yīng)用中重復(fù)地做某些事的情況是很多的,這也是計(jì)算機(jī)最擅長(zhǎng)的工作方式。重復(fù)地執(zhí)行某些指令,最好用循環(huán)程序來實(shí)現(xiàn)。
1.循環(huán)程序的結(jié)構(gòu)
循環(huán)程序通常由以下五個(gè)部分組成,如圖4-7所示。圖4-7循環(huán)程序的基本結(jié)構(gòu)
(1)初始化部分:建立循環(huán)初始值。如設(shè)置地址指針、計(jì)數(shù)器、其他循環(huán)參數(shù)的起始值等。
(2)工作部分(循環(huán)體):在循環(huán)過程中所要完成的具體操作,是循環(huán)程序的主要部分。這部分視具體情況而定。它可以是一個(gè)順序程序、一個(gè)分支程序或另一個(gè)循環(huán)程序。
(3)修改部分:為執(zhí)行下一個(gè)循環(huán)而修改某些參數(shù)。如修改地址指針、其他循環(huán)參數(shù),尤其是循環(huán)控制變量的修改等。
(4)控制部分:判斷循環(huán)結(jié)束條件是否成立,決定是否繼續(xù)循環(huán)。通常控制循環(huán)是否結(jié)束的方法有兩種:
①計(jì)數(shù)控制循環(huán):通過計(jì)數(shù)循環(huán)次數(shù),判斷是否已達(dá)到預(yù)定次數(shù),控制循環(huán),適合已知循環(huán)次數(shù)的循環(huán)控制。例如,計(jì)算∑=1+2+3+…+1000。②條件控制循環(huán):通過判斷循環(huán)終止條件是否已成立,控制循環(huán),適合僅知道結(jié)束條件的循環(huán)控制。例如,在掃描字符串時(shí),不知道字符串的長(zhǎng)度,只知道字符串的結(jié)尾標(biāo)志,則可使用該標(biāo)志作為循環(huán)控制條件對(duì)字符串中的各個(gè)字符進(jìn)行處理。
(5)結(jié)束處理部分:對(duì)循環(huán)結(jié)束進(jìn)行適當(dāng)處理,如存儲(chǔ)結(jié)果等。有的循環(huán)程序可以沒有這部分。
圖4-7(a)給出的循環(huán)程序框圖是“先執(zhí)行后判斷”的結(jié)構(gòu),這種循環(huán)結(jié)構(gòu)中的循環(huán)體至少被執(zhí)行一遍;另有一種結(jié)構(gòu)形式是“先判斷后執(zhí)行”的形式,如圖4-7(b)所示,這種循環(huán)結(jié)構(gòu)中的循環(huán)體可能一遍也不執(zhí)行。兩種循環(huán)控制方式和兩種循環(huán)結(jié)構(gòu)在實(shí)際應(yīng)用中要靈活運(yùn)用。
2.循環(huán)控制方法
1)用計(jì)數(shù)控制循環(huán)
用計(jì)數(shù)控制循環(huán)的方法適用于已知循環(huán)次數(shù)的循環(huán)程序
設(shè)計(jì)。
例4.3
從x單元開始的30個(gè)連續(xù)字單元中存放有30個(gè)無符號(hào)數(shù),從中找出最大者送入y單元中。根據(jù)題意,我們把第一個(gè)數(shù)先送入R3寄存器,將R3中的數(shù)與后面的29個(gè)數(shù)逐個(gè)進(jìn)行比較,如果R3中的數(shù)較小,則將該較大的數(shù)送入R3;繼續(xù)與余下的數(shù)據(jù)逐個(gè)比較。在比較過程中,R3中始終保持較大的數(shù),共計(jì)比較29次,則最終R3中保留了最大數(shù),最后把R3中的數(shù)(最大者)送入y單元。
這個(gè)問題的特點(diǎn)就是循環(huán)比較次數(shù)是已知的,因此可以用計(jì)數(shù)器控制循環(huán),程序的流程圖如圖4-8所示,參考源代碼如程序清單4-9所示。圖4-8從一批數(shù)中求最大者的程序流程圖
2)用條件控制循環(huán)
有些情況無法確定循環(huán)次數(shù),但知道循環(huán)結(jié)束的條件,這時(shí)可使用此條件控制循環(huán)。
例4.4
從自然數(shù)1開始累加,直到累加和大于1000為止,統(tǒng)計(jì)被累加的自然數(shù)的個(gè)數(shù),并把統(tǒng)計(jì)的個(gè)數(shù)送入n單元,把累加和送入sum單元。
根據(jù)題意,被累加的自然數(shù)的個(gè)數(shù)事先未知,因此不能用計(jì)數(shù)方法控制循環(huán)。但題目中給定一個(gè)條件,即累加和大于1000則停止累加,因此,可以根據(jù)這一條件控制循環(huán)。我們用R3寄存器存放累加和,用R4寄存器存放每次取得的自然數(shù),其中它的值也是統(tǒng)計(jì)自然數(shù)的個(gè)數(shù)。程序流程圖如圖4-9所示,參考程序如程序清單4-10所示。圖4-9利用條件控制循環(huán)的程序流程圖4.3.6子程序設(shè)計(jì)
1.子程序的概念
如果在一個(gè)程序中的多處用到同一段程序代碼,那么我們可以把這段共同的程序代碼抽取出來,寫成一個(gè)相對(duì)獨(dú)立的程序段,每當(dāng)我們需要執(zhí)行這段代碼時(shí),就調(diào)用這個(gè)程序段,執(zhí)行完這個(gè)程序段后,再返回原來調(diào)用它的程序。這樣我們編寫程序時(shí),就不必重寫這段代碼了,這樣的程序段稱為子程序或子過程。而調(diào)用子程序的程序稱為主程序或調(diào)用程序。
2.子程序的調(diào)用與返回
主程序中使用BL指令可以實(shí)現(xiàn)子程序的調(diào)用,語法如下所示:
BL 子程序名
在子程序的結(jié)束處,可以使用如下指令返回到主程序中:
MOV PC, LR
3.調(diào)用程序與子程序之間的參數(shù)傳遞
調(diào)用程序在調(diào)用子程序時(shí),可以向子程序傳遞一些參數(shù);同樣,子程序運(yùn)行后也可以把一些結(jié)果參數(shù)傳回給調(diào)用程序。調(diào)用程序與子程序之間的這種信息傳遞稱為參數(shù)傳遞。參數(shù)傳遞有以下三種方式。
1)寄存器傳遞參數(shù)方式
技術(shù)思想:主程序?qū)⒋齻鬟f的數(shù)據(jù)直接寫入約定的通用寄存器,再進(jìn)行BL子程序調(diào)用;或子程序返回后,主程序直接從約定的通用寄存器中獲得子程序的結(jié)果數(shù)據(jù)。
應(yīng)用特點(diǎn):這種方式適合于傳遞較少參數(shù)的應(yīng)用場(chǎng)合。
例4.5
用子程序?qū)崿F(xiàn)內(nèi)存區(qū)里的字符串拷貝功能,即將存儲(chǔ)單元中的源字符串對(duì)應(yīng)拷貝到目的字符串中。
解題思路:通過設(shè)定兩個(gè)地址指針,分別指向存儲(chǔ)區(qū)中的源字符串和目的字符串;然后通過加載和存儲(chǔ)指令(LDR和STR)的寄存器間接尋址方式,依次從源字符串讀取一個(gè)字符數(shù)據(jù),寫入目的字符串的對(duì)應(yīng)字符位置中,直到遇到源字符串的結(jié)束標(biāo)志“0”為止。
2)存儲(chǔ)區(qū)域傳遞參數(shù)方式
技術(shù)思想:主程序和子程序約定了某一共享內(nèi)存塊用于參數(shù)傳遞,主程序在BL調(diào)用子程序前,先將要傳遞的參數(shù)寫入約定的存儲(chǔ)單元,子程序可從約定的內(nèi)存讀取這些參數(shù);子程序返回時(shí),也可以使用該方式將數(shù)據(jù)傳給主程序。
應(yīng)用特點(diǎn):這種方式可以傳遞大批量數(shù)據(jù)。
實(shí)現(xiàn)方法:當(dāng)主程序與子程序有較多的數(shù)據(jù)需要傳遞時(shí),可以通過共享內(nèi)存區(qū)或傳內(nèi)存數(shù)據(jù)塊地址方式來傳遞批量數(shù)據(jù)。通常有三種方法裝載地址:
(1)通過ADR偽指令直接裝載近距離的數(shù)據(jù)塊地址。
(2)通過ADRL偽指令直接裝載較近距離的數(shù)據(jù)塊地址。
(3)通過偽指令“LDRRd,=Label”轉(zhuǎn)載遠(yuǎn)距離的數(shù)據(jù)塊地址。
例4.6
通過設(shè)置的入口參數(shù)查找函數(shù)地址表,實(shí)現(xiàn)選擇不同的函數(shù)功能。
說明:本題通過事先將函數(shù)地址存放在存儲(chǔ)單元中,使用查找地址表的方法,實(shí)現(xiàn)根據(jù)“選擇項(xiàng)(choice)”進(jìn)入不同的函數(shù)體功能。
3)堆棧傳遞參數(shù)方式
主程序和子程序使用同一個(gè)堆棧,主程序在BL調(diào)用子程序前,先將要傳遞的參數(shù)壓入堆棧中,子程序可從堆棧中讀取傳過來的數(shù)據(jù);子程序返回需要向主程序傳遞參數(shù)時(shí),也可使用此方法。這種參數(shù)傳遞方式多見于高級(jí)語言的函數(shù)調(diào)用時(shí),編譯系統(tǒng)采用的參數(shù)傳遞方法,匯編程序初級(jí)應(yīng)用中不常見,在此不再冗述。4.4匯編語言和C語言交叉編程
ARM開發(fā)工具ADS不但支持ARM/Thumb匯編語言程序設(shè)計(jì),在微控器模型頭文件的支持下,還支持ANSIC和C++語言程序設(shè)計(jì)。
在實(shí)際的嵌入式軟件中,大部分的代碼都是用C語言編寫的。人們之所以喜歡使用C語言進(jìn)行程序設(shè)計(jì),主要是因?yàn)镃語言支持豐富的抽象數(shù)據(jù)類型,更便于對(duì)目標(biāo)系統(tǒng)進(jìn)行數(shù)學(xué)模型描述和算法描述,并且編制的程序結(jié)構(gòu)比較好,便于人的理解和維護(hù),還有大量的支持庫可直接選用。盡管如此,許多地方還是要用到匯編語言,例如開機(jī)時(shí)處理器硬件相關(guān)的啟動(dòng)代碼必須使用匯編語言編寫。另外,匯編代碼一般比C代碼具有更高的效率,因此高實(shí)時(shí)性要求的設(shè)備驅(qū)動(dòng)等還常使用匯編語言編寫。實(shí)際應(yīng)用中,為了既兼顧代碼的高執(zhí)行效率,又兼顧程序設(shè)計(jì)的便捷性,可以使用交叉編程的方式進(jìn)行程序設(shè)計(jì),即在一個(gè)程序中既含有匯編代碼,又含有C代碼的程序設(shè)計(jì)方式。匯編語言和C語言交叉編程技術(shù)在嵌入式軟件開發(fā)中也時(shí)常用到,在此僅作簡(jiǎn)單介紹。4.4.1匯編程序與C程序間變量互訪
匯編程序和C語言程序中變量間的相互訪問是交叉編程的基本問題。
1.匯編程序訪問C程序中的變量
匯編程序訪問C程序中的變量,可通過地址間接地訪問C程序中聲明為外部全局屬性的變量。具體操作步驟如下:
(1)在C程序中,將供匯編程序訪問的變量用關(guān)鍵字extern聲明為全局變量。
(2)匯編程序中,用偽指令I(lǐng)MPORT引入C程序中的全局
變量。
(3)使用偽指令LDR讀取這個(gè)全局變量的地址。
(4)使用指令LDR讀取這個(gè)全局變量的值。
(5)在匯編程序中使用這個(gè)全局變量。
匯編程序訪問C程序中變量的例子如程序清單4-13所示。
2.C程序訪問匯編程序中的變量
如果需要在C程序中訪問匯編程序中的變量,則匯編程序中的變量名必須以下劃線為首字符,并用偽指令global將其聲明為全局變量。具體操作步驟如下:
(1)在匯編語言程序中,用偽指令“global”定義全局變量,變量名必須是以下劃線“_”為首字符的字母數(shù)字串。
(2)
C程序中將該變量聲明為外部變量,即可訪問匯編程序定義的全局變量。
C程序訪問匯編程序中變量的例子如程序清單4-13所示。4.4.2匯編程序調(diào)用C程序
匯編程序中調(diào)用C函數(shù),只需在匯編程序中用偽指令I(lǐng)MPORT將需要調(diào)用的C函數(shù)名引用即可,然后將C函數(shù)放在一個(gè)獨(dú)立的C文件中進(jìn)行編譯,剩下的工作就由鏈接器來處理。匯編程序與C函數(shù)間參數(shù)的傳遞規(guī)則遵守ATPCS(ARMThumbProcedureCallStandard)規(guī)則:用ARM處理器寄存器組中的{R0-R3}作為參數(shù)傳遞和結(jié)果返回寄存器;如果參數(shù)數(shù)目超過4個(gè),則使用堆棧進(jìn)行傳遞。
匯編程序調(diào)用C程序的例子如程序清單4-14所示。4.4.3C程序調(diào)用匯編程序
C程序調(diào)用匯編程序子程序,要做的主要工作有兩個(gè):一是在C程序中用關(guān)鍵字extern聲明匯編子程序的函數(shù)原型(C程序是函數(shù)結(jié)構(gòu)的程序設(shè)計(jì)風(fēng)格),聲明該函數(shù)的實(shí)現(xiàn)代碼在其他文件中;二是在匯編程序中用偽指令EXPORT導(dǎo)出子程序名,并且用該子程序名作為匯編代碼段的標(biāo)識(shí),最后用“MOVPC,LR”指令返回。這樣,在C程序中就可以像調(diào)用C函數(shù)一樣調(diào)用該匯編子程序了。從C程序的角度看,它并不關(guān)心該函數(shù)是用C語言還是匯編語言來編寫。因?yàn)镃程序中用到的函數(shù)名只起到表明該函數(shù)代碼存儲(chǔ)單元起始地址的作用,與匯編語言中的標(biāo)號(hào)label的作用一致。
C程序調(diào)用匯編程序的具體操作步驟如下:
(1)匯編程序中,用該子程序名作為匯編代碼段的標(biāo)識(shí),定義程序代碼,最后用“MOVPC,LR”指令返回。
(2)匯編程序中用偽指令EXPORT導(dǎo)出子程序名。
(3)?C程序中用關(guān)鍵字extern聲明該匯編子程序的函數(shù)原型,然后就可在C程序中訪問該函數(shù)。
(4)函數(shù)調(diào)用時(shí)的參數(shù)傳遞規(guī)則:寄存器組中的{R0-R3}作為參數(shù)傳遞而返回值用寄存器R0返回;如果參數(shù)數(shù)目超過4個(gè),則使用堆棧進(jìn)行傳遞。
C程序調(diào)用匯編程序的例子如程序清單4-15所示。4.4.4C程序中內(nèi)嵌匯編代碼
C程序中內(nèi)嵌的匯編代碼可實(shí)現(xiàn)一些高級(jí)語言不便實(shí)現(xiàn)的功能,并且同時(shí)支持ARM和Thumb指令,可提高執(zhí)行效率;但是不能直接引用C語言里定義的變量,數(shù)據(jù)交換必須遵守ATPCS的規(guī)定。
C程序中內(nèi)嵌的匯編代碼可使用大部分的ARM和Thumb指令,但存在一些限制,主要如下:
(1)不能直接向寄存器PC賦值,程序跳轉(zhuǎn)要使用指令B或者BL。
(2)在訪問物理寄存器時(shí),不要使用過于復(fù)雜的C表達(dá)式,避免物理寄存器沖突。
(3)?R12和R13常被編譯器用來存放中間編譯結(jié)果,計(jì)算表達(dá)式值時(shí)可能將R0~R3、R12及R14用于子程序調(diào)用,因此要避免直接使用這些物理寄存器。
(4)一般不要直接指定物理寄存器,而讓編譯器進(jìn)行分配。
(5)內(nèi)嵌匯編代碼中定義的變量不能在C函數(shù)體中訪問,但
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度牛只養(yǎng)殖保險(xiǎn)理賠服務(wù)合同協(xié)議2篇
- 2024年茶樓文化藝術(shù)交流合同
- 2024房產(chǎn)推廣服務(wù)合同范本大全
- 2024版水電安裝工程合同書
- 二零二五年城市冷鏈配送服務(wù)合作框架協(xié)議3篇
- 2024年特定擔(dān)保合同終止條款版B版
- 2024版國(guó)際貿(mào)易協(xié)議:標(biāo)的物選擇與規(guī)范詳解版B版
- 2025年度樓頂廣告牌安裝與戶外廣告策略咨詢合同2篇
- 2024年股權(quán)轉(zhuǎn)讓協(xié)議(附條件生效)3篇
- 體育賽事流程
- 《業(yè)務(wù)員銷售技巧》課件
- 《汽車涂裝》2024-2025學(xué)年第一學(xué)期工學(xué)一體化課程教學(xué)進(jìn)度計(jì)劃表
- 水廠安全管理培訓(xùn)
- 江西省贛州市2023-2024學(xué)年高一上學(xué)期期末考試化學(xué)試題 附答案
- 消化道出血護(hù)理常規(guī)課件
- 2024年物流運(yùn)輸公司全年安全生產(chǎn)工作計(jì)劃例文(4篇)
- 二零二四年度軟件開發(fā)合同:凈水器智能控制系統(tǒng)定制開發(fā)協(xié)議3篇
- 貴州省銅仁市2023-2024學(xué)年高二上學(xué)期期末質(zhì)量監(jiān)測(cè)試題 地理 含答案
- 糖尿病肌少癥
- 期末卷(一)-2023-2024學(xué)年高一年級(jí)地理上學(xué)期高頻考題期末測(cè)試卷(江蘇專用)(原卷版)
- 山東師范大學(xué)《古代文學(xué)專題(一)》期末復(fù)習(xí)題
評(píng)論
0/150
提交評(píng)論