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

下載本文檔

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

文檔簡(jiǎn)介

1、第4章 程序設(shè)計(jì)方法第4章 子程序設(shè)計(jì)子程序設(shè)計(jì) 本章著重講述本章著重講述6個(gè)方面的內(nèi)容:個(gè)方面的內(nèi)容:(1)如何通過偽指令如何通過偽指令PROC-ENDP在匯編源程在匯編源程序中定義一個(gè)子程序。序中定義一個(gè)子程序。(2)CALL調(diào)用指令的調(diào)用指令的4種使用形式和返回地址種使用形式和返回地址的保存。的保存。(3)RET返回指令的返回指令的4種使用形式。種使用形式。(4)在子程序中進(jìn)行現(xiàn)場(chǎng)保護(hù)和現(xiàn)場(chǎng)恢復(fù)。在子程序中進(jìn)行現(xiàn)場(chǎng)保護(hù)和現(xiàn)場(chǎng)恢復(fù)。(5)調(diào)用程序與子程序問的調(diào)用程序與子程序問的3種參數(shù)傳遞方法。種參數(shù)傳遞方法。(6)利用利用DOS提供的系統(tǒng)功能調(diào)用,實(shí)現(xiàn)數(shù)據(jù)提供的系統(tǒng)功能調(diào)用,實(shí)現(xiàn)數(shù)據(jù)的輸

2、入與輸出。的輸入與輸出。開開 始始第4章 程序設(shè)計(jì)方法4.1子程序的定義和格式及設(shè)計(jì)步驟子程序的定義和格式及設(shè)計(jì)步驟 4.1.1 子程序的定義和格式子程序的定義和格式4.1.2 子程序的設(shè)計(jì)步驟和子程序的說明文件子程序的設(shè)計(jì)步驟和子程序的說明文件返回本章首頁返回本章首頁第4章 程序設(shè)計(jì)方法4.1.1 子程序的定義和格式子程序的定義和格式在匯編語言中,要使某一程序段成為一個(gè)子程序,必須在匯編語言中,要使某一程序段成為一個(gè)子程序,必須首先通過過程定義偽指令首先通過過程定義偽指令PROC和和ENDP來把它定義成為一個(gè)子程序。來把它定義成為一個(gè)子程序。過程定義格式:過程定義格式: PROC NEAR/

3、FAR;NEAR表示過程在本表示過程在本代碼段內(nèi),代碼段內(nèi),F(xiàn)AR表示過程在其他代碼段內(nèi),表示過程在其他代碼段內(nèi), ; RET ;返回指令;返回指令 ENDP子程序可以采用子程序可以采用CALL指令來調(diào)用。調(diào)用一個(gè)過程的格指令來調(diào)用。調(diào)用一個(gè)過程的格式為:式為:CALL 過程名過程名返回本節(jié)返回本節(jié)第4章 程序設(shè)計(jì)方法其中其中與標(biāo)號(hào)類似,具有與標(biāo)號(hào)類似,具有3種屬性種屬性(偏移、段和類偏移、段和類型型),它也是所定義子程序入,它也是所定義子程序入口的符號(hào)地址。類型屬性中的口的符號(hào)地址。類型屬性中的NEAR和和FAR指明該段的指明該段的調(diào)用范圍。調(diào)用范圍。NEAR表示段內(nèi)調(diào)用,即指調(diào)用程序表示段

4、內(nèi)調(diào)用,即指調(diào)用程序(主主程序程序)和子程序在同一個(gè)代碼段中。如果一個(gè)子程序和子程序在同一個(gè)代碼段中。如果一個(gè)子程序定義為是段內(nèi)調(diào)用的,那么在定義中可以省略定義為是段內(nèi)調(diào)用的,那么在定義中可以省略NEAR不寫。不寫。FAR表示段間調(diào)用,即指調(diào)用程序和子程序表示段間調(diào)用,即指調(diào)用程序和子程序分別在兩個(gè)不同的代碼段中。如果一個(gè)子程序定義分別在兩個(gè)不同的代碼段中。如果一個(gè)子程序定義為是段間調(diào)用的,那么在定義中不能省略為是段間調(diào)用的,那么在定義中不能省略FAR。 第4章 程序設(shè)計(jì)方法4.1.2 子程序的設(shè)計(jì)步驟和子程序的說明文件子程序的設(shè)計(jì)步驟和子程序的說明文件匯編語言程序設(shè)計(jì)一般有以下幾個(gè)步驟:匯編

5、語言程序設(shè)計(jì)一般有以下幾個(gè)步驟:1確定子程序的名稱和調(diào)用類型。確定子程序的名稱和調(diào)用類型。2確定子程序完成的功能。確定子程序完成的功能。3確定子程序運(yùn)行時(shí)所需的入口參數(shù),以及主程序與確定子程序運(yùn)行時(shí)所需的入口參數(shù),以及主程序與子程序之間的入口參數(shù)傳遞方式。子程序之間的入口參數(shù)傳遞方式。4確定子程序返回時(shí),將運(yùn)算結(jié)果(即出口參數(shù))以確定子程序返回時(shí),將運(yùn)算結(jié)果(即出口參數(shù))以什么方式提交給主程序。什么方式提交給主程序。5確定子程序運(yùn)行時(shí)使用寄存器和內(nèi)存單元的情況,確定子程序運(yùn)行時(shí)使用寄存器和內(nèi)存單元的情況,并進(jìn)行現(xiàn)場(chǎng)保護(hù)。并進(jìn)行現(xiàn)場(chǎng)保護(hù)。6編寫子程序的說明文件。編寫子程序的說明文件。第4章 程序

6、設(shè)計(jì)方法【例【例4-1】子程序的說明文件示例】子程序的說明文件示例 后面將要講到的【例后面將要講到的【例4-11】中子程序的說明文件】中子程序的說明文件1子程序名:子程序名:BCD-16B;2子程序完成的功能:將一組分離子程序完成的功能:將一組分離BCD數(shù)轉(zhuǎn)換成數(shù)轉(zhuǎn)換成16位二進(jìn)位二進(jìn)制數(shù);制數(shù);3子程序的入口參數(shù):待轉(zhuǎn)換的分離子程序的入口參數(shù):待轉(zhuǎn)換的分離BCD數(shù)在內(nèi)存中的首數(shù)在內(nèi)存中的首地址,在地址,在ES:SI,BCD數(shù)的字節(jié)數(shù)存放在寄存器數(shù)的字節(jié)數(shù)存放在寄存器CX中;中;4子程序的出口參數(shù):轉(zhuǎn)換成的子程序的出口參數(shù):轉(zhuǎn)換成的16位二進(jìn)制數(shù),在位二進(jìn)制數(shù),在DX中:中:5子程序用到的寄存

7、器:子程序用到的寄存器:CX,DX,ES,SI;6典型例子。典型例子。第4章 程序設(shè)計(jì)方法返回本節(jié)返回本節(jié)若內(nèi)存中的若內(nèi)存中的BCD數(shù)定義為:數(shù)定義為:BCD DB 00H,04H,00H,01H,00H;即;即BCD數(shù)是數(shù)是01040D0000010000010000B當(dāng)當(dāng)(ES) = BCD的段地址,的段地址,(ST)= BCD的偏移地址,的偏移地址,(CX)=5結(jié)果結(jié)果(DX) = 0000010000010000B本子程序中雖還用到了寄存器本子程序中雖還用到了寄存器AX和和BX,但由于在子程序中已將相,但由于在子程序中已將相應(yīng)內(nèi)容保護(hù)入棧,所以,從調(diào)用程序來看,子程序?qū)@兩個(gè)寄應(yīng)內(nèi)容保

8、護(hù)入棧,所以,從調(diào)用程序來看,子程序?qū)@兩個(gè)寄存器的內(nèi)容沒有影響。存器的內(nèi)容沒有影響。第4章 程序設(shè)計(jì)方法4.2 子程序的調(diào)用和返回子程序的調(diào)用和返回主程序中是通過使用主程序中是通過使用CALL指令來實(shí)現(xiàn)對(duì)子程序的調(diào)用的。指令來實(shí)現(xiàn)對(duì)子程序的調(diào)用的。而子程序執(zhí)行完畢后返回而子程序執(zhí)行完畢后返回到主程序,則是通過子程序中的到主程序,則是通過子程序中的RET指令來完成的。當(dāng)執(zhí)指令來完成的。當(dāng)執(zhí)行中遇到行中遇到CALL 指令時(shí),就轉(zhuǎn)移到名為指令時(shí),就轉(zhuǎn)移到名為的子程序去執(zhí)的子程序去執(zhí)行,當(dāng)子程序執(zhí)行到指令行,當(dāng)子程序執(zhí)行到指令RET時(shí),就返回主程序的指令時(shí),就返回主程序的指令CALL 的下一條指令的

9、下一條指令(一般都稱其為斷點(diǎn)一般都稱其為斷點(diǎn));接著,又回到主程序里;接著,又回到主程序里執(zhí)行。執(zhí)行。 返回本章首頁返回本章首頁第4章 程序設(shè)計(jì)方法調(diào)用子程序有時(shí)也稱為調(diào)用子程序有時(shí)也稱為“轉(zhuǎn)子轉(zhuǎn)子”,即,即“轉(zhuǎn)移到轉(zhuǎn)移到子程序入口處執(zhí)行子程序入口處執(zhí)行”的意思。當(dāng)要轉(zhuǎn)去執(zhí)的意思。當(dāng)要轉(zhuǎn)去執(zhí)行的子程序定義為段內(nèi)調(diào)用時(shí),為了轉(zhuǎn)移到子行的子程序定義為段內(nèi)調(diào)用時(shí),為了轉(zhuǎn)移到子程序入口處,只需修改程序入口處,只需修改IP寄存器的內(nèi)容即可。寄存器的內(nèi)容即可。當(dāng)要轉(zhuǎn)去執(zhí)行的子程序定義為段間調(diào)用時(shí),當(dāng)要轉(zhuǎn)去執(zhí)行的子程序定義為段間調(diào)用時(shí),意味著意味著“調(diào)用調(diào)用”要轉(zhuǎn)移到另一個(gè)段去執(zhí)行,要轉(zhuǎn)移到另一個(gè)段去執(zhí)行,

10、這時(shí)的子程序入口地址轉(zhuǎn)移到新的段地址和這時(shí)的子程序入口地址轉(zhuǎn)移到新的段地址和偏移地址,此時(shí)不僅要修改寄存器偏移地址,此時(shí)不僅要修改寄存器IP的內(nèi)容,的內(nèi)容,還要修改寄存器還要修改寄存器CS的內(nèi)容。的內(nèi)容。第4章 程序設(shè)計(jì)方法4.2.1調(diào)用與返回指令調(diào)用與返回指令1. 調(diào)用指令調(diào)用指令CALL程序程序“調(diào)用調(diào)用”,意味著程序的執(zhí)行離開了,意味著程序的執(zhí)行離開了“原來的地方原來的地方”,形成,形成“斷斷點(diǎn)點(diǎn)”,轉(zhuǎn)去執(zhí)行子程,轉(zhuǎn)去執(zhí)行子程序。子程序執(zhí)行完畢后,又要回到序。子程序執(zhí)行完畢后,又要回到“斷點(diǎn)斷點(diǎn)”,繼續(xù)執(zhí)行原來的程序。,繼續(xù)執(zhí)行原來的程序。為此,必須先做好返回地址的保存,即調(diào)用程序現(xiàn)場(chǎng)的

11、保護(hù)工作,為此,必須先做好返回地址的保存,即調(diào)用程序現(xiàn)場(chǎng)的保護(hù)工作,以便調(diào)用程序現(xiàn)場(chǎng)的恢復(fù)。所以,調(diào)用指令的基本功能的第一步,以便調(diào)用程序現(xiàn)場(chǎng)的恢復(fù)。所以,調(diào)用指令的基本功能的第一步,是將返回地址(也稱斷點(diǎn)地址),即調(diào)用指令的下一條指令的地是將返回地址(也稱斷點(diǎn)地址),即調(diào)用指令的下一條指令的地址壓入堆棧。并按照某種尋址方式轉(zhuǎn)向子程序的入口。子程序執(zhí)址壓入堆棧。并按照某種尋址方式轉(zhuǎn)向子程序的入口。子程序執(zhí)行完畢后,再從堆棧中彈出返回地址。因此,必須牢記堆棧操作行完畢后,再從堆棧中彈出返回地址。因此,必須牢記堆棧操作“先進(jìn)后出先進(jìn)后出”的原則,以免失誤。的原則,以免失誤。子程序入口地址的尋址方式

12、與無條件轉(zhuǎn)移指令的尋址方式基本相同。子程序入口地址的尋址方式與無條件轉(zhuǎn)移指令的尋址方式基本相同。調(diào)用指令同樣可以調(diào)用指令同樣可以分為段內(nèi)調(diào)用與段間調(diào)用:段內(nèi)調(diào)用又分為相對(duì)尋址和間接尋址;段分為段內(nèi)調(diào)用與段間調(diào)用:段內(nèi)調(diào)用又分為相對(duì)尋址和間接尋址;段間調(diào)用則又分為直接尋址與間接尋址兩種尋址方式。間調(diào)用則又分為直接尋址與間接尋址兩種尋址方式。第4章 程序設(shè)計(jì)方法為了實(shí)現(xiàn)主程序調(diào)用子程序以及子程序自動(dòng)返回主程序。幾乎所有指為了實(shí)現(xiàn)主程序調(diào)用子程序以及子程序自動(dòng)返回主程序。幾乎所有指令系統(tǒng)都提供一組令系統(tǒng)都提供一組調(diào)用和返回指令。關(guān)于調(diào)用和返回指令。關(guān)于80868088指令系統(tǒng)中的調(diào)用與返回指令的助指

13、令系統(tǒng)中的調(diào)用與返回指令的助記符格式以及指令基本功能的討論如下:記符格式以及指令基本功能的討論如下:段內(nèi)調(diào)用的相對(duì)尋址方式段內(nèi)調(diào)用的相對(duì)尋址方式對(duì)于段內(nèi)調(diào)用指令,相對(duì)尋址方式的位移量只有對(duì)于段內(nèi)調(diào)用指令,相對(duì)尋址方式的位移量只有16位一種,也就是它位一種,也就是它沒有短調(diào)用。其沒有短調(diào)用。其指令形式為指令形式為 CALL 該指令的功能是:先將當(dāng)前調(diào)用指令的下一條指令的地址(該指令的功能是:先將當(dāng)前調(diào)用指令的下一條指令的地址(16位)壓位)壓入堆棧,并修改堆棧指針:入堆棧,并修改堆棧指針:(SP)(SP)2,(SP)+1:(SP)(IP)再將當(dāng)前的再將當(dāng)前的“下一條指令的地址下一條指令的地址”加

14、上加上“子程序的入口地址子程序的入口地址”的的16位位的偏移量:的偏移量:(IP)D16此時(shí),子程序和主程序在同一個(gè)代碼段內(nèi)。此時(shí),子程序和主程序在同一個(gè)代碼段內(nèi)。第4章 程序設(shè)計(jì)方法【例【例4-2】設(shè)】設(shè)SUB為一個(gè)為一個(gè),其屬性為,其屬性為NEAR類型。則類型。則下面的指令下面的指令CALL SUB 或或 CALL SUB NEAR是段內(nèi)調(diào)用的相對(duì)尋址方式是段內(nèi)調(diào)用的相對(duì)尋址方式段內(nèi)調(diào)用的間接尋址方式段內(nèi)調(diào)用的間接尋址方式其指令形式為其指令形式為CALL 該指令的功能是:先將當(dāng)前調(diào)用指令的下一條指令的地址(該指令的功能是:先將當(dāng)前調(diào)用指令的下一條指令的地址(16位)壓入位)壓入堆棧,并修改

15、堆棧指針:堆棧,并修改堆棧指針:(SP)(SP)2,(SP)+1:(SP)(IP)再將當(dāng)前的再將當(dāng)前的“下一條指令的地址下一條指令的地址” 修改為修改為“子程序的入口地址子程序的入口地址”,用偏,用偏移量移量EA表示:表示:(IP)EA此時(shí),子程序和主程序仍在同一個(gè)代碼段內(nèi)。這里的此時(shí),子程序和主程序仍在同一個(gè)代碼段內(nèi)。這里的EA可以是基址寄存可以是基址寄存器器BX或變址寄存器或變址寄存器SI和和DI的內(nèi)容,也可以是各種尋址方式的存儲(chǔ)器操的內(nèi)容,也可以是各種尋址方式的存儲(chǔ)器操作數(shù)。作數(shù)。第4章 程序設(shè)計(jì)方法【例【例4-3】段內(nèi)間接調(diào)用的各種尋址方式】段內(nèi)間接調(diào)用的各種尋址方式CALL BX ;

16、偏移地址在寄存器;偏移地址在寄存器BX之中之中CALL SI ;偏移地址在存儲(chǔ)器中,;偏移地址在存儲(chǔ)器中,EASI,PA(DS)10H(SI)設(shè)設(shè)VARW為一個(gè)為一個(gè),其屬性為,其屬性為NEAR類型。類型。CALL VARW ;偏移地址在已定義的變量;偏移地址在已定義的變量VARW字單字單元中,段內(nèi)調(diào)用只有字元中,段內(nèi)調(diào)用只有字操作一種格式,所以屬性操作符操作一種格式,所以屬性操作符WORD PTR可以省略??梢允÷浴ALL VARWDI ;偏移地址在;偏移地址在VARWDI字單元中。字單元中。第4章 程序設(shè)計(jì)方法段間調(diào)用的直接尋址方式段間調(diào)用的直接尋址方式其指令形式為其指令形式為CALL

17、FAR PTR 該指令的功能是:先將當(dāng)前調(diào)用指令的下一條指令的地址,包括該指令的功能是:先將當(dāng)前調(diào)用指令的下一條指令的地址,包括代碼段地址和偏移地址先后壓入堆棧,并修改堆棧指針:代碼段地址和偏移地址先后壓入堆棧,并修改堆棧指針:(SP)(SP)2,(SP)+1:(SP)(CS)(SP)(SP)2,(SP)+l:(SP)(IP)再將當(dāng)前的再將當(dāng)前的“下一條指令的地址下一條指令的地址”,修改為子程序的入口的另一,修改為子程序的入口的另一代碼段地址和相應(yīng)的偏移地址:代碼段地址和相應(yīng)的偏移地址:(IP)的偏移地址的偏移地址(CS)的段地址的段地址此時(shí),子程序和主程序不在同一個(gè)代碼段內(nèi)。此時(shí),子程序和主

18、程序不在同一個(gè)代碼段內(nèi)。第4章 程序設(shè)計(jì)方法【例【例4-4】設(shè)】設(shè)SUB2為一個(gè)為一個(gè),其屬性為,其屬性為FAR類型。則類型。則下面的指令下面的指令CALL SUB2 或或 CALL FAR PTR SUB2 是段間調(diào)用的直接尋址方式是段間調(diào)用的直接尋址方式段間調(diào)用的間接尋址方式段間調(diào)用的間接尋址方式其指令形式為其指令形式為 CALL 該指令的功能是:先將當(dāng)前調(diào)用指令的下一條指令的地址,包括代碼段該指令的功能是:先將當(dāng)前調(diào)用指令的下一條指令的地址,包括代碼段地址和偏移地址先后壓入堆棧,并修改堆棧指針:地址和偏移地址先后壓入堆棧,并修改堆棧指針:(SP)(SP)2,(SP)+1:(SP)(CS)

19、(SP)(SP)2,(SP)+l:(SP)(IP)再將當(dāng)前的再將當(dāng)前的“下一條指令的地址下一條指令的地址”,修改為子程序的入口的另一代碼段,修改為子程序的入口的另一代碼段地址和相應(yīng)的偏移地址:地址和相應(yīng)的偏移地址:(IP)以以EA形式給出的形式給出的 的偏移地址的偏移地址(CS)以以EA形式給出的形式給出的的所在的段地址的所在的段地址這里的這里的EA可以是基址寄存器可以是基址寄存器BX或變址寄存器或變址寄存器SI和和DI的內(nèi)容,也可以是的內(nèi)容,也可以是各種尋址方式的存儲(chǔ)器操作數(shù)。各種尋址方式的存儲(chǔ)器操作數(shù)。第4章 程序設(shè)計(jì)方法【例【例4-5】段間間接調(diào)用的各種尋址方式】段間間接調(diào)用的各種尋址方

20、式CALL VAR32 ;EA=VAR32,VAR32是是雙字變量雙字變量 CALL DWORD PTR BX ;EA=BX CALL DWORD PTR TABLEBX SI ;EA= TABLE +BXSI都是段間調(diào)用的間接尋址方式都是段間調(diào)用的間接尋址方式第4章 程序設(shè)計(jì)方法2 返回指令返回指令RET 子程序在其任務(wù)完成后,執(zhí)行的最后一條匯編指令子程序在其任務(wù)完成后,執(zhí)行的最后一條匯編指令是是RET,根據(jù)對(duì)該子程序的調(diào)用是段內(nèi)調(diào)用還是段,根據(jù)對(duì)該子程序的調(diào)用是段內(nèi)調(diào)用還是段間調(diào)用,其要實(shí)現(xiàn)的操作是不相同的。如果是段內(nèi)間調(diào)用,其要實(shí)現(xiàn)的操作是不相同的。如果是段內(nèi)調(diào)用,那么調(diào)用,那么RET指

21、令的功能只是把存放在堆棧里的指令的功能只是把存放在堆棧里的返回地址送返回地址送IP寄存器;如果是段間調(diào)用,那么寄存器;如果是段間調(diào)用,那么RET指令的功能就是要把存放在堆棧里的返回地址和段指令的功能就是要把存放在堆棧里的返回地址和段地址,分別送地址,分別送IP寄存器和寄存器和CS寄存器。因此,寄存器。因此,RET指指令的使用也有多種形式:段內(nèi)返回、段內(nèi)帶立即數(shù)令的使用也有多種形式:段內(nèi)返回、段內(nèi)帶立即數(shù)返回、段間返回和段間帶立即數(shù)返回。下面對(duì)它們返回、段間返回和段間帶立即數(shù)返回。下面對(duì)它們一一加以介紹。一一加以介紹。第4章 程序設(shè)計(jì)方法段內(nèi)返回段內(nèi)返回格式:格式:RET執(zhí)行的操作:執(zhí)行的操作:

22、IP(SP+1)(SP),SPSP2即將當(dāng)前棧項(xiàng)元素內(nèi)容即將當(dāng)前棧項(xiàng)元素內(nèi)容(就是斷點(diǎn)的地址就是斷點(diǎn)的地址)送寄存器送寄存器IP,然后往棧底,然后往棧底方向調(diào)整堆棧指針,達(dá)方向調(diào)整堆棧指針,達(dá)到棧頂元素出棧的目的。到棧頂元素出棧的目的。段內(nèi)帶立即數(shù)返回段內(nèi)帶立即數(shù)返回格式:格式:RET n (或或 RET )立即數(shù),立即數(shù),n通常是正偶數(shù)。如果匯編格式指令中的通常是正偶數(shù)。如果匯編格式指令中的n或表達(dá)式計(jì)算或表達(dá)式計(jì)算出的值是奇數(shù),匯出的值是奇數(shù),匯編時(shí)會(huì)自動(dòng)變成編時(shí)會(huì)自動(dòng)變成n + l。執(zhí)行的操作:執(zhí)行的操作:IP(SP+1)(SP),SPSP+2,SPSP + n第4章 程序設(shè)計(jì)方法段間返

23、回段間返回格式:格式:RET執(zhí)行的操作:執(zhí)行的操作: IP(SP+1)(SP),SPSP+2;CS(SP+1)(SP),SPSP+2段間帶立即數(shù)返回段間帶立即數(shù)返回格式:格式:RET n執(zhí)行的操作:執(zhí)行的操作:IP(SP+1)(SP),SPSP+2;CS(SP+1)(SP),SPSP+2,SPSP + n第4章 程序設(shè)計(jì)方法段內(nèi)返回和段間返回指令的匯編指令格式都是段內(nèi)返回和段間返回指令的匯編指令格式都是RET,但,但是匯編后產(chǎn)生的機(jī)器代碼指令卻是不同的。當(dāng)子程是匯編后產(chǎn)生的機(jī)器代碼指令卻是不同的。當(dāng)子程序的屬性是序的屬性是NEAR時(shí),對(duì)應(yīng)于段內(nèi)返回時(shí),對(duì)應(yīng)于段內(nèi)返回RET指令的指令的機(jī)器代碼是

24、機(jī)器代碼是C3H,對(duì)應(yīng)于段內(nèi)帶立即數(shù)返回,對(duì)應(yīng)于段內(nèi)帶立即數(shù)返回REI指令指令的機(jī)器代碼是的機(jī)器代碼是C2H;當(dāng)子程序的屬性是;當(dāng)子程序的屬性是FAR時(shí),對(duì)時(shí),對(duì)應(yīng)于段間返回應(yīng)于段間返回RET指令的機(jī)器代碼是指令的機(jī)器代碼是CBH,對(duì)應(yīng)于,對(duì)應(yīng)于段間帶立即數(shù)返回段間帶立即數(shù)返回RET指令的機(jī)器代碼是指令的機(jī)器代碼是CAH。所。所以,我們強(qiáng)調(diào)定義一個(gè)子程序?yàn)槎伍g調(diào)用時(shí),其類以,我們強(qiáng)調(diào)定義一個(gè)子程序?yàn)槎伍g調(diào)用時(shí),其類型屬性型屬性FAR是絕對(duì)不能省略的,否則就不能正確實(shí)是絕對(duì)不能省略的,否則就不能正確實(shí)現(xiàn)返回。屬性是現(xiàn)返回。屬性是FAR的子程序也可以被同一代碼段的子程序也可以被同一代碼段的主程序調(diào)

25、用。這時(shí),的主程序調(diào)用。這時(shí),CALL指令雖然與子程序同在指令雖然與子程序同在一個(gè)代碼段中,但它執(zhí)行的卻是段間調(diào)用操作。由一個(gè)代碼段中,但它執(zhí)行的卻是段間調(diào)用操作。由此也表明,此也表明,CALL指令的屬性是由過程的屬性決定的。指令的屬性是由過程的屬性決定的。第4章 程序設(shè)計(jì)方法【例【例4-6】段間調(diào)用的程序描述】段間調(diào)用的程序描述DATA SEGMENT。VARD DD SUBP ;定義一個(gè)雙字變量;定義一個(gè)雙字變量VARD,它的數(shù)據(jù)是子程序,它的數(shù)據(jù)是子程序SUBP的第一的第一條指令的第一個(gè)字節(jié)的內(nèi)存地址,其偏移地址存入低地址,條指令的第一個(gè)字節(jié)的內(nèi)存地址,其偏移地址存入低地址,段地址存入高

26、地址。實(shí)際上就是定義子程序段地址存入高地址。實(shí)際上就是定義子程序VARD,它就是,它就是子程序子程序SUBP DATA ENDSCODE 1 SEGMENTCALL SUBP ;子程序;子程序SUBP在另一個(gè)代碼段在另一個(gè)代碼段CODE2,所以是段間直接,所以是段間直接調(diào)用調(diào)用CALL VARD ;實(shí)際上是段間間接調(diào)用;實(shí)際上是段間間接調(diào)用SUBP,因,因VARD已定義為雙字變已定義為雙字變量量第4章 程序設(shè)計(jì)方法LEA SI,VARD ;送雙字變量;送雙字變量VARD的偏移地址到寄存器的偏移地址到寄存器SICALL DWORD PTRSI;段間間接調(diào)用,;段間間接調(diào)用,DWORD PTR不能

27、省不能省略,表明取略,表明取32位數(shù)據(jù)位數(shù)據(jù)CODE l ENDSCODE2 SEGMENI SUBP PROC FAR;定義名為;定義名為SUBP的子程序,的子程序,F(xiàn)AR屬性不可省屬性不可省略略 RET;子程序返回指令;子程序返回指令SUBP ENDPCODE2 ENDS第4章 程序設(shè)計(jì)方法4.2.2 現(xiàn)場(chǎng)的保護(hù)與恢復(fù)現(xiàn)場(chǎng)的保護(hù)與恢復(fù) 前面說過,在子程序調(diào)用的操作中,必須做好調(diào)用程序現(xiàn)場(chǎng)的保護(hù)前面說過,在子程序調(diào)用的操作中,必須做好調(diào)用程序現(xiàn)場(chǎng)的保護(hù)工作,以便調(diào)用程序現(xiàn)場(chǎng)的恢復(fù)。工作,以便調(diào)用程序現(xiàn)場(chǎng)的恢復(fù)。保護(hù)與恢復(fù)現(xiàn)場(chǎng)的工作可以在主程序中完成,也可以在子程序中完保護(hù)與恢復(fù)現(xiàn)場(chǎng)的工作可以

28、在主程序中完成,也可以在子程序中完成。一般情況下,是在子程序的開始安排一串保護(hù)現(xiàn)場(chǎng)的語句。成。一般情況下,是在子程序的開始安排一串保護(hù)現(xiàn)場(chǎng)的語句。在子程序的返回指令之前再恢復(fù)現(xiàn)場(chǎng)。這樣處理,主程序在轉(zhuǎn)子在子程序的返回指令之前再恢復(fù)現(xiàn)場(chǎng)。這樣處理,主程序在轉(zhuǎn)子前后均不必考慮保護(hù)、恢復(fù)現(xiàn)場(chǎng)的工作,其處理流程顯得清晰。前后均不必考慮保護(hù)、恢復(fù)現(xiàn)場(chǎng)的工作,其處理流程顯得清晰。尤其是當(dāng)多處調(diào)用同一子程序時(shí),每處都省去了轉(zhuǎn)子前后保存與尤其是當(dāng)多處調(diào)用同一子程序時(shí),每處都省去了轉(zhuǎn)子前后保存與恢復(fù)現(xiàn)場(chǎng)的語句串。這些工作集中在子程序中去做,整個(gè)代碼簡(jiǎn)恢復(fù)現(xiàn)場(chǎng)的語句串。這些工作集中在子程序中去做,整個(gè)代碼簡(jiǎn)短而緊

29、湊。短而緊湊。通過子程序的調(diào)用和返回指令的學(xué)習(xí),可以知道,在子程序中用到通過子程序的調(diào)用和返回指令的學(xué)習(xí),可以知道,在子程序中用到某些寄存器某些寄存器(或存儲(chǔ)單元或存儲(chǔ)單元),就可能破壞這些寄存器,就可能破壞這些寄存器(或存儲(chǔ)單元或存儲(chǔ)單元)在轉(zhuǎn)子程序前原有的內(nèi)容。因此,若子程序在轉(zhuǎn)子程序前原有的內(nèi)容。因此,若子程序A中可能改變寄存器中可能改變寄存器AX、BX、CX、DI、SI五個(gè)寄存器的內(nèi)容,則在子程序的開始處五個(gè)寄存器的內(nèi)容,則在子程序的開始處應(yīng)將這些寄存器的內(nèi)容入棧保護(hù),在子程序的返回指令之前用出應(yīng)將這些寄存器的內(nèi)容入棧保護(hù),在子程序的返回指令之前用出棧指令逐個(gè)恢復(fù)。棧指令逐個(gè)恢復(fù)。第4

30、章 程序設(shè)計(jì)方法實(shí)現(xiàn)方法就是,把子程序或過程的定義格式擴(kuò)充實(shí)現(xiàn)方法就是,把子程序或過程的定義格式擴(kuò)充為如下的格式:為如下的格式: PROCPUSH AXPUSH BXPUSH CX 保護(hù)現(xiàn)場(chǎng)保護(hù)現(xiàn)場(chǎng)PUSH DIPUSH SI 子程序工作部分子程序工作部分POP SIPOP DI POP CX 恢復(fù)現(xiàn)場(chǎng)恢復(fù)現(xiàn)場(chǎng)POP BXPOP AXRET ;返回?cái)帱c(diǎn)處;返回?cái)帱c(diǎn)處 ENDP 第4章 程序設(shè)計(jì)方法注意,由于是在棧中保存各寄存器的內(nèi)容,所注意,由于是在棧中保存各寄存器的內(nèi)容,所以,要依后進(jìn)先出的原則,從棧中彈出信息以,要依后進(jìn)先出的原則,從棧中彈出信息送入相應(yīng)的寄存器。上例中入棧保護(hù)的順序送入相

31、應(yīng)的寄存器。上例中入棧保護(hù)的順序是是AX、BX、CX、DI、SI,出?;謴?fù)的順序,出?;謴?fù)的順序則相反,即則相反,即SI、DI、CX、BX、AX。這樣才。這樣才能保證子程序的運(yùn)行不破壞主程序的工作現(xiàn)能保證子程序的運(yùn)行不破壞主程序的工作現(xiàn)場(chǎng)。場(chǎng)。第4章 程序設(shè)計(jì)方法【例【例4-7】下面給出的是一個(gè)名為】下面給出的是一個(gè)名為SUBP的子程序的定義格式,考的子程序的定義格式,考慮到了現(xiàn)場(chǎng)的保護(hù)與慮到了現(xiàn)場(chǎng)的保護(hù)與恢復(fù):恢復(fù):SUBP PROC NEARPUSH AXPOP AXRETSUBP ENDP從定義中可以看出,它屬于段內(nèi)調(diào)用從定義中可以看出,它屬于段內(nèi)調(diào)用(NEAR),因此也可以把,因此也可

32、以把NEAR省略。省略。第4章 程序設(shè)計(jì)方法4.3主程序與子程序之間傳遞參數(shù)的方式主程序與子程序之間傳遞參數(shù)的方式 4.3.1 寄存器法寄存器法4.3.2 約定存儲(chǔ)單元法約定存儲(chǔ)單元法4.3.3堆棧傳遞參數(shù)法堆棧傳遞參數(shù)法返回本章首頁返回本章首頁第4章 程序設(shè)計(jì)方法4.3.1 寄存器法寄存器法寄存器法就是子程序的入口參數(shù)和出口參數(shù)都寄存器法就是子程序的入口參數(shù)和出口參數(shù)都在約定的寄存器之中。此法的優(yōu)點(diǎn)是信息傳在約定的寄存器之中。此法的優(yōu)點(diǎn)是信息傳遞快編程也較方便且節(jié)省內(nèi)存單元。但遞快編程也較方便且節(jié)省內(nèi)存單元。但由于寄存器的個(gè)數(shù)是有限的,而且在處理過由于寄存器的個(gè)數(shù)是有限的,而且在處理過程中要

33、經(jīng)常使用寄存器,如果要傳送的參數(shù)程中要經(jīng)常使用寄存器,如果要傳送的參數(shù)很多,將導(dǎo)致無空閑寄存器供編寫程序使很多,將導(dǎo)致無空閑寄存器供編寫程序使用所以,寄存器法只適用于要傳遞的參數(shù)用所以,寄存器法只適用于要傳遞的參數(shù)較少的情況。較少的情況。第4章 程序設(shè)計(jì)方法【例【例4-8】編程計(jì)算】編程計(jì)算3個(gè)個(gè)16位無符號(hào)整數(shù)的平方根之和位無符號(hào)整數(shù)的平方根之和分析問題:本題采用連續(xù)減奇數(shù)法求平方根的算法:將整數(shù)依次分析問題:本題采用連續(xù)減奇數(shù)法求平方根的算法:將整數(shù)依次減去奇數(shù)減去奇數(shù)1,3,5,7,(2n1)。所能執(zhí)行這種減法的次數(shù),即是所求數(shù)的平方根。所能執(zhí)行這種減法的次數(shù),即是所求數(shù)的平方根值。比如

34、,要求數(shù)值。比如,要求數(shù)25的平方根。那么依次做下面的減法:的平方根。那么依次做下面的減法:25l = 24 ;減第;減第1次次243 = 21 ;減第;減第2次次2l5 = 16 ;減第;減第3次次167 = 9 ;減第;減第4次次99 = 0 ;減第;減第5次次 這表明減法可以進(jìn)行這表明減法可以進(jìn)行5次,因此次,因此25的平方根是的平方根是5。下面,將這種求。下面,將這種求平方根的算法編寫成名為平方根的算法編寫成名為SQROT的子程序。的子程序。第4章 程序設(shè)計(jì)方法確定算法:本題要作兩個(gè)循環(huán):內(nèi)循環(huán)求平方根,采用確定算法:本題要作兩個(gè)循環(huán):內(nèi)循環(huán)求平方根,采用子程序。所以主程序向子程子程序

35、。所以主程序向子程序傳遞的參數(shù)是序傳遞的參數(shù)是3個(gè)被開方數(shù),子程序向主程序傳遞的個(gè)被開方數(shù),子程序向主程序傳遞的參數(shù)是參數(shù)是3個(gè)方根。外循環(huán)累加平方根個(gè)方根。外循環(huán)累加平方根之和,循環(huán)次數(shù)已知是之和,循環(huán)次數(shù)已知是3次,故用循環(huán)次數(shù)作為外循環(huán)次,故用循環(huán)次數(shù)作為外循環(huán)的控制條件,配合使用的控制條件,配合使用LOOP指令。指令。內(nèi)循環(huán)因?yàn)橐鬟B續(xù)減法,循環(huán)次數(shù)不定,所以用內(nèi)循環(huán)因?yàn)橐鬟B續(xù)減法,循環(huán)次數(shù)不定,所以用CF1,表示當(dāng)減法需借位時(shí),子循環(huán)結(jié)束。,表示當(dāng)減法需借位時(shí),子循環(huán)結(jié)束。子程序與主程序之間采用寄存器方式傳遞參數(shù)。即:主子程序與主程序之間采用寄存器方式傳遞參數(shù)。即:主程序把輸入?yún)?shù)

36、放在程序把輸入?yún)?shù)放在DX中,傳遞給子程序;子程序中,傳遞給子程序;子程序?qū)⑤敵鰠?shù)放在將輸出參數(shù)放在AX里,傳遞給主程序。注意現(xiàn)場(chǎng)保里,傳遞給主程序。注意現(xiàn)場(chǎng)保護(hù)。顯然,不能對(duì)存放輸出參數(shù)的護(hù)。顯然,不能對(duì)存放輸出參數(shù)的AX寄存器進(jìn)行現(xiàn)寄存器進(jìn)行現(xiàn)場(chǎng)保護(hù),否則子程序的操作就白作了。場(chǎng)保護(hù),否則子程序的操作就白作了。 第4章 程序設(shè)計(jì)方法畫程序流程圖:略。畫程序流程圖:略。確定匯編語言程序的基本框架:可見,該匯編語言程序確定匯編語言程序的基本框架:可見,該匯編語言程序的基本框架至少要兩個(gè)段:的基本框架至少要兩個(gè)段:數(shù)據(jù)段和代碼段。數(shù)據(jù)段中定義數(shù)據(jù)段和代碼段。數(shù)據(jù)段中定義2個(gè)變量:一個(gè)數(shù)組變個(gè)變

37、量:一個(gè)數(shù)組變量量VARW,題設(shè)為,題設(shè)為16位數(shù),應(yīng)選位數(shù),應(yīng)選DW 類型,使用寄類型,使用寄存器存器SI定位。另一個(gè)是和數(shù)定位。另一個(gè)是和數(shù)SUM變量,也選變量,也選DW類型,類型,其中間結(jié)果放在寄存器其中間結(jié)果放在寄存器BX。平方根放在寄存器。平方根放在寄存器AX。還有一個(gè)數(shù)還有一個(gè)數(shù)N,為循環(huán)次數(shù),計(jì)數(shù)器用,為循環(huán)次數(shù),計(jì)數(shù)器用CX。編寫程序,可以想得到,需要編寫程序,可以想得到,需要MOV、SUB 、ADD 、LEA 、INC、CALL、JMP、JC、PUSH、POP和和LOOP等指令,最后要返回等指令,最后要返回DOS。未想到的,在編寫過程中隨時(shí)添加,如未想到的,在編寫過程中隨時(shí)添

38、加,如XOR指令等。指令等。第4章 程序設(shè)計(jì)方法具體程序如下:具體程序如下:DATA SEGMENT VARW DW 81,144,289SUM DW ?DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX ;XOR BX,BX ;BX清清0,存放平方根之和,存放平方根之和LEA SI,VARW ;送數(shù)組變量;送數(shù)組變量VARW的起始偏移地址到寄存器的起始偏移地址到寄存器SIMOV CX,3LOP: LEA DX,SI ;輸入?yún)?shù),;輸入?yún)?shù),DX81,144,289CALL SQROT ;調(diào)用子程序;

39、調(diào)用子程序SQROTADD BX,AX ;累加平方根;累加平方根ADD SI,2 ;SI SI2,移到下一個(gè)數(shù),移到下一個(gè)數(shù)LOOP LOP ;CX CX1,若,若CX0,循環(huán)到,循環(huán)到LOP語句,直到語句,直到CX0。MOV SUM,BX ;將最后結(jié)果送;將最后結(jié)果送SUM 內(nèi)存單元內(nèi)存單元 MOV AH,4CHINT 21H第4章 程序設(shè)計(jì)方法*以下為子程序以下為子程序*SQROT PROCPUSH CX :現(xiàn)場(chǎng)保護(hù):現(xiàn)場(chǎng)保護(hù)PUSH DX ;現(xiàn)場(chǎng)保護(hù);現(xiàn)場(chǎng)保護(hù)MOV CX,1 ;奇數(shù)初值為;奇數(shù)初值為1XOR AX,AX;AX清清0,存放平方根值,存放平方根值SQRl: SUB DX,C

40、X ;循環(huán)減奇數(shù),初始減;循環(huán)減奇數(shù),初始減1JC SQR 2 ;若;若CF1,減法需借位,轉(zhuǎn)移到,減法需借位,轉(zhuǎn)移到SQR 2,結(jié)束循環(huán)的條件,結(jié)束循環(huán)的條件INC AX ;若;若CF1,夠減,寄存器,夠減,寄存器AX加加1,記錄減法的次數(shù),最,記錄減法的次數(shù),最后即得所求數(shù)的平方根值后即得所求數(shù)的平方根值A(chǔ)DD CX,2 ;奇數(shù)遞增;奇數(shù)遞增JMP SQR l ;跳到;跳到SQR l,循環(huán)作減法,循環(huán)作減法SOR2: POP DX :現(xiàn)場(chǎng)恢復(fù):現(xiàn)場(chǎng)恢復(fù)POP CX ;現(xiàn)場(chǎng)恢復(fù);現(xiàn)場(chǎng)恢復(fù)RET ;返回,輸出參數(shù)在;返回,輸出參數(shù)在AX*子程序結(jié)束子程序結(jié)束*SQROT ENDPCODE EN

41、DSEND START第4章 程序設(shè)計(jì)方法具體程序如下:具體程序如下:DATA SEGMENT DAT DB ,;定義數(shù)組變量,有數(shù)據(jù);定義數(shù)組變量,有數(shù)據(jù)N1個(gè)個(gè)DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATAMOV DS,AX ;數(shù)據(jù)段初始化;數(shù)據(jù)段初始化MOV CX,N1 ;將外、內(nèi)循環(huán)次數(shù)送寄存器;將外、內(nèi)循環(huán)次數(shù)送寄存器CX保存保存LOPl: XOR SI,SI ;寄存器;寄存器SI清零,使外循環(huán)體每輪循環(huán)都從第一個(gè)開始清零,使外循環(huán)體每輪循環(huán)都從第一個(gè)開始PUSH CX ;保存外循環(huán)次數(shù);保存外循環(huán)次數(shù) 第4章

42、 程序設(shè)計(jì)方法*內(nèi)循環(huán)開始內(nèi)循環(huán)開始*LOP2: MOV AL,DATSI ;取國(guó)名的第一個(gè)字母;取國(guó)名的第一個(gè)字母CMP AL,DATSI+3 ;比較相鄰兩個(gè)國(guó)名的第一個(gè)字母;比較相鄰兩個(gè)國(guó)名的第一個(gè)字母JLE LOP3 ;符合順序,轉(zhuǎn)移到;符合順序,轉(zhuǎn)移到LOP3語句語句CALL MPR 0 ;不符合順序,則調(diào)用交換子程序;不符合順序,則調(diào)用交換子程序MPR 0LOP3: ADD SI,3 ;SI SI3,指向下一個(gè)國(guó)名,指向下一個(gè)國(guó)名LOOP LOP2 ;CXCX1,若,若CX0,則循環(huán)到,則循環(huán)到LOP2,繼續(xù)比,繼續(xù)比較下一較下一對(duì)相鄰兩個(gè)國(guó)名的第一個(gè)字母,直到對(duì)相鄰兩個(gè)國(guó)名的第一個(gè)

43、字母,直到CX0為止,形成內(nèi)為止,形成內(nèi)循環(huán)控制循環(huán)控制*內(nèi)循環(huán)結(jié)束內(nèi)循環(huán)結(jié)束*第4章 程序設(shè)計(jì)方法INC SI ;SI SI1,指向國(guó)名的第二個(gè)字母,指向國(guó)名的第二個(gè)字母POP CX ;恢復(fù)外循環(huán)次數(shù);恢復(fù)外循環(huán)次數(shù)LOOP LOP1 ;CXCX1,若,若CX0,則循環(huán)到,則循環(huán)到LOP1,繼,繼續(xù)對(duì)國(guó)名的第二個(gè)字母進(jìn)行比較,直到續(xù)對(duì)國(guó)名的第二個(gè)字母進(jìn)行比較,直到CX0為止,形成外循為止,形成外循環(huán)控制。再循環(huán)到環(huán)控制。再循環(huán)到LOP1,繼續(xù)對(duì)國(guó)名的第三個(gè)字母進(jìn)行比,繼續(xù)對(duì)國(guó)名的第三個(gè)字母進(jìn)行比較,較,MOV AH,4CHINT 2lH*子程序開始子程序開始*MPR 0 PROC ;實(shí)現(xiàn)交換

44、功能的子程序,入口參數(shù);實(shí)現(xiàn)交換功能的子程序,入口參數(shù)SIPUSH CX ;現(xiàn)場(chǎng)的保護(hù),(;現(xiàn)場(chǎng)的保護(hù),(CS)壓棧)壓棧PUSH SI ;現(xiàn)場(chǎng)的保護(hù),(;現(xiàn)場(chǎng)的保護(hù),(IP)壓棧)壓棧第4章 程序設(shè)計(jì)方法MOV CX,3 ;CX3, MPR l: MOV AL,SI ;通過寄存器;通過寄存器AL向子程序傳遞入口參數(shù),即將第一向子程序傳遞入口參數(shù),即將第一個(gè)國(guó)名的第一個(gè)字母送寄存器個(gè)國(guó)名的第一個(gè)字母送寄存器AL XCHG AL,BYTE PTRSI+3 ;將(;將(AL)與相鄰國(guó)名的第一個(gè)字母交換,)與相鄰國(guó)名的第一個(gè)字母交換,MOV BYTE PTRSI,AL ;將(;將(AL)送內(nèi)存單元)

45、送內(nèi)存單元SI,實(shí)現(xiàn)將字母靠,實(shí)現(xiàn)將字母靠后的國(guó)名往后移,同時(shí)字母靠前的國(guó)名往后的國(guó)名往后移,同時(shí)字母靠前的國(guó)名往前移的操作,向主程序返回參數(shù)前移的操作,向主程序返回參數(shù)ALINC SI ;SI SI1,指向國(guó)名的第二個(gè)字母,指向國(guó)名的第二個(gè)字母LOOP MPR l ;CXCX1,若,若CX0,則循環(huán)到,則循環(huán)到MPR l,把國(guó)名的后兩個(gè)字母,把國(guó)名的后兩個(gè)字母,跟隨第一個(gè)字母移動(dòng)位置,直到跟隨第一個(gè)字母移動(dòng)位置,直到CX0為止,形成子程序的內(nèi)循環(huán)控制為止,形成子程序的內(nèi)循環(huán)控制POP SI ;現(xiàn)場(chǎng)恢復(fù);現(xiàn)場(chǎng)恢復(fù)IPPOP CX ;現(xiàn)場(chǎng)恢復(fù);現(xiàn)場(chǎng)恢復(fù)CSRET ;返回?cái)帱c(diǎn)處;返回?cái)帱c(diǎn)處MPR

46、0 ENDP ;子程序;子程序MPR 0結(jié)束結(jié)束*子程序結(jié)束子程序結(jié)束*CODE ENDSEND START第4章 程序設(shè)計(jì)方法【例【例4-9】每個(gè)國(guó)家的縮寫名稱,都用】每個(gè)國(guó)家的縮寫名稱,都用3個(gè)大寫的英文字個(gè)大寫的英文字母代表。比如母代表。比如CHA,USA,RUS及及AUS等。請(qǐng)將等。請(qǐng)將N個(gè)國(guó)家的縮寫名稱按字母的順序進(jìn)行排序。個(gè)國(guó)家的縮寫名稱按字母的順序進(jìn)行排序。分析問題:將分析問題:將N個(gè)國(guó)家的縮寫名稱按字母的順序進(jìn)行排個(gè)國(guó)家的縮寫名稱按字母的順序進(jìn)行排序,要反復(fù)進(jìn)行序,要反復(fù)進(jìn)行N1次比次比較,有時(shí)還要交換,最多較,有時(shí)還要交換,最多N1次。第一個(gè)字母比較完了,次。第一個(gè)字母比較完

47、了,其結(jié)果必然是第一個(gè)字母相同的國(guó)名排在一起。再其結(jié)果必然是第一個(gè)字母相同的國(guó)名排在一起。再對(duì)第二個(gè)字母比較,也要進(jìn)行對(duì)第二個(gè)字母比較,也要進(jìn)行N1次;第二個(gè)字母比次;第二個(gè)字母比較完了,再對(duì)第三個(gè)字母比較,再進(jìn)行較完了,再對(duì)第三個(gè)字母比較,再進(jìn)行N1次;可見,次;可見,這是循環(huán)嵌套問題。第一個(gè)字母比較是外循環(huán),后這是循環(huán)嵌套問題。第一個(gè)字母比較是外循環(huán),后面兩次是內(nèi)循環(huán),次數(shù)都是面兩次是內(nèi)循環(huán),次數(shù)都是N1次。每次循環(huán)中又嵌次。每次循環(huán)中又嵌套套“交換操作交換操作”的內(nèi)循環(huán)。的內(nèi)循環(huán)。第4章 程序設(shè)計(jì)方法4.3.2 約定存儲(chǔ)單元法約定存儲(chǔ)單元法 當(dāng)需要傳遞的參數(shù)較多,只使用寄存器不能完成任務(wù)

48、,當(dāng)需要傳遞的參數(shù)較多,只使用寄存器不能完成任務(wù),這時(shí)可以考慮在內(nèi)存數(shù)據(jù)段的存儲(chǔ)單元中開辟專門這時(shí)可以考慮在內(nèi)存數(shù)據(jù)段的存儲(chǔ)單元中開辟專門的區(qū)域用于參數(shù)傳遞,讓子程序直接訪問數(shù)據(jù)段中的區(qū)域用于參數(shù)傳遞,讓子程序直接訪問數(shù)據(jù)段中的變量。主程序和子程序按照事先的約定,在指定的變量。主程序和子程序按照事先的約定,在指定的存儲(chǔ)單元中進(jìn)行數(shù)據(jù)交換?;蛘?,把參數(shù)存放在的存儲(chǔ)單元中進(jìn)行數(shù)據(jù)交換?;蛘?,把參數(shù)存放在數(shù)據(jù)段的存儲(chǔ)單元中,將參數(shù)區(qū)的首地址存放在某數(shù)據(jù)段的存儲(chǔ)單元中,將參數(shù)區(qū)的首地址存放在某個(gè)寄存器中,然后用寄存器傳遞參數(shù)的辦法,把這個(gè)寄存器中,然后用寄存器傳遞參數(shù)的辦法,把這個(gè)地址傳遞給子程序。個(gè)

49、地址傳遞給子程序。這種方式所能傳遞的參數(shù)數(shù)量幾乎沒有限制,其缺點(diǎn)是這種方式所能傳遞的參數(shù)數(shù)量幾乎沒有限制,其缺點(diǎn)是需要占用一定數(shù)量的存儲(chǔ)單元,由于任何程序在任需要占用一定數(shù)量的存儲(chǔ)單元,由于任何程序在任何時(shí)刻都可以修改這些數(shù)據(jù),不利于模塊化設(shè)計(jì)和何時(shí)刻都可以修改這些數(shù)據(jù),不利于模塊化設(shè)計(jì)和信息隔離。信息隔離。第4章 程序設(shè)計(jì)方法【例【例4-10】利用子程序結(jié)構(gòu),編寫一個(gè)計(jì)算】利用子程序結(jié)構(gòu),編寫一個(gè)計(jì)算S=1!+2!+7!+8!的程序。!的程序。分析問題:為了利用子程序結(jié)構(gòu),把計(jì)算任一正整數(shù)分析問題:為了利用子程序結(jié)構(gòu),把計(jì)算任一正整數(shù)i的階乘的階乘i!編寫成為一個(gè)子程編寫成為一個(gè)子程序。然后

50、在主程序中用不同的正整數(shù)調(diào)用它,并求它們的和。序。然后在主程序中用不同的正整數(shù)調(diào)用它,并求它們的和。確定算法:用子程序計(jì)算階乘,因?yàn)橐磸?fù)乘,采用循環(huán)程確定算法:用子程序計(jì)算階乘,因?yàn)橐磸?fù)乘,采用循環(huán)程序,循環(huán)次數(shù)是數(shù)的本序,循環(huán)次數(shù)是數(shù)的本身的值。用循環(huán)次數(shù)作為循環(huán)的控制條件,再配合使用身的值。用循環(huán)次數(shù)作為循環(huán)的控制條件,再配合使用JNZ指令。計(jì)算階乘之和,放在外循環(huán),循環(huán)次數(shù)已知,指令。計(jì)算階乘之和,放在外循環(huán),循環(huán)次數(shù)已知,8次,次,用循環(huán)次數(shù)作為循環(huán)的控制條件,再配合使用用循環(huán)次數(shù)作為循環(huán)的控制條件,再配合使用LOOP指令。指令。畫程序流程圖:略。畫程序流程圖:略。第4章 程序設(shè)計(jì)

51、方法確定匯編語言程序的基本框架:可見,該匯編語言程序的基本框架至少確定匯編語言程序的基本框架:可見,該匯編語言程序的基本框架至少要兩個(gè)段:要兩個(gè)段:數(shù)據(jù)段和代碼段。如果形式上要完整一些,還可以再定義堆棧段。數(shù)據(jù)數(shù)據(jù)段和代碼段。如果形式上要完整一些,還可以再定義堆棧段。數(shù)據(jù)段中至少定義段中至少定義2個(gè)變量,一個(gè)數(shù)組變量個(gè)變量,一個(gè)數(shù)組變量VARB,含有,含有8個(gè)數(shù)據(jù),由題設(shè)個(gè)數(shù)據(jù),由題設(shè)應(yīng)選應(yīng)選DB 類型,使用寄存器類型,使用寄存器SI定位;另一個(gè)變量是累加和定位;另一個(gè)變量是累加和SUM,選,選DW 類型。采用內(nèi)外循環(huán)。內(nèi)循環(huán)有子程序。類型。采用內(nèi)外循環(huán)。內(nèi)循環(huán)有子程序。 外循環(huán)次數(shù)的計(jì)數(shù)器外

52、循環(huán)次數(shù)的計(jì)數(shù)器用用CX,內(nèi)循環(huán)次數(shù)的計(jì)數(shù)器用,內(nèi)循環(huán)次數(shù)的計(jì)數(shù)器用DH。中間結(jié)果用寄存器。中間結(jié)果用寄存器AX,BX和和DL。有子程序,就有參數(shù)傳遞問題。入口參數(shù)用存儲(chǔ)單元有子程序,就有參數(shù)傳遞問題。入口參數(shù)用存儲(chǔ)單元VARB 并通過寄并通過寄存器存器SI傳遞,出口參數(shù)用傳遞,出口參數(shù)用AX傳遞。傳遞。編寫程序,可以想得到,需要編寫程序,可以想得到,需要MOV、ADD 、CMP 、JLE、INC、CALL、PUSH、POP和和LOOP等指令,最后要返回等指令,最后要返回DOS。未想到的,在編寫過程中隨時(shí)。未想到的,在編寫過程中隨時(shí)添加和修改,如添加和修改,如XOR指令等。由于每個(gè)國(guó)家的縮寫名

53、稱是指令等。由于每個(gè)國(guó)家的縮寫名稱是3個(gè)字母,個(gè)字母,因此要占用因此要占用3個(gè)字節(jié)存放。修改操作數(shù)的地址時(shí)要加個(gè)字節(jié)存放。修改操作數(shù)的地址時(shí)要加3,交換時(shí)最多要,交換時(shí)最多要交換交換N1次。并且要考慮到第三章所述關(guān)于多重循環(huán)的注意事項(xiàng)。交次。并且要考慮到第三章所述關(guān)于多重循環(huán)的注意事項(xiàng)。交換操作采用子程序完成。換操作采用子程序完成。第4章 程序設(shè)計(jì)方法具體程序如下:具體程序如下:DATA SEGMENTVARB DB 1,2,3,4,5,6,7,8SUM DW?DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATAMOV DS,

54、AXLEA SI,VARB ;送數(shù)組變量;送數(shù)組變量VARB的起始地址到寄存器的起始地址到寄存器SI,定位,定位 MOV CX,8 ;循環(huán)次數(shù)送入;循環(huán)次數(shù)送入CXXOR BX,BX ;BX清清0,存放階乘之和,存放階乘之和LOPl:CALL SUBP ;段內(nèi)直接調(diào)用子程序;段內(nèi)直接調(diào)用子程序SUBPADD BX,AX ;計(jì)算階乘之和,寄存器;計(jì)算階乘之和,寄存器AX存放數(shù)的階乘存放數(shù)的階乘INC SI ;SI SI1,指向下一個(gè)數(shù),指向下一個(gè)數(shù)LOOP LOPl ;CX CX1,循環(huán)次數(shù)減,循環(huán)次數(shù)減1,若,若CX0,繼續(xù)循環(huán),直,繼續(xù)循環(huán),直到到CX0。MOV SUM,BX ;結(jié)果存入;結(jié)

55、果存入SUM字存儲(chǔ)單元字存儲(chǔ)單元MOV AH,4CH ;終止程序運(yùn)行并返回;終止程序運(yùn)行并返回DOSINT 2lH第4章 程序設(shè)計(jì)方法*子程序開始子程序開始*SUBP PROC ;定義;定義SUBP子程序,子程序,NEAR屬性,可省略屬性,可省略MOV DL,1 ;選寄存器;選寄存器DL,存放乘數(shù),初值為,存放乘數(shù),初值為1MOV AX,1 ;AX存放存放N!,初值為,初值為1MOV DH,BYTE PTRSI;循環(huán)次數(shù)送入寄存器;循環(huán)次數(shù)送入寄存器DHLOP2:MUL DL ;計(jì)算;計(jì)算N!INC DL ;乘數(shù)加;乘數(shù)加1DEC DH ;DH DH1,循環(huán)次數(shù)減,循環(huán)次數(shù)減1,若,若DH0,

56、繼續(xù)循環(huán),直,繼續(xù)循環(huán),直到到DH0。JNZ LOP2 ;循環(huán)乘;循環(huán)乘RET ;返回;返回SUBP ENDP ;子程序結(jié)束;子程序結(jié)束*子程序結(jié)束子程序結(jié)束*CODE ENDSEND START第4章 程序設(shè)計(jì)方法【例【例4-11】將一組分離】將一組分離BCD數(shù)轉(zhuǎn)換為數(shù)轉(zhuǎn)換為16位二進(jìn)制數(shù),試編寫其程序。位二進(jìn)制數(shù),試編寫其程序。分析問題:分離分析問題:分離BCD數(shù),例如(數(shù),例如(9)BCD00001001B,其中低四位是,其中低四位是該數(shù)的該數(shù)的BCD碼,高碼,高4位可以是任意的位可以是任意的0、1代碼,比如說,可以是代碼,比如說,可以是0000。而(。而(39)BCD000000110

57、0001001B,將它轉(zhuǎn)換為二進(jìn)制數(shù)為:,將它轉(zhuǎn)換為二進(jìn)制數(shù)為:27H00100111B= (000000111010) + (00001001)B,即等于即等于(分離(分離BCD數(shù)的高位字節(jié))數(shù)的高位字節(jié))10 + (分離分離BCD數(shù)的低位字節(jié)數(shù)的低位字節(jié)) 因?yàn)橐獙?duì)一組分離因?yàn)橐獙?duì)一組分離BCD數(shù)進(jìn)行轉(zhuǎn)換,需反復(fù)操作,故轉(zhuǎn)換過程可以用數(shù)進(jìn)行轉(zhuǎn)換,需反復(fù)操作,故轉(zhuǎn)換過程可以用子程序?qū)崿F(xiàn)。但要注意主程序和子程序間的參數(shù)傳遞以及現(xiàn)場(chǎng)保護(hù)和子程序?qū)崿F(xiàn)。但要注意主程序和子程序間的參數(shù)傳遞以及現(xiàn)場(chǎng)保護(hù)和恢復(fù)問題?;謴?fù)問題。 第4章 程序設(shè)計(jì)方法確定算法:采用子程序,并采用比較循環(huán)指令,循環(huán)次數(shù)是數(shù)組長(zhǎng)

58、度確定算法:采用子程序,并采用比較循環(huán)指令,循環(huán)次數(shù)是數(shù)組長(zhǎng)度LENG l。故。故用循環(huán)次數(shù)作為循環(huán)的控制條件,再配合使用用循環(huán)次數(shù)作為循環(huán)的控制條件,再配合使用LOOP指令。指令。畫程序流程圖:略。畫程序流程圖:略。確定匯編語言程序的基本框架:可見,該匯編語言程序的基本框架至少確定匯編語言程序的基本框架:可見,該匯編語言程序的基本框架至少要三個(gè)段:要三個(gè)段:堆棧段、數(shù)據(jù)段和代碼段。堆棧段的存在是因?yàn)橛鞋F(xiàn)場(chǎng)保護(hù)和恢復(fù)問題,堆棧段、數(shù)據(jù)段和代碼段。堆棧段的存在是因?yàn)橛鞋F(xiàn)場(chǎng)保護(hù)和恢復(fù)問題,定義定義256個(gè)字長(zhǎng)度的堆??臻g。數(shù)據(jù)段中至少定義個(gè)字長(zhǎng)度的堆??臻g。數(shù)據(jù)段中至少定義5個(gè)變量,它們依個(gè)變量,

59、它們依次是:次是:(1)待分離的)待分離的BCD數(shù)數(shù)BCD1,題目要求轉(zhuǎn)換為,題目要求轉(zhuǎn)換為16位二進(jìn)制數(shù),位二進(jìn)制數(shù),16位二位二進(jìn)制數(shù),其最大值是進(jìn)制數(shù),其最大值是215132767,那么一個(gè)待分離的,那么一個(gè)待分離的BCD數(shù)要占數(shù)要占45個(gè)字節(jié)。所以定義為:個(gè)字節(jié)。所以定義為: BCD1 DB 5 DUP(?)實(shí)際上,應(yīng)該定義為實(shí)際上,應(yīng)該定義為“5的倍數(shù)的倍數(shù)”個(gè)字節(jié)單元。本例從示例出發(fā),只定個(gè)字節(jié)單元。本例從示例出發(fā),只定義了義了5個(gè)字節(jié)。在實(shí)際運(yùn)用時(shí),應(yīng)該定義為:個(gè)字節(jié)。在實(shí)際運(yùn)用時(shí),應(yīng)該定義為: 待分離的待分離的BCD數(shù)的數(shù)目數(shù)的數(shù)目5個(gè)字節(jié)單元。個(gè)字節(jié)單元。第4章 程序設(shè)計(jì)方法

60、(2)變量)變量ADSEG,ADOFST,表示,表示BCD數(shù)的地址數(shù)的地址(包括段包括段地址和偏移地址地址和偏移地址),應(yīng)選,應(yīng)選DW 類型。使用寄存器類型。使用寄存器ES和和SI定定位。位。(3)變量)變量LENG l和和RESULT,用來表示,用來表示BCD數(shù)的長(zhǎng)度及結(jié)數(shù)的長(zhǎng)度及結(jié)果,應(yīng)選果,應(yīng)選DW 類型。類型。其中間結(jié)果放在寄存器其中間結(jié)果放在寄存器AX 和和BX。循環(huán)次數(shù)計(jì)數(shù)器用。循環(huán)次數(shù)計(jì)數(shù)器用CX。編寫程序,可以想得到,需要編寫程序,可以想得到,需要MOV、AND 、ADD 、DEC 、CBW、MUL 、PUSH、POP、CALL和和LOOP等指令。最后要返回等指令。最后要返回D

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論