微機(jī)原理軟件實(shí)驗(yàn)報(bào)告_第1頁
微機(jī)原理軟件實(shí)驗(yàn)報(bào)告_第2頁
微機(jī)原理軟件實(shí)驗(yàn)報(bào)告_第3頁
微機(jī)原理軟件實(shí)驗(yàn)報(bào)告_第4頁
微機(jī)原理軟件實(shí)驗(yàn)報(bào)告_第5頁
已閱讀5頁,還剩49頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

信息與通信工程學(xué)院微機(jī)原理軟件實(shí)驗(yàn)報(bào)告 班 級(jí): 姓 名: 學(xué) 號(hào): 日 期: 實(shí)驗(yàn)一DEBUG的使用 1一、實(shí)驗(yàn)?zāi)康?1二、實(shí)驗(yàn)內(nèi)容 1三、預(yù)習(xí)思考 3四、實(shí)驗(yàn)過程 4五、實(shí)驗(yàn)總結(jié) 7實(shí)驗(yàn)二分支、循環(huán)程序設(shè)計(jì) 8一、實(shí)驗(yàn)?zāi)康?8二、實(shí)驗(yàn)內(nèi)容 8三、預(yù)習(xí)思考 8四、實(shí)驗(yàn)過程 9(一)、流程圖 9(二)、源代碼 10(三)、實(shí)驗(yàn)分析 13五、實(shí)驗(yàn)總結(jié) 14實(shí)驗(yàn)三代碼轉(zhuǎn)換程序設(shè)計(jì) 15一、實(shí)驗(yàn)?zāi)康?15二、實(shí)驗(yàn)內(nèi)容 15三、預(yù)習(xí)思考 15四、實(shí)驗(yàn)過程 16(一)流程圖 16(二)模塊層次圖 16(三)源代碼 17(四)實(shí)驗(yàn)分析 21五、實(shí)驗(yàn)總結(jié) 22實(shí)驗(yàn)四子程序設(shè)計(jì) 23一、實(shí)驗(yàn)?zāi)康?23二、實(shí)驗(yàn)內(nèi)容 23三、預(yù)習(xí)思考 23四、實(shí)驗(yàn)過程 24(一)流程圖 24(二)模塊層次圖 25(三)源代碼 25(四)實(shí)驗(yàn)分析 39五、實(shí)驗(yàn)總結(jié) 40實(shí)驗(yàn)五中斷程序設(shè)計(jì) 41一、實(shí)驗(yàn)?zāi)康?41二、實(shí)驗(yàn)內(nèi)容 41三、預(yù)習(xí)思考 41四、實(shí)驗(yàn)過程 42(一)流程圖 42(二)源代碼 43(三)實(shí)驗(yàn)分析 49五、實(shí)驗(yàn)總結(jié) 50實(shí)驗(yàn)一DEBUG的使用一、實(shí)驗(yàn)?zāi)康恼莆諈R編程序的編輯、編譯、連接和執(zhí)行的全過程;學(xué)習(xí)和掌握用DEBUG調(diào)試程序的方法。二、實(shí)驗(yàn)內(nèi)容用編輯軟件,輸入以下匯編語言源程序:DATSEGMENTADB20BDB15YDB3DUP(0)ZDB0,0DATENDSSTASEGMENTSTACK DW50DUP(?)STAENDSCODSEGMENTASSUMECS:COD,DS:DATSTARPROCFAR PUSHDS XORAX,AX PUSHAX MOVAX,DAT MOVDS,AX MOVAX,STA MOVSS,AX MOVAL,A MOVZ,AL MOVZ+1,AL CALLSUB1 MOVAL,B MOVZ,AL MOVZ+1,AL CALLSUB1 MOVAL,A MOVZ,AL MOVAL,B MOVZ+1,AL CALLSUB1 ADDWORDPTRY,AX ADCBYTEPTR[Y+2],0 RETSTARENDPSUB1PROC MOVAL,Z MOVAH,Z+1 MULAH ADDWORDPTRY,AX ADCBYTEPTR[Y+2],0 RETSUB1ENDPCODENDS ENDSTAR通過編譯,連接形成可執(zhí)行文件。用DEBUG將可執(zhí)行文件調(diào)入,并進(jìn)行調(diào)試。用D命令觀察數(shù)據(jù)區(qū)在內(nèi)存中的具體內(nèi)容,記錄單元A和B的具體地址。用U命令對(duì)目標(biāo)代碼反匯編,觀察反匯編后的結(jié)果。注意發(fā)現(xiàn)源程序的起始位置,并記錄這個(gè)起始地址。用T命令作單步跟蹤調(diào)試。比較每條指令執(zhí)行后的結(jié)果和原來的理解是否一致,得出程序運(yùn)行的結(jié)果:它們是寫在什么單元,具體內(nèi)容是什么;并判斷結(jié)果是否正確。在子程序SUB1的入口處設(shè)一斷點(diǎn),用G命令執(zhí)行程序。在斷點(diǎn)處觀察堆棧的內(nèi)容,比較堆棧的內(nèi)容和程序返回地址是否一致。用E命令修改單元A,B的內(nèi)容,重新執(zhí)行程序,并記錄結(jié)果。用M命令和A命令對(duì)程序進(jìn)行修改:將主程序中最后兩條指令(ADD和ADC)修改為一條CALLSUB1指令,重新執(zhí)行程序。退出DEBUG。重新使用編輯軟件,把源程序最后一句中的STAR去掉。再次生成可執(zhí)行文件,并用DEBUG調(diào)入內(nèi)存。當(dāng)使用U命令時(shí),顯示的結(jié)果與前一次(未加STAR)的結(jié)果有何不同?三、預(yù)習(xí)思考熟悉常用的DEBUG命令。答:常用的DEBUG命令如下圖表所示。閱讀并分析程序的功能。答:程序完成的功能是計(jì)算兩個(gè)數(shù)的完全平方和,即計(jì)算。若SS=2000H,SP=FFFFH,向堆棧中壓入4字節(jié)數(shù)據(jù)后,如何用D命令顯示壓入堆棧的內(nèi)?答:使用的命令是:-D2000:FFFB,即使用段基址加偏移量查看。四、實(shí)驗(yàn)過程以下由實(shí)驗(yàn)截圖展現(xiàn)具體的實(shí)驗(yàn)過程,截圖進(jìn)行了詳細(xì)標(biāo)注,便于閱讀。上圖為編譯、鏈接形成可執(zhí)行文件的過程。上圖展現(xiàn)了進(jìn)行反編譯然后使用D命令查看數(shù)據(jù)段中A、B值的過程。上圖使用E命令對(duì)數(shù)據(jù)段數(shù)據(jù)A和B進(jìn)行了修改,分別由20和15改為了48和64,修改后用D命令進(jìn)行了查看。上圖演示了如何設(shè)置斷點(diǎn)。在SUB1出設(shè)置一斷點(diǎn),可以看到程序執(zhí)行到CALL0003F時(shí)中斷,各寄存器的值均有顯示。下圖為調(diào)用子程序SUB1,然后子程序結(jié)束,返回主程序前寄存器的值。可以看到,壓入堆棧的IP值彈出,CS:IP已經(jīng)指向了下一條語句的地址。下圖中操作實(shí)現(xiàn)的功能是將ADD和ADC兩條語句替換為CALL語句,通過A命令可以直接修改程序指令,通過插入NOP指令使CPU空閑。也可以通過M命令拷貝CALLSUB1的機(jī)器代碼到目的地址,但操作容易出錯(cuò),原因是源地址和目標(biāo)地址指令長度不一致。當(dāng)重新使用編輯軟件,把源程序最后一句中的STAR去掉。再次生成可執(zhí)行文件,再次DEBUG時(shí)。當(dāng)使用U命令時(shí),結(jié)果如下圖所示??梢钥吹剑瑳]有ENDSTAR語句,編譯器將不知道代碼段的入口地址是多少,導(dǎo)致從數(shù)據(jù)段開始譯碼,后續(xù)譯碼全部紊亂。ENDSTAR的作用是指示編譯器程序結(jié)束,同時(shí)告訴編譯器程序執(zhí)行時(shí)代碼段的入口地址。五、實(shí)驗(yàn)總結(jié)此次實(shí)驗(yàn)是微機(jī)原理軟件實(shí)驗(yàn)的第一次實(shí)驗(yàn)。由于平時(shí)只是注重理論的學(xué)習(xí),沒有多少實(shí)際編程和調(diào)試經(jīng)驗(yàn),上機(jī)操作還不熟練。以后需要加強(qiáng)實(shí)踐。匯編的調(diào)試很重要,有時(shí)比寫出源代碼更重要。代碼是很容易寫出的,就看是好是壞,編程技巧是否足夠,編程經(jīng)驗(yàn)是否豐富,但代碼的測(cè)試,排錯(cuò)確實(shí)十分困難的,很難把每一種可能的情況考慮周到,用戶的操作也可能出現(xiàn)各種不可預(yù)知的情況,往往細(xì)小的錯(cuò)誤甚至是不明確的地方都可能成為錯(cuò)誤的隱患。這也就是為何軟件開發(fā)三個(gè)之一的人寫代碼,三分之二的人進(jìn)行測(cè)試。這次實(shí)驗(yàn)我學(xué)會(huì)了匯編程序的基本調(diào)測(cè)方法,也體會(huì)到匯編的調(diào)試和C/C++或者Java調(diào)試的差異。匯編的調(diào)試需要深入堆棧和內(nèi)存區(qū),關(guān)心每一地址和每一個(gè)指令。這也體現(xiàn)匯編是底層語言的特點(diǎn)。實(shí)驗(yàn)二分支、循環(huán)程序設(shè)計(jì)一、實(shí)驗(yàn)?zāi)康拈_始獨(dú)立進(jìn)行匯編語言程序設(shè)計(jì);掌握基本分支,循環(huán)程序設(shè)計(jì);掌握最簡(jiǎn)單的DOS功能調(diào)用。二、實(shí)驗(yàn)內(nèi)容安排一個(gè)數(shù)據(jù)區(qū),內(nèi)存有若干個(gè)正數(shù),負(fù)數(shù)和零。每類數(shù)的個(gè)數(shù)都不超過9。編寫一個(gè)程序統(tǒng)計(jì)數(shù)據(jù)區(qū)中正數(shù),負(fù)數(shù)和零的個(gè)數(shù)。將統(tǒng)計(jì)結(jié)果在屏幕上顯示。(擴(kuò)展題)統(tǒng)計(jì)出正奇數(shù)、正偶數(shù),負(fù)奇數(shù)、負(fù)偶數(shù)以及零的個(gè)數(shù)。三、預(yù)習(xí)思考十進(jìn)制數(shù)0~9所對(duì)應(yīng)的ASCII碼是什么?如何將十進(jìn)制數(shù)0~9在屏幕上顯示出來?答:0~9分別對(duì)應(yīng)ASCII碼的30H~39H。欲將十進(jìn)制數(shù)0~9顯示在屏幕上,只需要用二進(jìn)制數(shù)0~9分別加上30H即可。如何檢驗(yàn)一個(gè)數(shù)為正,為負(fù)或?yàn)榱??你能舉出多少種不同的方法?答:方法有多種,現(xiàn)舉出兩種。一是直接用CMP命令和0比較,然后用JZ等命令進(jìn)行判斷;二是和0相比是否相等,然后用該數(shù)(假設(shè)為8位)和10000000相與,取出符號(hào)位判斷,可區(qū)分正負(fù)。其余方法大同小異,核心的思想是要么直接和0相比,要么使用邏輯或移位運(yùn)算,取出符號(hào)為進(jìn)行判斷。

四、實(shí)驗(yàn)過程(一)、流程圖

(二)、源代碼DATASEGMENT ARRAYDB1,2,3,4,5,6,-1,-2,-3,0,0,0 LENGEQU$-ARRAY;數(shù)組長度 POSIDB?;正數(shù)個(gè)數(shù) NEGTDB?;負(fù)數(shù)個(gè)數(shù) ZERODB?;零的個(gè)數(shù) POSIEVENDB?;正偶數(shù) POSIODDDB?;正奇數(shù) NEGTEVENDB?;負(fù)偶數(shù) NEGTODDDB?;負(fù)奇數(shù) ;用于打印提示的字符串定義 POSICHARDB'Positive:$' NEGTCHARDB'Negtive:$' ZEROCHARDB'Zero:$' EVENCHARDB'Even:$' ODDCHARDB'Odd:$' CRDB0DH,0AH,'$';回車換行的ASCII碼DATAENDS;CODESEGMENT ASSUMECS:CODE,DS:DATA;START: MOVAX,DATA MOVDS,AX MOVSI,OFFSETARRAY-1 MOVCL,LENG;數(shù)組長度賦予CL MOVAL,0LOP: CMPCL,0;循環(huán)控制條件:數(shù)組長度減為零 JECALC;為零則跳出 INCSI DECCL MOVBL,[SI];采用基址加變址尋址 CMPBL,AL;和零比較 JGISPOSI;是正數(shù)跳轉(zhuǎn) JEISZERO;是零跳轉(zhuǎn) JLISNEGT;是負(fù)數(shù)跳轉(zhuǎn);ISPOSI: INCPOSI;正數(shù)個(gè)數(shù)加一 ANDBX,1 ADDPOSIEVEN,BL;和1與之后的結(jié)果加到正偶數(shù)中 JMPLOPISZERO: INCZERO JMPLOPISNEGT: INCNEGT;負(fù)數(shù)個(gè)數(shù)加一 ANDBX,1 ADDNEGTEVEN,BL;和1與之后結(jié)果加到負(fù)偶數(shù)中 JMPLOP;CALC: MOVAH,POSI MOVAL,POSIEVEN SUBAH,AL;計(jì)算正奇數(shù)個(gè)數(shù) MOVPOSIODD,AH MOVAH,NEGT MOVAL,NEGTEVEN SUBAH,AL;計(jì)算負(fù)奇數(shù)個(gè)數(shù) MOVNEGTODD,AH;PRINT: ;打印正數(shù)提示符和正數(shù)(奇偶)個(gè)數(shù) MOVAH,09H MOVDX,OFFSETPOSICHAR INT21H MOVAH,02H MOVDL,POSI ADDDL,30H INT21H MOVAH,09H MOVDX,OFFSETEVENCHAR INT21H MOVAH,02H MOVDL,POSIEVEN ADDDL,30H INT21H MOVAH,09H MOVDX,OFFSETODDCHAR INT21H MOVAH,02H MOVDL,POSIODD ADDDL,30H INT21H MOVDX,OFFSETCR MOVAH,09H INT21H; ;打印負(fù)數(shù)提示符和負(fù)數(shù)(奇偶)個(gè)數(shù) MOVAH,09H MOVDX,OFFSETNEGTCHAR INT21H MOVAH,02H MOVDL,NEGT ADDDL,30H INT21H MOVAH,09H MOVDX,OFFSETEVENCHAR INT21H MOVAH,02H MOVDL,NEGTEVEN ADDDL,30H INT21H MOVAH,09H MOVDX,OFFSETODDCHAR INT21H MOVAH,02H MOVDL,NEGTODD ADDDL,30H INT21H MOVDX,OFFSETCR MOVAH,09H INT21H MOVAH,09H MOVDX,OFFSETZEROCHAR INT21H MOVAH,02H MOVDL,ZERO ADDDL,30H INT21HEXT: MOVAX,4C00H INT21H;CODE ENDS ENDSTART(三)、實(shí)驗(yàn)分析數(shù)據(jù)區(qū)待統(tǒng)計(jì)的數(shù)據(jù)為:1,2,3,4,5,6,-1,-2,-3,0,0,0實(shí)驗(yàn)結(jié)果如下圖所示。本實(shí)驗(yàn)較為簡(jiǎn)單,意在練習(xí)基本的分支、循環(huán)結(jié)構(gòu)。關(guān)鍵的點(diǎn)在于和0比較,區(qū)分正負(fù)和零,然后在正數(shù)和負(fù)數(shù)中判斷奇偶,這里巧妙地使用了和1與之后加和到偶數(shù)中,最后利用統(tǒng)計(jì)的數(shù)的個(gè)數(shù)減去偶數(shù)得奇數(shù)的方法。使得程序更加流暢和簡(jiǎn)潔,思路也更清晰。五、實(shí)驗(yàn)總結(jié)實(shí)驗(yàn)中設(shè)計(jì)好的計(jì)算思路是很重要的,匯編的代碼由各種跳轉(zhuǎn)和邏輯結(jié)構(gòu)組成,需要考慮代碼間的邏輯關(guān)系,否則容易出錯(cuò)。語法錯(cuò)誤是很顯而易見的,但邏輯錯(cuò)誤卻不容易發(fā)現(xiàn)。當(dāng)有大量判斷和循環(huán)存在時(shí),需要考慮清楚程序跳轉(zhuǎn)的條件和方向,這點(diǎn)和高級(jí)語言有較大差異,匯編本質(zhì)上沒有循環(huán)和分支,都是通過將IP賦予代碼區(qū)地址進(jìn)行跳轉(zhuǎn)實(shí)現(xiàn)的,程序員需要自主控制如何跳轉(zhuǎn),向何處跳轉(zhuǎn),這點(diǎn)和C/C++中飽受詬病的goto語句處理有些類似??紤]到實(shí)驗(yàn)練習(xí)的重點(diǎn)在分支循環(huán)結(jié)構(gòu),此次寫代碼時(shí)暫時(shí)沒有使用子程序或宏,導(dǎo)致輸出部分代碼有些過長。實(shí)驗(yàn)三代碼轉(zhuǎn)換程序設(shè)計(jì)一、實(shí)驗(yàn)?zāi)康恼莆諑追N最基本的代碼轉(zhuǎn)換方法;運(yùn)用子程序進(jìn)行程序設(shè)計(jì)。二、實(shí)驗(yàn)內(nèi)容從鍵盤上輸入若干兩位十進(jìn)制數(shù),尋找其中的最小值,然后在屏幕上顯示出來。兩個(gè)十進(jìn)制數(shù)之間的分隔符,輸入結(jié)束標(biāo)志自定,但要在報(bào)告中說明。對(duì)輸入要有檢錯(cuò)措施,以防止非法字符輸入,并有適當(dāng)?shù)奶崾尽⒄麄€(gè)程序分解為若干模塊,分別用子程序?qū)崿F(xiàn)。在報(bào)告中要給出模塊層次圖。三、預(yù)習(xí)思考如何將輸入的兩個(gè)字符(0~9)變?yōu)槭M(jìn)制或二進(jìn)制數(shù)?答:輸入的字符0~9是ASCII碼表示的,對(duì)應(yīng)于30H~39H,通過減去30H,可以轉(zhuǎn)換為相應(yīng)的計(jì)算機(jī)數(shù)。如何將選出的最小值(二進(jìn)制或十進(jìn)制)變?yōu)锳SCII碼再進(jìn)行顯示?答:如果采用輸入時(shí)把ASCII碼轉(zhuǎn)換為數(shù)字,然后比較數(shù)字的大小再輸出,那么輸出時(shí)還需要把數(shù)字再次轉(zhuǎn)換為ASCII碼。這是不明智的??梢灾苯幼x入并存儲(chǔ)數(shù)字的ASCII碼,容易比較其大小,然后直接輸出ASCII碼即可。你覺得采用二進(jìn)制運(yùn)算還是十進(jìn)制運(yùn)算更適合于這個(gè)實(shí)驗(yàn)?答:采用二進(jìn)制或者十進(jìn)制都需要進(jìn)行ASCII碼到數(shù)字的轉(zhuǎn)換和其反向轉(zhuǎn)換,換用新的思路可以大大簡(jiǎn)化編程負(fù)擔(dān)。即直接使用數(shù)字對(duì)應(yīng)的ASCII比較,分別比較十位和個(gè)位,最后直接輸出字符即可。四、實(shí)驗(yàn)過程(一)流程圖(二)模塊層次圖(三)源代碼DATASEGMENTINPUTDB100DUP(?)MINTMPDB'9'-30H,'9'-30H;置最小值的初始值為99COUNTDB0DIFERRORDB0D;用于判斷調(diào)用輸入子程序是否有錯(cuò);提示信息字符串WELCOMEDB'Pleaseinputnumbers:','$'OUTTIPDB'Minimumis:','$'CRDB0DH,0AH,'$';回車換行;各種錯(cuò)誤輸入提示ERROR1DB'ERROR:Characterisnotvalid!','$'ERROR2DB'ERROR:Numbermustcontainstwodigits!','$'ERROR3DB'ERROR:Numberisempty!','$'ERROR4DB'ERROR:Needseparatechar!','$'DATAENDS;CODESEGMENT ASSUMECS:CODE,DS:DATAMAINPROCFAR MOVAX,DATA MOVDS,AX MOVDX,OFFSETWELCOME;調(diào)用歡迎提示 CALLPRINT MOVDX,OFFSETCR;回車換行 CALLPRINT CALLGETNUM;獲取用戶輸入 CMPIFERROR,0;判斷輸入過程是否有錯(cuò) JNZBACK;錯(cuò)誤則直接返回DOS MOVDX,OFFSETCR;回車換行 CALLPRINT CALLFINDMIN;查找最小數(shù) MOVDX,OFFSETOUTTIP;調(diào)用輸出提示 CALLPRINT MOVAH,02H MOVDL,MINTMP;輸出最小值的十位 ADDDL,30H INT21H MOVAH,02H MOVDL,MINTMP[1];輸出最小值的個(gè)位 ADDDL,30H INT21H BACK: MOVAX,4C00H;返回DOS INT21HMAINENDP;;獲取輸入,出口參數(shù)為IFERROR,表示是否有錯(cuò)GETNUMPROC PUSHAX;保存現(xiàn)場(chǎng) PUSHBX PUSHCX PUSHDX PUSHDI MOVDI,0;數(shù)組偏移地址 MOVCX,0;標(biāo)識(shí)數(shù)字的位數(shù)GETLOOP: MOVAH,01H;從鍵盤讀取一個(gè)字符 INT21H CMPAL,0DH;和回車比較 JEEXIT1;是回車則結(jié)束輸入 CMPCX,0;數(shù)字位數(shù)為空 JECMPSPACE0 CMPCX,1;數(shù)字位數(shù)為1 JECMPSPACE1 CMPCX,2;數(shù)字位數(shù)為2 JECMPSPACE2CMPSPACE0:CMPAL,20H JEGETLOOP;數(shù)字位數(shù)為0且輸入空格則忽略,繼續(xù)輸入 JMPASCBIN;不是空格就讀取該字符CMPSPACE1:CMPAL,20H JEERR2;數(shù)字位數(shù)為1且輸入空格則位數(shù)不是兩位數(shù)出錯(cuò) JMPASCBIN;否則讀取該字符CMPSPACE2:CMPAL,20H JNEERR4;數(shù)字位數(shù)為2后,不輸入空格則分隔符錯(cuò)誤 XORCX,CX;輸入空格則清零重新計(jì)數(shù) JMPGETLOOP ASCBIN: SUBAL,30H;化為二進(jìn)制數(shù)字 JLERR1;小于則無效字符 CMPAL,9;和9比較 JGERR1;大于9則是無效字符 MOVINPUT[DI],AL;保存輸入的數(shù) INCCOUNT;統(tǒng)計(jì)輸入的數(shù)字個(gè)數(shù),為判斷是否輸入為兩位數(shù) INCDI;向后移動(dòng)數(shù)組 INCCX JMPGETLOOPERR1: MOVIFERROR,1;輸出錯(cuò)誤1 MOVDX,OFFSETERROR1 CALLPRINT JMPRETURNERR2: MOVIFERROR,1;輸出錯(cuò)誤2 MOVDX,OFFSETERROR2 CALLPRINT JMPRETURN ERR3: MOVIFERROR,1;輸出錯(cuò)誤3 MOVDX,OFFSETERROR3 CALLPRINT JMPRETURN ERR4: MOVIFERROR,1;輸出錯(cuò)誤4 MOVDX,OFFSETERROR4 CALLPRINT JMPRETURN EXIT1: MOVBL,COUNT;判斷輸入數(shù)的個(gè)數(shù)是否為零 CMPBL,0 JEERR3;輸入數(shù)目為0則輸出錯(cuò)誤并退出 ANDBL,01H;判斷數(shù)字是否為兩位數(shù) CMPBL,0 JNEERR2;輸入數(shù)字個(gè)數(shù)為奇數(shù)則出錯(cuò)RETURN: POPDI;恢復(fù)現(xiàn)場(chǎng) POPDX POPCX POPBX POPAX RETGETNUMENDP;;回車換行輸出字符串,入口參數(shù)為DXPRINTPROC PUSHAX MOVAH,09H INT21H POPAX RETPRINTENDP;;查找最小的數(shù)子程序FINDMINPROC PUSHDI;保護(hù)現(xiàn)場(chǎng) PUSHAX PUSHCX MOVDI,-2;數(shù)組下標(biāo) MOVCL,COUNT;把數(shù)組長度移入CX MOVAL,CL CBW MOVCX,AXLOP: ADDDI,2 CMPCX,DI;是否已經(jīng)比較完畢 JEEXIT2;如果比較完畢所有數(shù)則退出 MOVAH,INPUT[DI];否則接著比較,移入十位數(shù) MOVAL,INPUT[DI+1];移入個(gè)位數(shù) CMPAH,MINTMP;比較十位數(shù),MINTMP低地址為十位 JALOP;如果MINTMP小,則直接比較下一個(gè)數(shù) JEHIGHEQU ;如果十位數(shù)相等,比較個(gè)位數(shù),再否則十位大就直接存儲(chǔ)STOMIN: MOVMINTMP,AH MOVMINTMP[1],AL JMPLOPHIGHEQU: CMPAL,MINTMP[1];比較個(gè)位數(shù) JNBLOP;個(gè)位數(shù)比MINTMP大則跳到下一個(gè)數(shù) JMPSTOMIN;否則將當(dāng)前數(shù)寫入為MINTMPEXIT2: POPCX POPAX POPDI RETFINDMINENDP;CODEENDS ENDMAIN (四)實(shí)驗(yàn)分析下圖是實(shí)驗(yàn)輸出結(jié)果截圖。實(shí)驗(yàn)中以空格為分隔符,空格的個(gè)數(shù)不限制,以回車為輸入結(jié)束標(biāo)志符。對(duì)輸入的數(shù)字進(jìn)行了位數(shù)和范圍的嚴(yán)格限制,即必須是兩位數(shù)字,如果數(shù)字小于10,需要補(bǔ)齊零。實(shí)驗(yàn)中對(duì)輸入錯(cuò)誤執(zhí)行嚴(yán)格的檢查,出錯(cuò)則重新輸入。判斷輸入錯(cuò)誤的核心思路為:以空格為分割,以回車結(jié)束,要求必須是兩位數(shù),也即,一位數(shù)字后不能有空格,兩位數(shù)字后必須有空格,回車之后總的輸入進(jìn)行判斷,數(shù)字個(gè)數(shù)必須為偶數(shù),以上三種情況囊括了所有可能的格式錯(cuò)誤,不滿足任何一個(gè)條件即出錯(cuò)。滿足格式輸入后,再判斷字符的是否0~9,不是則出錯(cuò)。每項(xiàng)錯(cuò)誤均已錯(cuò)誤列表的形式給出,打印出錯(cuò)誤提示??偨Y(jié)實(shí)驗(yàn)中的關(guān)鍵設(shè)計(jì)思路如下:1、嚴(yán)格的輸入格式檢查,嚴(yán)格的輸入字符有效性檢查。2、以數(shù)組方式進(jìn)行存儲(chǔ),每兩個(gè)BYTE存儲(chǔ)一個(gè)輸入的兩位數(shù),存儲(chǔ)格式為字符ASCII碼。不進(jìn)行字符ASCII碼到數(shù)字的轉(zhuǎn)換。3、比較數(shù)字大小時(shí),采用分別比較高位ASCII碼和低位ASCII碼的方式,從而不用在輸入時(shí)將字符存儲(chǔ)為數(shù)字,輸出時(shí)也不用再進(jìn)行逆轉(zhuǎn)換。程序效率大為提高。4、為使得程序結(jié)構(gòu)清晰,減小代碼耦合度,采用了多子程序的設(shè)計(jì)方式。把實(shí)驗(yàn)任務(wù)分為三步:讀取輸入、找出最小、輸出打印,分別以子程序方式實(shí)現(xiàn),主調(diào)函數(shù)依次調(diào)用完成實(shí)驗(yàn)任務(wù)。五、實(shí)驗(yàn)總結(jié)本實(shí)驗(yàn)的關(guān)鍵點(diǎn)在于如何設(shè)計(jì)子程序完成部分功能。在設(shè)計(jì)子程序的過程中,我依據(jù)結(jié)構(gòu)化代碼的流程進(jìn)行劃分,自然形成了讀取輸入、找出最小、打印輸出的思路。這一思路是沒有問題的,但存在子程序劃分還不夠細(xì)致的問題,比如,讀取輸入子程序代碼過于冗長,這是因?yàn)槲覜]有把輸入格式檢查、錯(cuò)誤提示單獨(dú)作為子過程進(jìn)行獨(dú)立編寫。這是設(shè)計(jì)中的一大不足,這一缺陷也讓我在調(diào)試子程序的時(shí)候頗費(fèi)周折。這次教訓(xùn)一定要銘記。實(shí)驗(yàn)中比較大小的方式有多種,如何采用更加簡(jiǎn)潔有效的方式是值得思考的問題。我一開始也不免陷入到比較數(shù)字大小的常規(guī)方法中,但由于匯編輸入具有特殊性,即輸入的是ASCII碼而非數(shù)字的大小,且存在將兩個(gè)字符進(jìn)行連接成為兩位數(shù)的需求,而輸出時(shí)又需要進(jìn)行反過程??紤]到ASCII也是可以比較的,且十位數(shù)和個(gè)位數(shù)是可以分別比較的這一情況,我采用了巧妙的方式進(jìn)行處理。這說明,在實(shí)際的編程中,需要根據(jù)具體情況調(diào)整一般方法,使得方法更加簡(jiǎn)潔可行且有效。實(shí)驗(yàn)四子程序設(shè)計(jì)一、實(shí)驗(yàn)?zāi)康倪M(jìn)一步掌握子程序設(shè)計(jì)方法;進(jìn)一步掌握基本的DOS功能調(diào)用。二、實(shí)驗(yàn)內(nèi)容從鍵盤上輸入某班學(xué)生的某科目成績。輸入按學(xué)生的學(xué)號(hào)由小到大的順序輸入。統(tǒng)計(jì)檢查每個(gè)學(xué)生的名次。將統(tǒng)計(jì)結(jié)果在屏幕上顯示。為便于觀察,輸入學(xué)生數(shù)目不宜太多,以不超過一屏為宜。輸出應(yīng)便于閱讀.盡可能考慮美觀。輸入要有檢錯(cuò)手段。三、預(yù)習(xí)思考如何確定一個(gè)學(xué)生在這門科目中的名次?答:有兩種基本思路,一是抽取每個(gè)學(xué)生的成績和其他所有學(xué)生的成績進(jìn)行比較,然后統(tǒng)計(jì)比其分?jǐn)?shù)高的學(xué)生,得出該學(xué)生的名次;二是把學(xué)生成績存入連續(xù)內(nèi)存區(qū)域,即數(shù)組方式,取得每個(gè)學(xué)生的成績偏移量,即成績指針。然后比較指針?biāo)傅某煽兊拇笮?,根?jù)比較結(jié)果移動(dòng)指針完成排序。具體排序時(shí)可以采用諸多的方式,比如冒泡法,快速排序法等等,均是可行的。本實(shí)驗(yàn)采用第二種方式,用冒泡法予以具體實(shí)現(xiàn)。輸入結(jié)束后,采用什么方法進(jìn)行比較以得到學(xué)生的名次最為簡(jiǎn)單?答:如上問所述,采用冒泡排序法可獲得較好的時(shí)間和空間性能。冒泡法平均時(shí)間性能O(N2)。相比于直接比較,性能有所改善。但相對(duì)于快速排序、歸并排序等優(yōu)化的算法的時(shí)間復(fù)雜度O(N*log2N)還不夠好。但后兩者使用匯編實(shí)現(xiàn)代碼的復(fù)雜度和編程要求要高。考慮到學(xué)生人數(shù)比較少,使用冒泡法是比較簡(jiǎn)潔的,時(shí)間性能是可以接受的。準(zhǔn)備好模塊層次圖。答:見下文“實(shí)驗(yàn)過程”中所示。給出輸出顯示的形式。答:輸出以列表形式給出。學(xué)號(hào)、分?jǐn)?shù)、名次各一列。具體形式參見實(shí)驗(yàn)分析部分的輸出截圖。四、實(shí)驗(yàn)過程(一)流程圖(二)模塊層次圖(三)源代碼DATASEGMENTIDDB400DUP(?);存儲(chǔ)學(xué)號(hào),每個(gè)16固定個(gè)BYTE,存儲(chǔ)為字符串 MARKDB20DUP(?);存儲(chǔ)分?jǐn)?shù),每個(gè)1BYTE,存儲(chǔ)為二進(jìn)制數(shù) RANKDB20DUP(?);存儲(chǔ)排名,每個(gè)1BYTE,存儲(chǔ)為二進(jìn)制數(shù) RANKTMPDB20DUP(?);排序時(shí)指針臨時(shí)區(qū) MTMPDB?;記錄成績的臨時(shí)區(qū) COUNTBDB?;記錄總的學(xué)生的個(gè)數(shù),存為8位 COUNTWDW?;記錄總的學(xué)生個(gè)數(shù),存為16位 CHEOKDB?;輸入檢查標(biāo)志位 ERRORDB?;記錄錯(cuò)誤號(hào) TMPDB2DUP(?);開辟兩個(gè)內(nèi)存臨時(shí)存儲(chǔ)區(qū),用作判斷和計(jì)數(shù) CRDB0DH,0AH,'$';回車換行 TABDB09H,09H,'$';輸出TAB鍵 ERR0DB'Inputcannotbeempty!','$' ERR2DB'Characterisinvalid!','$' ERR4DB'Markisinvalid!','$' ERR6DB'Inputisinvalid!','$' ERRLISTDWERR0,ERR2,ERR4,ERR6 TIP0DB'Pleasere-input:','$' TIP1DB'Pleaseinputnumberofstudents:','$' TIP2DB'PleaseinputIDandMARK:','$' PRTIPDB'RESULT','$' PRINFODB'ID',09H,09H,'MARK',09H,09H,'RANK','$' PRPRE1DB'ID:','$' PRPRE2DB'MARK:','$' BUFFDB16;定義輸入緩沖區(qū),最長的字符長度 PRESDB?;存儲(chǔ)實(shí)際輸入了多少個(gè)字符 CHARDB16DUP(?);實(shí)際可存儲(chǔ)有效字符16個(gè)DATAENDSCODESEGMENT;;打印提示字信息的宏,形參為PARAPRINTTIPMACROPARA PUSHAX PUSHDX MOVAH,09H MOVDX,OFFSETPARA INT21H POPDX POPAXENDM;;打印單個(gè)字符的宏,形參為ACHARPRINTCHARMACROACHAR PUSHAX PUSHDX MOVAH,02H MOVDL,ACHAR INT21H POPDX POPAXENDM;;主程序MAINPROCFAR ASSUMECS:CODE,DS:DATA,ES:DATA MOVAX,DATA MOVDS,AX MOVES,AX CALLGETNUMBER;獲得學(xué)生的人數(shù) CALLGETINFO;獲得學(xué)號(hào)分?jǐn)?shù)的輸入 CALLSORT;執(zhí)行排序活動(dòng)名次 CALLPRINT;把名次結(jié)果打印出來BACK: MOVAX,4C00H;返回DOS INT21HMAINENDP ;;獲得將要輸入的學(xué)生的人數(shù)信息的子程序;每班的學(xué)生定義不超過100人GETNUMBERPROCNEAR PUSHAX PUSHBXHE: PRINTTIPTIP1GREP: CALLGETIN;獲取一個(gè)輸入緩沖 MOVCHEOK,0 CALLCHECK CMPCHEOK,0 JEGRETURN MOVERROR,6 CALLPRINTERR PRINTTIPTIP0 PRINTTIPCR JMPGREPERRHERE: PRINTTIPCR MOVERROR,6 CALLPRINTERR PRINTTIPTIP0 JMPGREPGRETURN: CALLCHANGE MOVAL,MTMP CMPAL,0 JEERRHERE MOVCOUNTB,AL;寫入人數(shù) CBW MOVCOUNTW,AX PRINTTIPCR POPBX POPAX RETGETNUMBERENDP;;循環(huán)直到輸入人數(shù)滿時(shí)終止,獲得輸入的字符串GETINFOPROCNEAR PUSHAX PUSHBX PUSHCX PUSHDX PUSHSI PUSHDI PRINTTIPTIP2 MOVTMP,0;記錄是學(xué)號(hào)還是分?jǐn)?shù) XORBX,BX;記錄每個(gè)ID的偏移量 XORAX,AX;記錄學(xué)生數(shù)目MORE: PRINTTIPCR CMPCOUNTB,AL JNZHERE1 JMP RETURN;計(jì)數(shù)器為0則返回父程序HERE1: CMPTMP,0 JEPR1 CMPTMP,1 JEPR2PR1: PRINTTIPPRPRE1 JMPHERE2PR2: PRINTTIPPRPRE2HERE2: CALLGETIN;否則接受輸入 CALLCHECK;檢查輸入是否是數(shù)字且不為空 CMPCHEOK,0 JNECHEFAIL;不為零則不合法,需要重新輸入 CMPTMP,0 JEISID;輸入的是學(xué)號(hào) CMPTMP,1; JEISMARK;輸入的是分?jǐn)?shù)CHEFAIL: PRINTTIPTIP0 PRINTTIPCR MOVCHEOK,0;重新把返回判斷位置零 JMPMORE;寫入學(xué)號(hào),固定為16個(gè)字符ISID: MOVDL,PRES;抽取需要寫入字符的個(gè)數(shù) XORDH,DH MOVCX,DX MOVSI,CX INCCX MOVCHAR[SI],'$';把最后一個(gè)字符之后的位置填充為'$' ;開始寫入ID MOVTMP,1;表示下一個(gè)是分?jǐn)?shù) CLD MOVSI,OFFSETCHAR MOVDI,OFFSETID ADDDI,BX REPMOVSB;寫入ID ;寫完則為接受下一個(gè)輸入BUFF作準(zhǔn)備 ADDBX,16;ID的偏移地址向后挪動(dòng)固定的16BYTE JMPMORE;跳回繼續(xù)輸入下一個(gè)BUFF;是學(xué)號(hào),檢查、轉(zhuǎn)換、寫入保存ISMARK: CALLCHANGE CMPCHEOK,0 JEWRITEMARK MOVERROR,4 JMPCHEFAILWRITEMARK: PUSHBX MOVBL,MTMP MOVDI,AX MOVMARK[DI],BL;實(shí)際寫入成績 POPBX MOVTMP,0;計(jì)數(shù)清理,表明下一個(gè)輸入為學(xué)號(hào) INCAX;已接受的學(xué)生個(gè)數(shù)加一 JMPMORERETURN: POPDI POPSI POPDX POPCX POPBX POPAX RETGETINFOENDP;;獲得一次BUFF輸入子程序;入口參數(shù)為BUFF的偏移地址,出口參數(shù)為BUFF中的字符串 GETINPROCNEAR PUSHAX PUSHDX PUSHDI MOVDX,OFFSETBUFF MOVAH,0AH INT21H POPDI POPDX POPAX RETGETINENDP;;執(zhí)行輸入字符是否是數(shù)字的合法性檢查CHECKPROCNEAR PUSHDI PUSHCX PUSHAX XORDI,DI;記錄CHAR讀取的偏移量 MOVAL,PRES;讀取輸入的BUFF中的字符數(shù) CBW MOVCX,AX CMPCX,0;判斷是否輸入BUFF為空 JEISEMPTY;為空則重新輸入AGAIN: CMPCX,DI JERETURNCHECK MOVAH,CHAR[DI] CMPAH,30H; JLINVALID;小于則無效字符 CMPAH,39H; JGINVALID;大于則是無效字符 INCDI JMPAGAINISEMPTY: MOVERROR,0;輸入為空的處理代碼 PRINTTIPCR CALLPRINTERR PRINTTIPCR MOVCHEOK,1 JMPRETURNCHECKINVALID:MOVERROR,2;輸入不合法的處理代碼 PRINTTIPCR CALLPRINTERR PRINTTIPCR MOVCHEOK,1RETURNCHECK: POPAX POPCX POPDI RETCHECKENDP;;處理成績輸入的子程序;檢查輸入成績是否在0-100之間的子程序并轉(zhuǎn)化為二進(jìn)制數(shù)CHANGEPROCNEAR ;把3位數(shù)字轉(zhuǎn)換為二進(jìn)制數(shù) PUSHAX PUSHBX PUSHCX MOVCL,PRES CMPCL,3 JAMINVALID;四位數(shù)或以上,溢出 JETHRDIG;三位數(shù) CMPCL,2 JETWODIG;兩位數(shù) CMPCL,1 JEONEDIG;一位數(shù)THRDIG: ;判斷是否是100,是則直接在臨時(shí)成績區(qū)寫入100 MOVBL,CHAR[0];百位 SUBBL,30H CMPBL,1 JNEMINVALID MOVBL,CHAR[1];十位 SUBBL,30H CMPBL,0 JNEMINVALID MOVBL,CHAR[2];個(gè)位 SUBBL,30H CMPBL,0 JNEMINVALID MOVMTMP,100;寫入100 JMPCRETURNTWODIG:;當(dāng)是兩位數(shù)時(shí)判斷十位是否是0,不是則進(jìn)行轉(zhuǎn)換,然后寫入臨時(shí)成績中 MOVBL,CHAR[0];十位 SUBBL,30H CMPBL,0 JEMINVALID MOVAL,10 MULBL;成10取得十位數(shù) MOVBL,CHAR[1];個(gè)位 SUBBL,30H ADDAL,BL;因?yàn)樾∮?00所以有效數(shù)在AL中, ;可以直接加個(gè)位數(shù)得結(jié)果 MOVMTMP,AL;寫入轉(zhuǎn)換后的數(shù)字 JMPCRETURNONEDIG: ;一位數(shù)時(shí)直接寫入臨時(shí)成績區(qū)即可 MOVBL,CHAR[0];個(gè)位 SUBBL,30H MOVMTMP,BL JMPCRETURNMINVALID: MOVERROR,4 CALLPRINTERR MOVCHEOK,1 CRETURN: POPCX POPBX POPAX RETCHANGEENDP;;打印錯(cuò)誤信息子程序PRINTERRPROCNEAR PUSHAX PUSHDX PUSHBX MOVAL,ERROR CBW MOVBX,AX MOVAH,09H MOVDX,ERRLIST[BX] INT21H POPBX POPDX POPAX RETPRINTERRENDP;;排序子程序SORTPROCNEAR PUSHAX PUSHBX PUSHCX PUSHDX PUSHSI PUSHDI ;寫入偏移量作為分?jǐn)?shù)的指針 MOVAL,COUNTB;讀取學(xué)生數(shù)目 XORBX,BX;BX作為尋址計(jì)數(shù)器 ;順序?qū)懭氤煽兤屏縎LOP: DECAL MOVRANKTMP[BX],AL INCBX CMPAL,0 JNESLOP ;排序名次,冒泡排序法 MOVCX,COUNTW;CX記錄了總的學(xué)生人數(shù) DECCX JZWRRAK;如果只有一個(gè)學(xué)生則直接寫入名次,否則排序異常LOP1: XORDI,DI;從第一個(gè)名次開始LOP2: MOVAL,RANKTMP[DI];取出地址指針,即成績偏移量 XORAH,AH MOVSI,AX MOVDL,MARK[SI];取出成績1 MOVAL,RANKTMP[DI+1] XORAH,AH MOVSI,AX MOVDH,MARK[SI];同理取出成績2 CMPDL,DH JGENEXTCMP MOVAH,RANKTMP[DI];交換分?jǐn)?shù)指針 XCHGAH,RANKTMP[DI+1] MOVRANKTMP[DI],AH NEXTCMP:INCDI CMPDI,CX JNELOP2 LOOPLOP1 ;寫入最后的名次WRRAK: XORSI,SI MOVCX,COUNTW MOVBL,1;保存名次LOPSAVE: CMPSI,CX JEFINISH MOVAL,RANKTMP[SI];提取該名次學(xué)生的地址指針 XORAH,AH MOVDI,AX MOVRANK[DI],BL;寫入該學(xué)生的名次 INCBL INCSI JMPLOPSAVEFINISH: POPDI POPSI POPDX POPCX POPBX POPAX RETSORTENDP;;打印輸入成績和名次子程序PRINTPROCNEAR PUSHAX PUSHBX PUSHCX PUSHDX PUSHSI PRINTTIPCR PRINTTIPPRTIP;打印提示信息 PRINTTIPCR PRINTTIPPRINFO PRINTTIPCR MOVCX,COUNTW;CX用于保存學(xué)生人數(shù) XORSI,SI;SI用于指明當(dāng)前處理的學(xué)生的序號(hào) XORBX,BX;BX保存當(dāng)前輸入的學(xué)號(hào)偏移量,每次增16NEXPRINT: MOVTMP[1],0;對(duì)打印名次置標(biāo)志位,表明沒有打印名次 CMPSI,CX JNEPRINTID JMPPRETPRINTID: ;打印學(xué)號(hào),直接字符串打印,因結(jié)尾寫入了'$' MOVAH,09H MOVDX,OFFSETID ADDDX,BX INT21H PRINTTIPTABPRINTMARK: ;打印分?jǐn)?shù),分為100、10-99、0-9三中情況打印 MOVAL,MARK[SI]PRINTRANK: CMPAL,100 JEPTTHR CMPAL,10 JLPTONE JMPPTTWOPTTHR: ;是100則直接輸出字符串即可,不必轉(zhuǎn)化 PRINTCHAR'1' PRINTCHAR'0' PRINTCHAR'0' JMPNEXTPTTWO: ;10-99需要除以10,商和余數(shù)分別是十位和個(gè)位 CBW PUSHBX MOVBL,10 DIVBL MOVBX,AX ADDBL,30H ADDBH,30H PRINTCHARBL PRINTCHARBH POPBX JMPNEXTPTONE: ;0-9直接二進(jìn)制轉(zhuǎn)到ASCII碼然后輸出 ADDAL,30H PRINTCHARALNEXT: PRINTTIPTAB ;開始打印名次,和打印成績復(fù)用代碼 MOVAL,RANK[SI] CMPTMP[1],0 JNEFINISHP MOVTMP[1],1 JMPPRINTRANK FINISHP: PRINTTIPCR;打印完一個(gè)學(xué)生的學(xué)號(hào)成績及名次,回車換行 INCSI ADDBX,16;進(jìn)行下一個(gè)學(xué)生的打印 JMPNEXPRINTPRET: POPSI POPDX POPCX POPBX POPAX RETPRINTENDP;CODEENDS ENDMAIN(四)實(shí)驗(yàn)分析輸入輸出格式如下圖所示。首先提示輸入學(xué)生人數(shù),然后逐個(gè)提示輸入學(xué)號(hào)和分?jǐn)?shù),輸入完畢之后打印出最終結(jié)果,結(jié)果輸出按照表格的形式給出,三列分別為學(xué)號(hào)、分?jǐn)?shù)、排名。設(shè)計(jì)輸入的學(xué)生個(gè)數(shù)上限是100人。分?jǐn)?shù)從0—100分。學(xué)號(hào)可以輸入任意長度的15位數(shù)字,存儲(chǔ)為字符串格式,每個(gè)學(xué)生固定長度。分?jǐn)?shù)經(jīng)過轉(zhuǎn)換后存儲(chǔ)為數(shù)字,每人占用一個(gè)BYTE。名次亦存儲(chǔ)為數(shù)字,每人占用一個(gè)BYTE。下圖演示了錯(cuò)誤輸入時(shí)的處理,根據(jù)錯(cuò)誤類型打印出提示,并允許進(jìn)行重新輸入,而不用退出程序。本程序設(shè)計(jì)的主要特點(diǎn)如下:1、在程序設(shè)計(jì)思路上,采用了多子程序模塊化設(shè)計(jì),充分利用了宏和DOS功能調(diào)用等高級(jí)匯編技巧。2、在數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)上,采用數(shù)組的方式進(jìn)行存儲(chǔ),可直接又下標(biāo)(即學(xué)生的班內(nèi)序號(hào))進(jìn)行直接尋址,效率較高。3、在進(jìn)行排名比較時(shí),利用了指針技術(shù),即對(duì)分?jǐn)?shù)的偏移量進(jìn)行排序,而不移動(dòng)實(shí)際的分?jǐn)?shù)。模擬了高級(jí)語言中的數(shù)組和指針的技術(shù),結(jié)構(gòu)和思路完整規(guī)范。排序技術(shù)選用了冒泡排序,獲得一定的性能提升。4、對(duì)用戶輸入進(jìn)行嚴(yán)格的檢查,對(duì)各種可能出現(xiàn)的錯(cuò)誤進(jìn)行了提示和處理。使得程序具有很好的完備性和健壯性。五、實(shí)驗(yàn)總結(jié)此次實(shí)驗(yàn)是在前幾次實(shí)驗(yàn)的基礎(chǔ)上完成的,綜合了子程序設(shè)計(jì)、DOS調(diào)用、宏匯編等等編程方法和技術(shù)。具有很強(qiáng)的綜合性。程序的設(shè)計(jì)按照小型程序的要求,充分考慮了健壯性和運(yùn)行效率等因素,精心設(shè)計(jì)了數(shù)據(jù)結(jié)構(gòu)和算法。是可用于實(shí)際工程的代碼雛形。由于完備性、健壯性、效率、界面等方方面面都考慮到,故代碼長度達(dá)到了461行。這也使得調(diào)試花費(fèi)了大量時(shí)間。綜合實(shí)驗(yàn)對(duì)我的匯編編程能力的提升大有幫助。從四次實(shí)驗(yàn)的整個(gè)過程來看,我的進(jìn)步是十分明顯的。這也是令我十分欣喜的事情。實(shí)驗(yàn)五中斷程序設(shè)計(jì)一、實(shí)驗(yàn)?zāi)康某醪秸莆罩袛喑绦虻脑O(shè)計(jì)方法;初步掌握修改DOS系統(tǒng)中斷,以適應(yīng)實(shí)際使用的方法。二、實(shí)驗(yàn)內(nèi)容編寫一個(gè)32位二進(jìn)制數(shù)除以16位二進(jìn)制數(shù)的除法程序。觀察當(dāng)除數(shù)為0,或超過相應(yīng)寄存器范圍時(shí),程序執(zhí)行的結(jié)果。修改零號(hào)中斷服務(wù)程序,使它具有以下功能:判斷除數(shù)是否為0,當(dāng)除數(shù)為0時(shí),顯示相應(yīng)的結(jié)果;當(dāng)除數(shù)不為0時(shí),采用適當(dāng)?shù)姆椒ㄍ瓿缮坛^16位的二進(jìn)制數(shù)的除法運(yùn)算。注意必須保護(hù)原有中斷服務(wù)程序的入口地址,并在程序完畢前加以恢復(fù)。選作題:用二進(jìn)制將結(jié)果在屏幕上顯示。從鍵盤輸入二進(jìn)制數(shù)。三、預(yù)習(xí)思考如何保護(hù)原有中斷向量表中的中斷服務(wù)程序的入口地址?答:先讀取中斷向量表中0號(hào)中斷的地址,壓入堆棧,程序結(jié)束時(shí)彈出堆棧,寫回中斷向量表即可。如何將你的中斷服務(wù)程序入口地址置入中斷向量表?答:有兩種基本方法:一是直接寫入法,使用指令將中斷服務(wù)程序入口地址的IP寫入n×4的RAM位置,中斷服務(wù)程序入口的CS寫入n×4+2的位置;二是DOS功能調(diào)用,25H用來寫中斷向量表,35H讀中斷向量表。四、實(shí)驗(yàn)過程(一)流程圖(二)源代碼DATASEGMENTXXDD?;被除數(shù)32bitYYDW?;除數(shù)16bitTMPDW?FLAGDB0;是否調(diào)用了中斷處理程序的標(biāo)志位,即是否溢出 ;一些提示信息ERR0DB'ERROR!DividebyZERO!','$'TIP1DB'Quotient:','$'TIP2DB'Remainder:','$'TIP3DB'Inputhigh16-bitofdividend:','$'TIP4DB'Inputlow16-bitofdividend:','$'TIP5DB'Input16-bitdivisor:','$'CRDB0DH,0AH,'$';回車換行ONEDB'1','$'ZERDB'0','$'TABDB09H,'$'BUFFDB17;輸入緩沖區(qū),可容納包括回車在內(nèi)的17個(gè)字符 PRESDB0 CHARDB17DUP(0)DATAENDS;;定義堆棧STACKSEGMENTSTACK'STACK'DB100DUP(0)STACKENDS;CODESEGMENTASSUMEDS:DATA,CS:CODE,ES:CODE,SS:STACK;打印字符串的宏P(guān)RINTMACROPARA PUSHAX PUSHDX MOVAH,09H MOVDX,OFFSETPARA INT21H POPDX POPAXENDM;;主程序入口MAIN:MOVAX,DATAMOVDS,AXMOVAX,0MOVES,AX ;保存原中斷向量表MOVAX,WORDPTRES:[0000H]PUSHAXMOVAX,WORDPTRES:[0002H]PUSHAX;寫入新的中斷處理子程序地址MOVWORDPTRES:[0000H],OFFSETINT0MOVWORDPTRES:[0002H],SEGINT0CALLINPUT;獲取輸入MOVDX,WORDPTRXX;移入被除數(shù)高16位MOVAX,WORDPTRXX+2;移入被除數(shù)低16位MOVBX,YY;移入除數(shù)DIVBX;進(jìn)行32位除法運(yùn)算CMPFLAG,0;查看是否調(diào)用了中斷處理程序,即可判斷是否溢出JNEISOF;溢出跳轉(zhuǎn),到擴(kuò)充除法的結(jié)果輸出 ;否則直接輸出沒有溢出的正常除法結(jié)果PRINTTIP1MOVBX,AXCALLDISP2PRINTCRPRINTTIP2MOVBX,DXCALLDISP2JMPEOP ;有溢出的時(shí)候需要輸出32位商和16位余數(shù)ISOF:PRINTTIP1MOVBX,DXCALLDISP2MOVBX,AXCALLDISP2PRINTCRPRINTTIP2MOVBX,CXCALLDISP2EOP:POPAX;程序結(jié)束出口 ;恢復(fù)中斷向量表MOVWORDPTRES:[0002H],AXPOPAXMOVWORDPTRES:[0000H],AXMOVAX,4C00H;返回DOSINT21H;;新的0號(hào)中斷子程序INT0: POPSIADDSI,2;修改IP的值,指向DIV后的指令PUSHSICMPBX,0;判斷除數(shù)是否為0JEDIV0;為零則提示除數(shù)為0,然后返回DOSMOVFLAG,1;置標(biāo)志為除數(shù)不為零溢出 ;進(jìn)行擴(kuò)展除法運(yùn)算,分別用除數(shù)除以被除數(shù)高16位和低16位 ;輸出參數(shù)為DX:商高16位,AX:商低16位,CX:16位余數(shù)PUSHAXMOVAX,DXXORDX,DX;除前將DX清零DIVBX;高16位除

溫馨提示

  • 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)論