第4章程序設(shè)計_第1頁
第4章程序設(shè)計_第2頁
第4章程序設(shè)計_第3頁
第4章程序設(shè)計_第4頁
第4章程序設(shè)計_第5頁
已閱讀5頁,還剩28頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、1匯編語言程序設(shè)計C和匯編的函數(shù)相互調(diào)用 2計算計算1 1100100的累加和的累加和匯編必須有一個主函數(shù)的標(biāo)號匯編必須有一個主函數(shù)的標(biāo)號“_main”_main”,而且必須聲明此而且必須聲明此“_main”_main”為全局型標(biāo)號。為全局型標(biāo)號。用戶不用考慮程序代碼的實際的物理地址,用戶不用考慮程序代碼的實際的物理地址,而是通過偽指令通知編譯器把程序代碼定位而是通過偽指令通知編譯器把程序代碼定位在什么類型的存儲單元,具體地址由編譯器在什么類型的存儲單元,具體地址由編譯器管理。管理。程序用偽指令程序用偽指令.RAM.RAM在數(shù)據(jù)存儲區(qū)內(nèi)聲明了一在數(shù)據(jù)存儲區(qū)內(nèi)聲明了一個變量個變量G_Sum,G_

2、Sum,變量名變量名G_SumG_Sum實際上代表了實際上代表了變量的地址變量的地址, ,對變量進行讀寫操作時,則需要對變量進行讀寫操作時,則需要用用G_SumG_Sum來表示變量中的實際內(nèi)容。來表示變量中的實際內(nèi)容。C C的編譯器的編譯器GCCGCC把把C C語言代碼編譯為匯編代語言代碼編譯為匯編代碼,匯編編譯器碼,匯編編譯器Xasm16Xasm16對匯編代碼進行編對匯編代碼進行編譯成為目標(biāo)文件。鏈接器將目標(biāo)文件、庫函譯成為目標(biāo)文件。鏈接器將目標(biāo)文件、庫函數(shù)模塊、資源文件連接成整體,形成一個可數(shù)模塊、資源文件連接成整體,形成一個可在芯片上運行的可執(zhí)行文件。在芯片上運行的可執(zhí)行文件。偽指令程序

3、指令立即數(shù)31.匯編語言語句格式匯編語言語句格式: 標(biāo)號:標(biāo)號: 指令指令 ;或;或/ 標(biāo)號標(biāo)號以冒號結(jié)束,作為指令所在地址的符號表示。標(biāo)號按使以冒號結(jié)束,作為指令所在地址的符號表示。標(biāo)號按使用范圍分為全局標(biāo)號和局部標(biāo)號兩種;用范圍分為全局標(biāo)號和局部標(biāo)號兩種; 指令指令分為硬指令和偽指令兩種;分為硬指令和偽指令兩種; 注釋注釋僅作為程序編寫與閱讀時的參考,匯編器不對其作任何僅作為程序編寫與閱讀時的參考,匯編器不對其作任何處理。注釋行必須用分號處理。注釋行必須用分號(;)或雙斜線或雙斜線(/)起始,可與指令在起始,可與指令在同一行,也可在指令的前一行或后一行同一行,也可在指令的前一行或后一行。

4、偽指令偽指令不必區(qū)分字母的大小寫,但所有定義的標(biāo)號包括宏名、不必區(qū)分字母的大小寫,但所有定義的標(biāo)號包括宏名、結(jié)構(gòu)名、結(jié)構(gòu)變量名、段名及程序名,其字母大小寫一律區(qū)結(jié)構(gòu)名、結(jié)構(gòu)變量名、段名及程序名,其字母大小寫一律區(qū)分開。分開。42.數(shù)制、數(shù)據(jù)類型與參數(shù)數(shù)制、數(shù)據(jù)類型與參數(shù) nSP的匯編器將十進制作為默認(rèn)數(shù)制。十六進制可用的匯編器將十進制作為默認(rèn)數(shù)制。十六進制可用符號符號0 x或或$作為前綴,或用符號作為前綴,或用符號H作為后綴。作為后綴。數(shù)制后綴二進制B八進制O或Q十進制D或不寫十六進制HASCII字符串用雙引號或單引號括起52.數(shù)制、數(shù)據(jù)類型與參數(shù)數(shù)制、數(shù)據(jù)類型與參數(shù) nSP匯編指令中所用的數(shù)

5、據(jù)類型匯編指令中所用的數(shù)據(jù)類型 匯編指令中的參數(shù)可以是常數(shù),也可以是表達式。常數(shù)參匯編指令中的參數(shù)可以是常數(shù),也可以是表達式。常數(shù)參數(shù)基本有數(shù)值型和字符串型兩種。數(shù)基本有數(shù)值型和字符串型兩種。63.全局標(biāo)號與局部標(biāo)號全局標(biāo)號與局部標(biāo)號 全局標(biāo)號全局標(biāo)號是指在源程序的是指在源程序的各個程序段中均能調(diào)用各個程序段中均能調(diào)用的標(biāo)號,的標(biāo)號,而局部標(biāo)號則指而局部標(biāo)號則指僅在各個所定義的程序段中調(diào)用僅在各個所定義的程序段中調(diào)用的標(biāo)號的標(biāo)號。 全局標(biāo)號原則上可以由任意數(shù)量的字母和數(shù)字字符組成,全局標(biāo)號原則上可以由任意數(shù)量的字母和數(shù)字字符組成,但只有但只有前前32位位是是有效有效的。它可以寫在文件中的任何一

6、行上,的。它可以寫在文件中的任何一行上,但但必須以字母字符或下劃線(必須以字母字符或下劃線(_)開頭)開頭,且,且標(biāo)號名后須以冒標(biāo)號名后須以冒號(:)來結(jié)束號(:)來結(jié)束。73.全局標(biāo)號與局部標(biāo)號全局標(biāo)號與局部標(biāo)號 局部標(biāo)號只有在局部標(biāo)號只有在局部區(qū)域內(nèi)定義局部區(qū)域內(nèi)定義才有效。正是這種約束才才有效。正是這種約束才使得局部標(biāo)號的定義可以安全地重復(fù)使用在整個程序各處使得局部標(biāo)號的定義可以安全地重復(fù)使用在整個程序各處而不致產(chǎn)生混亂錯誤。而不致產(chǎn)生混亂錯誤。 局部標(biāo)號也像全局標(biāo)號那樣局部標(biāo)號也像全局標(biāo)號那樣最多可有最多可有32個字母或數(shù)字字符個字母或數(shù)字字符,且且必須以字母字符或問號(?)開頭必須以

7、字母字符或問號(?)開頭。nSP的匯編器的匯編器通常規(guī)定用問號(?)作為局部標(biāo)號的前綴或后綴。通常規(guī)定用問號(?)作為局部標(biāo)號的前綴或后綴。 在不同的局部區(qū)域里所定義的局部標(biāo)號都有不同的含義,在不同的局部區(qū)域里所定義的局部標(biāo)號都有不同的含義,且標(biāo)號且標(biāo)號?a是不同于標(biāo)號是不同于標(biāo)號a?的。的。 切忌將諸如切忌將諸如“+、-、*、/”這類運算符用在局部標(biāo)號中。這類運算符用在局部標(biāo)號中。 8 程序的最基本結(jié)構(gòu)形式有順序、分支、循環(huán)、子程序四種程序的最基本結(jié)構(gòu)形式有順序、分支、循環(huán)、子程序四種結(jié)構(gòu)。結(jié)構(gòu)。 分支結(jié)構(gòu)分為分支結(jié)構(gòu)分為雙分支結(jié)構(gòu)雙分支結(jié)構(gòu)和和多分支結(jié)構(gòu)多分支結(jié)構(gòu)兩種。在程序體中,兩種。在

8、程序體中,根據(jù)不同的條件執(zhí)行不同的動作,在某一確定的條件下,根據(jù)不同的條件執(zhí)行不同的動作,在某一確定的條件下,只能執(zhí)行多個分支中的一個分支。只能執(zhí)行多個分支中的一個分支。 由于高級語言提供了由于高級語言提供了IF. ELSE語句,使得分支結(jié)構(gòu)的層語句,使得分支結(jié)構(gòu)的層次清晰,分支路徑明確。然而次清晰,分支路徑明確。然而在匯編語言在匯編語言中,只能依靠中,只能依靠跳跳轉(zhuǎn)語句轉(zhuǎn)語句實現(xiàn)這樣的結(jié)構(gòu)。實現(xiàn)這樣的結(jié)構(gòu)。9匯編語言實現(xiàn)分兩分支路徑的方式 匯編語言實現(xiàn)多重分支方式 10 循環(huán)程序可以有兩種結(jié)構(gòu)形式,一種是循環(huán)程序可以有兩種結(jié)構(gòu)形式,一種是WHILE_DO結(jié)構(gòu)形結(jié)構(gòu)形式;另一種是式;另一種是D

9、O_WHILE結(jié)構(gòu)形式。結(jié)構(gòu)形式。 循環(huán)程序一般由循環(huán)程序一般由3個主要部分組成:個主要部分組成:初始化部分初始化部分、循環(huán)體循環(huán)體。循環(huán)控制部分循環(huán)控制部分。WHILE_DO結(jié)構(gòu)DO_WHILE結(jié)構(gòu)11程序程序舉例:數(shù)據(jù)搬運舉例:數(shù)據(jù)搬運 把內(nèi)存中地址為把內(nèi)存中地址為0 x00000 x00000 x00060 x0006中的數(shù)據(jù),移到地址為中的數(shù)據(jù),移到地址為0 x00100 x00100 x00160 x0016中中.IRAM .IRAM Label: Label: .DW 0 x0001,0 x0002,0 x0003,0 x0004,0 x0005,0 x0006,0 x0007;

10、.DW 0 x0001,0 x0002,0 x0003,0 x0004,0 x0005,0 x0006,0 x0007; .VAR C_Move_To_Position=0 x0010; /.VAR C_Move_To_Position=0 x0010; /定義起始地址;定義起始地址; .CODE .CODE .PUBLIC _main; .PUBLIC _main; _main: _main: R1=7; / R1=7; /設(shè)置要移動的數(shù)據(jù)的個數(shù)設(shè)置要移動的數(shù)據(jù)的個數(shù) R2=C_Move_To_Position; R2=C_Move_To_Position; BP=Label; BP=Lab

11、el; L_Loop: L_Loop: R3=BP; / R3=BP; /被移動的數(shù)據(jù)送入被移動的數(shù)據(jù)送入r3 r3 R2=R3; / R2=R3; / 被移動的數(shù)據(jù)送往目的地址被移動的數(shù)據(jù)送往目的地址 BP+=1; / BP+=1; /源地址加源地址加1 1 R2=R2+1; / R2=R2+1; /目的地址加目的地址加1 1 R1-=1; / R1-=1; /計數(shù)減計數(shù)減1 1 JNZ L_Loop; JNZ L_Loop; MainLoop: MainLoop: jmp MainLoop; jmp MainLoop; .END.END12 在某些問題的處理中,僅采在某些問題的處理中,僅采

12、用單循環(huán)往往不夠,還必須用單循環(huán)往往不夠,還必須采用多重循環(huán)才能解決。采用多重循環(huán)才能解決。 所謂所謂多重循環(huán)多重循環(huán)是指在循環(huán)程是指在循環(huán)程序中嵌套有其它循環(huán)程序。序中嵌套有其它循環(huán)程序。 多重循環(huán)程序設(shè)計的基本方多重循環(huán)程序設(shè)計的基本方法和單重循環(huán)程序設(shè)計是一法和單重循環(huán)程序設(shè)計是一致的,應(yīng)分別考慮各重循環(huán)致的,應(yīng)分別考慮各重循環(huán)的的控制條件控制條件及其程序?qū)崿F(xiàn),及其程序?qū)崿F(xiàn),相互之間不能混淆。相互之間不能混淆。多重循環(huán)結(jié)構(gòu) 13 實際應(yīng)用中,經(jīng)常會遇到在同一程序中,須要多次進行一實際應(yīng)用中,經(jīng)常會遇到在同一程序中,須要多次進行一些相同的計算和操作,可以采用子程序的概念,將一些重些相同的計

13、算和操作,可以采用子程序的概念,將一些重復(fù)使用的程序標(biāo)準(zhǔn)化,使之成為一個獨立的程序段,需要復(fù)使用的程序標(biāo)準(zhǔn)化,使之成為一個獨立的程序段,需要時調(diào)用即可,我們就把這些程序段稱作為子程序。時調(diào)用即可,我們就把這些程序段稱作為子程序。 子程序的結(jié)構(gòu)包括三個部分:子程序的結(jié)構(gòu)包括三個部分:1.子程序的定義聲明和開始子程序的定義聲明和開始標(biāo)號部分;標(biāo)號部分;2.子程序的實體內(nèi)容部分,表明程序?qū)⑦M行怎子程序的實體內(nèi)容部分,表明程序?qū)⑦M行怎樣的操作;樣的操作;3.子程序的結(jié)束標(biāo)號部分。子程序的結(jié)束標(biāo)號部分。14 程序的調(diào)用包括主程序調(diào)用子程程序的調(diào)用包括主程序調(diào)用子程序,子程序調(diào)用子程序等。程序序,子程序調(diào)

14、用子程序等。程序調(diào)用是通過調(diào)用指令調(diào)用是通過調(diào)用指令CALL來實來實現(xiàn)的。現(xiàn)的。 程序執(zhí)行的過程中,當(dāng)遇到調(diào)用程序執(zhí)行的過程中,當(dāng)遇到調(diào)用子程序指令,子程序指令,CPU便會將便會將下一條下一條指令的地址壓入堆棧指令的地址壓入堆棧暫時保護起暫時保護起來,然后轉(zhuǎn)到被調(diào)用的子程序入來,然后轉(zhuǎn)到被調(diào)用的子程序入口 去口 去 執(zhí) 行 子 程 序執(zhí) 行 子 程 序 , 當(dāng) 執(zhí) 行 到, 當(dāng) 執(zhí) 行 到RETF時返回,時返回,CPU又將又將堆棧中堆棧中的返回地址彈出送到的返回地址彈出送到PC,繼續(xù)執(zhí),繼續(xù)執(zhí)行原來的程序。行原來的程序。子程序調(diào)用過程 15 在程序調(diào)用的過程中,需要注意到的問題是在程序調(diào)用的過

15、程中,需要注意到的問題是斷點的現(xiàn)場保斷點的現(xiàn)場保護護。通常的做法是用。通常的做法是用堆棧堆棧對現(xiàn)場進行保護,在子程序開始對現(xiàn)場進行保護,在子程序開始就把子程序就把子程序要破壞掉的寄存器的內(nèi)容壓棧保護要破壞掉的寄存器的內(nèi)容壓棧保護,當(dāng)子程序,當(dāng)子程序結(jié)束的時候,再結(jié)束的時候,再彈?;謴?fù)現(xiàn)場彈棧恢復(fù)現(xiàn)場。 程序調(diào)用的過程都伴隨著程序調(diào)用的過程都伴隨著參數(shù)的傳遞參數(shù)的傳遞,正確的參數(shù)傳遞要,正確的參數(shù)傳遞要滿足滿足入口入口和和出口出口條件。條件。16 入口條件入口條件指執(zhí)行子程序時所必需的有關(guān)寄存器內(nèi)容或源程指執(zhí)行子程序時所必需的有關(guān)寄存器內(nèi)容或源程序的存儲器的存儲地址等,主程序調(diào)用子程序時必須先滿

16、序的存儲器的存儲地址等,主程序調(diào)用子程序時必須先滿足入口條件,即足入口條件,即滿足子程序?qū)斎雲(yún)?shù)的約定。滿足子程序?qū)斎雲(yún)?shù)的約定。 出口條件出口條件就是指子程序執(zhí)行完后將就是指子程序執(zhí)行完后將運算結(jié)果所存放的寄存運算結(jié)果所存放的寄存器或存儲器地址器或存儲器地址等,也就是說,等,也就是說,必須確定主程序?qū)敵鰠⒈仨毚_定主程序?qū)敵鰠?shù)的約定。數(shù)的約定。 參數(shù)的傳遞有以下幾種情況:參數(shù)的傳遞有以下幾種情況: 1) 通過寄存器傳遞通過寄存器傳遞 2) 通過變量傳遞通過變量傳遞 3) 通過堆棧傳遞通過堆棧傳遞 17(1)通過寄存器傳遞參數(shù)通過寄存器傳遞參數(shù) 寄存器傳遞參數(shù),是最常用的一種參數(shù)傳遞的

17、方式。我們寄存器傳遞參數(shù),是最常用的一種參數(shù)傳遞的方式。我們常用到的傳遞參數(shù)的寄存器有常用到的傳遞參數(shù)的寄存器有4個個,分別為,分別為R1R4。 在程序調(diào)用的過程中,寄存器中的值也會被帶到被調(diào)用的在程序調(diào)用的過程中,寄存器中的值也會被帶到被調(diào)用的子程序中供子程序使用。子程序運算結(jié)束后返回主程序,子程序中供子程序使用。子程序運算結(jié)束后返回主程序,這些寄存器的新值也會被帶到主程序中繼續(xù)參加主程序的這些寄存器的新值也會被帶到主程序中繼續(xù)參加主程序的運算。運算。通過寄存器傳遞參數(shù) 18(2)通過變量傳遞參數(shù)通過變量傳遞參數(shù) 通過變量進行的參數(shù)傳遞,主要是通過通過變量進行的參數(shù)傳遞,主要是通過全局型變量

18、全局型變量實現(xiàn)的。實現(xiàn)的。 如果在某個匯編文件中定義了一個全局變量(如果在某個匯編文件中定義了一個全局變量(.PUBLIC),那),那么此匯編文件中的所有匯編代碼都能夠使用這個變量。同時該么此匯編文件中的所有匯編代碼都能夠使用這個變量。同時該變量也起到了參數(shù)傳遞的作用。變量也起到了參數(shù)傳遞的作用。 利用變量傳遞參數(shù) 19(3)通過堆棧傳遞參數(shù)通過堆棧傳遞參數(shù) 在在C函數(shù)與匯編函數(shù)的相互調(diào)用過程中,主要函數(shù)與匯編函數(shù)的相互調(diào)用過程中,主要通過堆棧來傳遞通過堆棧來傳遞參數(shù)參數(shù),而在函數(shù)返回時,則,而在函數(shù)返回時,則采用寄存器來傳遞返回值采用寄存器來傳遞返回值。 在主程序把要傳遞的參數(shù)壓入堆棧,然后

19、調(diào)用子程序。子程序在主程序把要傳遞的參數(shù)壓入堆棧,然后調(diào)用子程序。子程序從堆棧中尋找需要的參數(shù)進行處理。當(dāng)子程序返回后,主程序從堆棧中尋找需要的參數(shù)進行處理。當(dāng)子程序返回后,主程序需要進行彈棧處理,以恢復(fù)參數(shù)壓入堆棧前的堆棧狀態(tài)。需要進行彈棧處理,以恢復(fù)參數(shù)壓入堆棧前的堆棧狀態(tài)。 IDE開發(fā)環(huán)境中的開發(fā)環(huán)境中的C語言與匯編語言的相互調(diào)用就是采用堆棧傳語言與匯編語言的相互調(diào)用就是采用堆棧傳遞參數(shù)及寄存器返回參數(shù)的方式。遞參數(shù)及寄存器返回參數(shù)的方式。堆棧傳遞參數(shù) 201.子程序的嵌套子程序的嵌套 子程序嵌套就是指子程序調(diào)用子程序。其中嵌套的層數(shù)稱為嵌套深度。子程序嵌套就是指子程序調(diào)用子程序。其中嵌

20、套的層數(shù)稱為嵌套深度。211.子程序的嵌套子程序的嵌套 子程序嵌套要子程序嵌套要注意注意以下幾個方面:以下幾個方面: (1)寄存器的保護和恢復(fù),以避免各層子程序之間發(fā)生因)寄存器的保護和恢復(fù),以避免各層子程序之間發(fā)生因寄存器沖突而出錯的情況。寄存器沖突而出錯的情況。 (2)程序中如果使用了堆棧來傳遞參數(shù),應(yīng)對堆棧小心操)程序中如果使用了堆棧來傳遞參數(shù),應(yīng)對堆棧小心操作,避免堆棧使用不當(dāng)造成子程序不能正確返回的出錯情作,避免堆棧使用不當(dāng)造成子程序不能正確返回的出錯情況。況。(3)子程序的嵌套層數(shù)不是無限的。堆棧是在數(shù)據(jù)存儲區(qū))子程序的嵌套層數(shù)不是無限的。堆棧是在數(shù)據(jù)存儲區(qū)內(nèi)開辟的空間,內(nèi)開辟的空

21、間,SPCE061A的數(shù)據(jù)存儲空間為的數(shù)據(jù)存儲空間為2K字。字。222. 子程序的遞歸子程序的遞歸 遞歸調(diào)用是指子程序遞歸調(diào)用是指子程序調(diào)用子程序本身調(diào)用子程序本身。 進行遞歸調(diào)用需注意的是:一個遞歸程序進行遞歸調(diào)用需注意的是:一個遞歸程序必須有一個能夠必須有一個能夠退出遞歸調(diào)用的測試語句退出遞歸調(diào)用的測試語句。如果無條件地進行遞歸調(diào)用,。如果無條件地進行遞歸調(diào)用,會使堆棧空間溢出,導(dǎo)致嚴(yán)重錯誤。會使堆??臻g溢出,導(dǎo)致嚴(yán)重錯誤。23函數(shù)調(diào)用協(xié)議 所謂調(diào)用協(xié)議,指不同的子程序代碼之間形成的一種握手通訊接口,并完成一個子程序到另外一個子程序的參數(shù)傳遞和控制,以及定義出子程序調(diào)用與子程序返回值的規(guī)則。24 調(diào)用協(xié)議包

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論