微機原理課件第四章宏匯編語言程序設計.ppt_第1頁
微機原理課件第四章宏匯編語言程序設計.ppt_第2頁
微機原理課件第四章宏匯編語言程序設計.ppt_第3頁
微機原理課件第四章宏匯編語言程序設計.ppt_第4頁
微機原理課件第四章宏匯編語言程序設計.ppt_第5頁
已閱讀5頁,還剩157頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第四章 宏匯編語言程序設計,匯編語言是利用指令的助記符、符號地址、標號來編寫的語言,它是機器語言的符號表示,是較低級的語言。,利用匯編語言編寫的程序稱為匯編語言源程序,上一章講到的指令系統(tǒng)中的每條指令都是構成源程序的基本語句。但機器不能識別源程序,要通過匯編程序翻譯成二進制代碼的浮動目標程序,然后由連接程序將目標文件與庫文件相連,最后得到可執(zhí)行的程序,才可在機器上直接運行。,基本概念:,匯編語言:用指令的助記符、符號地址、標號 等來編寫的語言。,匯編語言源程序:用匯編語言編寫的程序(*.asm),匯編程序:將匯編語言源程序翻譯成目標目標程序(代碼),這個翻譯過程稱為匯編,翻譯軟件就叫匯編程序。,一個完整的匯編語言的語句由下列幾部分組成:標號和變量、指令助記符、界符、常數(shù)和注釋,所有這些都稱為標記。,4-1 匯編語言的標記,一、標號和變量 表示指令性語句的符號地址或表示一個數(shù)據(jù)單元的符號地址。,對標號或變量要注意以下幾點: 標號或變量可以由數(shù)字、字母、下劃線或其它特殊字符組成。,標號或變量不能以數(shù)字開頭,但可出現(xiàn)在標號的其它地方。,標號或變量最大長度不能超過31個字符。,二、指令助記符 指出指令的性質(功能),三、界符 作為一個程序中或一條指令中兩個部分的分隔符號用。,四、常數(shù) 二進制:01001101B 十進制:2000或2000D 八進制:1700Q 十六進制:1200H,0FFH 串常數(shù):ABCD ,五、注釋 用;開頭后面的內容可隨意,用來增加程序可 讀性的。,表達式由運算對象和運算符組成,在匯編時由匯編程序對它進行運算,運算結果作為一個語句中的操作數(shù)來使用。,4-2 匯編語言中的表達式,運算對象:常數(shù)、標號或變量,一、算術運算符 有:+、-、*、/、MOD(模,即取除法運算結果之余數(shù))、SHL(左移,左移1位相當于乘2)、SHR(右移,右移1位相當于除以2)。,二、邏輯運算符 有:AND(與)、OR(或)、NOT(非)、XOR(異或),邏輯運算符是按位運算的,只能對常數(shù)進行運算,得到結果也是常數(shù)。,例4-5 IN AL,PORT AND DX,PORT AND 0FEH OUT DX,AX 前一個AND是指令助記符,而后一個AND是 邏輯運算符。,三、關系運算符 有:EQ(相等)、NE(不等)、LT (小于)、GT(大于),LE(小于或等于)、 GE(大于或等于)。,四、數(shù)值返回運算符 數(shù)值返回運算符也經(jīng)常稱作分析運算符 有:OFFSET、SEG、TYPE、LENGTH、 SIZE 5種,它們加在變量或標號前,返回運 算對象的某個參數(shù)值,例如偏移地址值、段 地址值、類型屬性、變量包含的單元數(shù)等。,1.OFFSET 格式:OFFSET 變量或標號 OFFSET 返回標號或變量的偏移地址值。,2.SEG 格式:SEG 變量或標號 SEG 返回標號或變量的段地址值。,3.TYPE 格式:TYPE 變量或標號,TYPE加在變量前,返回變量的類型屬性。,TYPE加在標號前,返回標號的距離屬性。,例4-9 A1 DB 1,2,3 ;變量 A2 DW 1234H ;變量 A3 DD 6 DUP(?);變量 L1: MOV AH,TYPE A1;標號 MOV BH,TYPE A2 MOV CH,TYPE A3 MOV DH,TYPE L1 MOV DX,TYPE L1,4.LENGTH 格式:LENGTH 變量,5.SIZE 格式:SIZE 變量,1.段操作符 格式: 段前綴:變量或地址表達式 段前綴有段寄存器CS、DS,ES,SS后跟冒號 :,用來表示某個變量或地址被修改到哪個 段寄存器提供的段地址。,2.PTR 格式: 類型/距離:PTR 變量或標號,3.THIS 格式:變量或標號 EQU THIS 類型或距離,4.SHORT 格式:SHORT 標號 SHORT用來說明轉移類指令中轉向地址的 屬性,指出轉向的目標地址與本指令之間的 距離在-128+127之間,即限制在短轉移范 圍內。,5.HIGH和LOW 格式:HIGH/LOW 變量或標號 HIGH和LOW稱為字節(jié)分離運算符,對一個 數(shù)或地址表達式,HIGH從中分離出高位字節(jié) LOW從中分離出低位字節(jié)。,六、其它運算符 有: 、()、.、MASK和WIDTH等,七、優(yōu)先級 表達式是常數(shù)、變量、標號和運算符的 組合,在計算表達式時,應按優(yōu)先級高低進 行計算,同時遵循同級運算從左到右的原則 計算。,4-3 偽指令語句,偽指令語句沒有對應的機器代碼,并不 像指令語句那樣由CPU來執(zhí)行,它是MASM 匯編程序對源程序匯編期間進行處理的。主 要完成變量定義、存儲器分配、指示程序開 始和結束、段定義、段分配等。偽指令有以 下幾種類型:,一、數(shù)據(jù)定義語句 格式1:變量名 助記符 操作數(shù),操作數(shù) 格式2:變量名 助記符 n DUP(操作數(shù),操作數(shù)),例4-21 操作數(shù)是常數(shù)或表達式 DA1 DB 10H,20H DA2 DW 1122H,34H DA3 DD 5*10H,1234H,例4-22 操作數(shù)是字符串 FIRST DB HELLO SECOND DW OK THIRD DB OK,注意:用DW定義字符 串時,只允許包含兩個 字符,多于兩個字符時, 只能用DB來定義。,例4-23 操作數(shù)用?定義不確定值的變量,用 作保留存儲空間,以便存放運算結果。 M1 DB ?,? M2 DW 1234H,?,例4-24 操作數(shù)用DUP來定義重復變量 ONE DB 5 DUP(0) TWO DW 10 DUP(?) THREE DB 3 DUP(1,2),FOUR DB 2 DUP(1,3 DUP(10H);DUP 嵌套,操作數(shù)是變量或標號: 用偽指令DW和DD可以將變量或標號的 偏移地址存入存儲器中,當用DD來定義時, 原變量或標號的偏移地址存入低位字中,原 變量或標號的段地址存入高位字中。,例4-25 PP DB 1,2,3;變量PP AD1:MOV AX,BX;標號AD1、AD2 AD2:MOV BX,CX,假設變量的PP的偏移地址為1000H,標號AD1 的偏移地址為2000H,標號AD2的偏移地址為 3000H,段地址為4000H。,二、表達式賦值語句 表達式賦值語句有兩種,賦值語句EQU和等號語句=,它們均不占用內存。,1.賦值語句EQU 格式:符號名 EQU 表達式 功能:用來給變量、標號、常數(shù)、指令、表達式等定義一個符號名,程序中用到EQU左邊的變量、標號時可用右邊的常數(shù)值或表達式代替,但一經(jīng)定義在同一個程序模塊中就不能重新定義。,2.等號語句= 等號語句=與EQU語句具有相同功能,區(qū)別在于EQU中左邊的標號不允許重新定義,而用=定義的語句允許重新定義。,三、段定義語句,前面講過,存儲器的物理地址由段地址和偏移地址組合而成,任何一個邏輯段,無論是代碼段,數(shù)據(jù)段,堆棧段,附加段,都必須進行段定義,以便連接程序把不同段和模塊連成一個可執(zhí)行程序。此外還必須明確段和段寄存器之間的關系,這可使用段分配語句來完成。,1.段定義語句 SEGMENTENDS,功能:將一個邏輯段定義成一個整體。,段名 SEGMENT 定位類型 組合類型 分類名 段名 ENDS,2.段分配語句ASSUME 在8086系統(tǒng)中存儲器采用分段結構,各段容量64K字節(jié),用戶可以設置多個邏輯段,但只允許4個邏輯段同時有效,段分配語句用來完成將邏輯段分別定義成代碼段、堆棧段、數(shù)據(jù)段和附加段。,ASSUME為偽指令助記符,放在代碼段的開始,不可省略。提供給匯編程序,說明當前代碼段,數(shù)據(jù)段,堆棧段和附加段4個如何定義。,2.段分配語句ASSUME,例4-29通過表轉換指令來實現(xiàn)將57的7段顯示段碼送到BX寄存器中。,四、過程定義語句,過程也稱子程序。在主程序中,經(jīng)常要用到一些程序段,程序段的功能和結構相同,僅有一些變量賦值不同,此時可以將這些程序段獨立編寫用過程定義語句進行定義,然后在主程序中對它進行過程調用。這樣既節(jié)省了內存空間,也便于進行模塊化程序設計,使編程清晰,使用靈活。,格式: 過程名 PROC 屬性 ;過程內容 RET N 過程名 ENDP,四、過程定義語句,在匯編語言源程序中,使用CALL指令調用過程,過程調用允許嵌套和遞歸調用。嵌套調用指在一個被調用的過程中,又調用另一個過程;遞歸調用是指在一個被調用的過程中,又調用了本身的過程。嵌套與遞歸的深度由堆棧段的容量決定因為過程調用時必須將當前的地址壓入堆棧保護起來,使調用返回時能返回到正確的返回地址。另外在子程序入口也有許多參數(shù)要保護,以免影響主程序原來的運行狀態(tài)。,例4-30 近過程定義及調用格式 CCODE SEGMENT ABC PROC NEAR RET ABC ENDP CALL ABC CCODE ENDS,例4-31 遠過程定義及調用格式 C1CODE SEGMENT KKK PROC FAR RET KKK ENDP C1CODE ENDS C2CODE SEGMENT CALL KKK C2CODE ENDS,例4-32 過程嵌套調用格式 CCODE SEGMENT KKK PROC NEAR CALL LLL RET KKK ENDP LLL PROC NEAR RET LLL ENDP CCODE ENDS,五、程序開始和結束語句,1.NAME 格式:NAME 程序名 功能:為源程序目標模塊賦名字。 2.TITLE 格式:TITLE 文本名 功能:將文本名賦給源程序目標模塊作名字。,3.ORG 格式:ORG 表達式,4.END 格式:END 標號名 功能:標記匯編源程序結束,六、結構定義語句,七、外部偽指令及對準偽指令,1.外部偽指令 程序中包含多個模塊時,有些程序或數(shù)據(jù)在各個模塊間要相互共享,可用外部偽指令PUBLIC和EXTRN來實現(xiàn)此功能。其中PUBLIC用來定義共享模塊,EXTRN用來引用共享模塊。,例4-42 DATA SEGMENT A1 DB 10H,20H A2 DW 4 DUP(0) A3 EQU 1000H DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA TMF LABEL FAR PUBLIC A2,A3,TMF CODE ENDS,PDATA SEGMENT P1 DB 0AH,0BH P2 DB 2 DUP(?) PDATA ENDS PCODE SEGMENT EXTRN A2:WORD,A3:ABS,TMF:FAR MAIN: MOV AX,PDATA MOV BX,OFFSET A2 MOV CX,A3 JMP TMF PCODE ENDS END MAIN,2.對準偽指令 格式:EVEN,3.LABLE(相當于THIS偽指令),LABLE偽指令給已定義的變量或標號取一個名字,并可重新定義它的類型屬性,使同一變量或標號在不同地方被引用時,可采用不同的名字,具有不同的類型屬性,這樣提高了程序的靈活性。,(1)LABLE與變量連用 LABLE與變量連用時,給下一個變量取一個別名,類型屬性可修改成BYTE、WORD等。,(2)LABLE與標號連用 LABLE與標號連用時,給下一個語句定 義的標號取一個別名,并可改變距離屬性為 FAR或NEAR。,4-4 DOS系統(tǒng)功能調用和BIOS中斷調用,一、DOS系統(tǒng)功能調用,DOS系統(tǒng)功能調用分別實現(xiàn)設備管理、文件讀/寫、文件管理和目錄管理等功能。每個子程序對應一個功能號,所有的系統(tǒng)功能調用的格式是一致的,按下面4步進行:,(1)系統(tǒng)功能號送到AH寄存器;,(2)入口參數(shù)送到指定寄存器中;,(3)用INT 21H指令執(zhí)行功能調用;,(4)根據(jù)出口參數(shù)分析功能調用執(zhí)行情況。,1. DOS鍵盤功能調用,鍵盤提供了字符鍵、功能鍵和控制鍵。每個鍵都有對應的鍵值,即標準ASCII碼值,通過DOS功能調用可讀入鍵值到AL寄存器或存儲器中,表4-7列出DOS鍵盤功能調用的有關命令。,表4-7 DOS鍵盤功能調用,(1)鍵入單字符,1號功能調用:從鍵盤輸入字符并顯示, 調用命令為: MOV AH,1 INT 21H,例4-51 交互式程序中用戶按下數(shù)字鍵1,2,3,程序 轉入相應的服務子程序,若按下其它鍵就繼續(xù)等待。 KEY:MOV AH,1 ;讀入鍵值AL INT 21H CMP AL,1 ;鍵值為1 嗎? JE ONE CMP AL, 2 ;鍵值為2 嗎? JE TWO CMP AL,3 ;鍵值為3 嗎? JE THREE JMP KEY ;其它鍵則繼續(xù)等待按鍵 ONE: TWO: THREE:,8號功能調用:從鍵盤輸入字符但不回顯,命令為: MOV AH,8 INT 21H,6號功能調用:直接控制臺輸入/輸出,命令為: MOV DL,0FFH MOV AH,6 INT 21H,7號功能調用:直接控制臺輸入/輸出但無回顯,命令格式為: MOV AH,7 INT 21H,(2)輸入字符串,0AH功能調用:能從鍵盤接收字符串到內存的輸入緩沖區(qū)。,例4-52 開辟一個緩沖區(qū),從鍵盤輸入一個字符串,將輸入的字符數(shù)CL寄存器,并將指針指向字符串的第一個字符。,(3)檢驗鍵盤狀態(tài) 0BH功能調用:檢驗是否有鍵按下,若有鍵按下AL=0FFH,若沒有鍵按下,AL=0,無論檢測到是否有鍵按下,程序將繼續(xù)執(zhí)行下一條指令。,(4)清除鍵盤緩沖區(qū) 0CH功能調用:先清除鍵盤緩沖區(qū),然后執(zhí)行AL中指定的功能,AL中可以指定1, 6,7,8或0AH功能號,使程序在輸入字符前將以前鍵入的字符清掉。,2. DOS顯示功能調用 DOS顯示功能調用能夠顯示字符或字符串,這些功能都自動向前移動光標,表4-8給出了DOS顯示功能調用的有關命令。,(1)單字符顯示,2號功能調用:2號功能調用實現(xiàn)將字符送到屏幕顯示出來。它要求將要顯示字符的ASCII碼值送到DL寄存器中。,6號功能調用:是直接控制臺輸入/輸出調用,除前面談到的鍵盤輸入功能外,在DL不等于0FFH時,表示向屏幕輸出。它要求將要顯示字符的ASCII碼值送到DL寄存器中。,(2)字符串顯示 9號功能調用:顯示字符串,要求DS:DX指向串地址首址,并且字符串必須以$ 字符為結束符。若要求顯示字符串后光標自動回車換行,則在$字符前再加上0DH(回車),0AH(換行)字符。,4-5 程序設計方法,前面幾章已討論了指令系統(tǒng)和匯編語言設計基礎,而設計出一個好的程序不僅要能正常運行,完成要求的功能,還應該具有下列特點:,(1)程序結構模塊化,程序易讀,易調試及 維護。,(2)執(zhí)行速度快。,(3)占用內存空間小。,尤其是結構化設計,在程序復雜的情況下尤為重要。一般來說設計匯編語言源程序的基本步驟如下:,(1)分析問題,抽象出描述問題的數(shù)學模型,并確定實現(xiàn)數(shù)學模型的算法。,(2)繪制程序流程圖,通常先畫粗框圖,在結構模塊中再細畫框圖??驁D一般有起始框,執(zhí)行框,判斷框和終止框。,(3)分配存儲空間及工作單元。分配數(shù)據(jù)段,堆棧段,代碼段各在內存什么位置,各個寄存器主要起什么作用。,(4)按流程圖設計編寫程序。,(5)靜態(tài)檢查,上機調試。,(6)程序運行,結果分析。,在進行匯編語言源程序設計時,通常用到四種程序結構:順序結構;分支結構循環(huán)結構;子程序結構。下面分別加以說明。,一、順序結構,順序結構的程序一般是簡單程序,程序順序執(zhí)行,無分支,無循環(huán),也無轉移,圖中沒有判斷框。,例4-64 內存中TABLE開始存放09的平方值,通過人機對話,當任給定一個數(shù)X(09),查表得X的平方值,放在AL中。(見程序流程圖),.MODEL SMALL .386 .STACK 100H .DATA TABLE DB 0,1,4,9,16,25,36 DB 49,64,81 BUF DB Please input one number(09): DB 0DH,0AH,$ .CODE .STARTUP,MOV DX,OFFSET BUF;顯示字符串 MOV AH,9 INT 21H MOV AH,1 ;1號功能調用,鍵入數(shù)送 AL中 INT 21H MOV AH,0 ;查表得鍵入數(shù)的平方值 AND AL,0FH ADD BX,AX MOV AL,BX .EXIT 0 END,二、分支結構,1.分支結構 一般情況下,程序順序執(zhí)行,但經(jīng)常要求程序根據(jù)不同條件選擇不同的處理方法,這就需要用到分支結構。,例4-65 編程實現(xiàn)以下函數(shù):,核心代碼如下:,MOV AL,X CMP AL,0 JG ZHSHU SUB AL,5 JMP OUT ZHSHU:ADD AL,3 OUT: MOV Y,AL,2. 多分支,有的分支結構為多分支,可以利用多個條件轉移指令來實現(xiàn),依次測試條件是否滿足,若滿足轉入相應分支入口,若不滿足繼續(xù)向下測試,直到全部測試完。這種方法編程簡單、直觀,但運行速度慢,要依次檢查才能進入要求的入口。,例4-66 有8個加工子程序,入口地址分別為P1,P2,P8編程實現(xiàn)檢測鍵盤輸入命令,使系統(tǒng)分別轉向8個加工子程序。(鍵值為1轉向P1,鍵值為2轉向P2,等等。),MOV AH,1 INT 21H CMP AL,1 JE P1 CMP AL,2 JE P2 ,CMP AL,8 JE P8 JMP ST P1: P2: P3: P8: ST: HLT,3. 跳轉表實現(xiàn)多分支,利用跳轉表實現(xiàn)多分支,就克服了上面 的缺點,可以直接找到相應入口。利用這種 方法要在存儲器中先建立一個跳轉表,表中包括每個分支的入口地址,跳轉指令或關鍵 字,利用此表就可以實現(xiàn)分支結構。,(1)根據(jù)表中入口地址實現(xiàn)分支,跳轉表中存放了每個分支程序的入口地址,只要找到表地址,在將其內容取出,即可得到每個分支的入口地址。 表地址=跳轉表的首地址+偏移量,例4-67 將例4-66 中程序改成用跳轉表來實現(xiàn):,BASE DW P1,P2,P3,P4 DW P5,P6,P7,P8 ,(2)根據(jù)表中指令機器碼實現(xiàn)分支,跳轉表中存放的是轉移指令機器碼,查表后程序轉到相應的子程序。圖4-15給出了轉移指令跳轉表存放形式。,例4-68 將例4-66 程序用跳轉表存放轉移指令 機器碼實現(xiàn)分支。,MOV AH,1 INT 21H AND AL,0FH MOV AH,0 MOV BL,AL ;將鍵值保存到BL中 ADD AL,AL ADD AL,BL ;偏移量=鍵值3 MOV BX,OFFSET BASE ADD BX,AX JMP BX,跳轉表中存放關鍵字,及相應分支地址,圖4-16給出了關鍵字跳轉表的格式,圖4-17給出了關鍵字分支流程圖。,(3)根據(jù)表中關鍵字實現(xiàn)分支,例4-69 將例4-66用關鍵字跳轉表方式實現(xiàn)分支,BDATA SEGMENT BASE DB 31H ;關鍵字 DW P1 ;P1入口地址 DB 32H DW P2 DB 38H DW P8 BDATA ENDS,LOP: MOV AH,1 INT 21H CMP AL,0 JE LOP MOV BX,OFFSET BASE NEXT: CMP AL,BX JE DO ADD BX,3 ;加3調整指針 JMP NEXT DO: JMP WORD PTR BX+1 ,三、循環(huán)程序結構,1. 循環(huán)程序結構形式,循環(huán)程序有兩種結構形式:一種是“先執(zhí)行,后判斷”結構,另一種是“先判斷,后執(zhí)行”結構。圖4-18給出了兩種循環(huán)程序結構框圖。,無論哪種循環(huán)結構都包括以下四個部分:,(1)初始化:為循環(huán)作準備,設置循環(huán)計數(shù)值,設置變量 初值。,(2)循環(huán)體:循環(huán)部分的核心,包括循環(huán)的全部執(zhí)行指令。,(3)修改參數(shù):修改操作數(shù)地址,為下次循環(huán)作準備。,(4)循環(huán)控制:修改計數(shù)器值,判斷循環(huán)控制條件,決定是否跳出循環(huán)。,程序流程圖如下所示: (先執(zhí)行,后判斷結構),例4-70 將BX中的16進制數(shù)轉換為ASCII碼,存放到BUF開始的內存單元中去,并在屏幕顯示出數(shù)值。,MOV SI,OFFSET BUF MOV CH,4 NEXT: MOV CL,4 ROL BX,CL MOV AL,BL AND AL,0FH ADD AL,30H CMP AL,3AH JL STORE ADD AL,7 STORE: MOV SI,AL MOV AH,2 MOV DH,AL INT 21H INC SI DEC CH JNZ NEXT HLT,例4-71 AX寄存器中有一個16位二進制數(shù),編程統(tǒng)計其中1的個數(shù),結構放到CL寄存器中。,MOV CL,0 ;初始化 L1: AND AX,AX ;控制循環(huán) JZ STOP SAL AX,1 ;循環(huán)體 JNC L2 INC CL L2: JMP L1 STOP:HLT,此程序采用先判斷,后執(zhí)行的循環(huán)結構。,2 . 用邏輯尺的方法控制循環(huán),循環(huán)控制條件是循環(huán)程序設計的關鍵,必須結合對算法的分析來選擇控制條件。有時程序要求按不同次序處理兩種函數(shù)操作,可以采用邏輯尺的方法控制循環(huán)。,DATA SEGMENT LOGRUL EQU 0011010110000000B COUNT EQU 10 ;循環(huán)次數(shù) BUF DB 20 DUP(?);采集數(shù)據(jù) BLOCK DB 20 DUP(?);處理后數(shù)據(jù) DATA ENDS,MOV DX,LOGRUL;邏輯尺DX MOV CX,COUNT ;設循環(huán)次數(shù) MOV SI,OFFSET BUF MOV DI,OFFSET BLOCK NEXT: MOV AX,WORD PTR SI ROL DX,1 ;左移一位 JC FUN2 ;進位為1轉FUN2 FUN1: ADD AX,5 JMP NEXT1 FUN2: SUB AX,3 NEXT1:MOV WORD PTRDI,AX;送結果 INC SI ;修改地址指針 INC SI INC DI INC DI LOOP NEXT ,3. 多重循環(huán),(2)內循環(huán)可以嵌套在外循環(huán)中,也可幾個內循環(huán)并列在外循環(huán)中,但各層循環(huán)之間不能交叉,可以從內循環(huán)跳到外循環(huán),不可以從外循環(huán)中直接跳進內層循環(huán)。,有些循環(huán)結構比較復雜,需要用多重循環(huán)完成。多重 循環(huán)設計方法與單循環(huán)設計方法相同,但應注意:,(1)各重循環(huán)的初始控制條件及程序實現(xiàn)。,(3)防止出現(xiàn)死循環(huán),即不能讓循環(huán)回到初始條件,引起死循環(huán)。,例4-72 存儲器數(shù)據(jù)段從BUF開始存放一個字數(shù)組,數(shù) 組中第一字是存放該數(shù)組的長度N,編制一個程序使此數(shù) 組中的數(shù)據(jù)按照從小到大的次序排列。,采用冒泡排序算法。從第一個數(shù)據(jù)開始相鄰的數(shù)進行比 較,若次序不對,兩數(shù)交換位置。第一遍比較(N-1)次 后,最大的數(shù)已到了數(shù)組尾,第二遍僅需比較(N-2)次 就夠了,共比較(N-1)遍就完成了排序,這樣共有兩重 循環(huán)。圖4-20給出了程序流程圖。,開始,數(shù)I數(shù)I+1?,結束,初始化 數(shù)組起始地址BX 內循環(huán)次數(shù)N-1CX 外循環(huán)次數(shù)N-1DX,I=0,地址加2,兩數(shù)位置交換,內循環(huán)計數(shù)CX-1,外循環(huán)計數(shù)DX-1,CX=0?,DX=0?,A,A,Y,N,N,N,Y,Y,圖4-20 數(shù)組排序冒泡算法流程圖,ADATA SEGMENT BUF DW N,15,37,8600,0A768H DW 3412H,1256H,76H ADATA ENDS ASTACK SEGMENT STACK STACK;定義堆棧段 SA DB 100 DUP(?) TOP LABEL WORD ASTACK ENDS ACODE SEGMENT ASSUME CS:ACODE,DS:ADATA,SS:ASTACK MAIN PROC FAR START: MOV AX,ASTACK;將堆棧段段地址送SS MOV SS,AX MOV SP,OFFSET TOP;堆棧指針指向棧頂 PUSH DS ;為返回DOS作準備 SUB AX,AX PUSH AX,MOV AX,ADATA;將數(shù)據(jù)段段地址送DS MOV DS,AX MOV BX,0;指向BUF第一個字 MOV CX,BUFBX DEC CX ;設計數(shù)器CX,內循環(huán)次數(shù) L1: MOV DX,CX ;設計數(shù)器 DX,外循環(huán)次數(shù) L2: ADD BX,2 MOV AX,BUFBX;取BUFI CMP AX,BUFBX+2;若BUFI BUFI+2轉 JBE CONTI XCHG AX,BUFBX+2;否則兩數(shù)交換 MOV BUFBX,AX CONTI: LOOP L2 ;內循環(huán) MOV CX,DX;外循環(huán)次數(shù)CX MOV BX,0 ;地址返回第一個數(shù)據(jù) LOOP L1 ;外循環(huán),RET MAIN ENDP ACODE ENDS END START,四、子程序結構,1. 子程序使用,(1)功能描述:子程序的名稱、功能及性能 (2)子程序中用到的寄存器和存儲單元 (3)子程序的入口參數(shù),出口參數(shù) (4)子程序中調用其他子程序的名稱,例4-74 有一個子程序說明如下: ;名稱:BCD2BIN ;功能:將一個字節(jié)的的BCD碼轉換成二進制數(shù) ;所用寄存器:CX ;入口參數(shù):AL存放兩位BCD碼 ;出口參數(shù):AL存放二進制數(shù) ;調其他子程序:無,子程序形式如下: BCD2BIN PROC NEAR(FAR) PUSH CX MOV CH,AL AND CH,0FH;取BCD碼低位 MOV CL,4 ;設置移位次數(shù),SHR AL,CL;取BCD碼的高位 MOV CL,10 MUL CL ;高位10+低位 ADD AL,CH POP CX RET BCD2BIN ENDP,過程調用時,主程序使用CALL指令,調用中要處理 好三個問題:,(1)保護調用程序的返回地址,這一點由CALL指令本 身來完成,CPU執(zhí)行CALL指令時會自動將當前斷點的偏 移地址值IP入棧。若是段間調用,將段基址CS和偏移地 址值IP入棧。當子程序返回時,遇到子程序中RET指令, 則自動將當前棧頂值彈出到IP及CS寄存器中,因此要特,別注意堆棧的使用,防止彈出地址值錯誤。,(2)保護某些寄存器內容,子程序中要用到某些寄存器, 為了不破壞寄存器中原有的信息,要將需要保護的寄存器 內容入棧,一般安排在子程序開頭,用一組PUSH指令, 在子程序結尾處,相應安排一組POP指令,將所保護的寄 存器原來的內容恢復。注意堆棧工作方式為先進后出,所 以要注意PUSH和POP指令組的次序。,(3)主程序與子程序相互之間參數(shù)的傳遞,由于相互之 間可以傳遞參數(shù)才使子程序更靈活,更具有通用性,參數(shù) 傳遞的方法有3種: 1. 用寄存器傳遞參數(shù):適合于參數(shù)較少的場合。,2. 用存儲器傳遞參數(shù):適合參數(shù)較多的場合,需要事先 在存儲器中建立一個參數(shù)表。 3. 用堆棧傳遞參數(shù):適合參數(shù)較多的場合,尤其在子程 序嵌套與遞歸調用的情況下,比較不容易出錯。,下面舉例說明參數(shù)傳遞的方式。 例4-75 數(shù)據(jù)段定義兩個數(shù)組,編程實現(xiàn)數(shù)組段分別求和 (不計溢出) DATA SEGMENT ARY1 DW 100 DUP(?);定義數(shù)組1 SUM1 DW ? ARY2 DW 100 DUP(?);定義數(shù)組2 SUM2 DW ? DATA ENDS,STACK SEGMENT STACK SA DW 50 DUP(?) TOP EQU LENGTH SA STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK MAIN PROC FAR START: MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV SP,TOP LEA SI,ARY1;數(shù)組1首地址,入口參數(shù) MOV CX,LEGHTH ARY1;數(shù)組1長度, ;入口參數(shù) CALL SUM ;調用求和子程序,LEA SI,ARY2;數(shù)組2首地址,入口參數(shù) MOV CX,LENGTH ARY2;數(shù)組2長度, ;入口參數(shù) CALL SUM ;調用求和子程序 RET MAIN ENDP SUM PROC NEAR ;SUM子程序 XOR AX,AX ;AX清0 L1: ADD AX,WORD PTRSI ;加數(shù)組元素 INC SI INC SI LOOP L1 MOV WORD PTRSI,AX;數(shù)組和保存 MOV AH,4CH INT 21H RET ;子程序返回 SUM ENDP,CODE ENDS END START 本例是通過存儲器來傳遞參數(shù)的,需要傳遞的數(shù)組的數(shù) 保留在存儲器中,調用前只需將數(shù)組偏移地址放入SI寄存 器,在過程中通過寄存器間接尋址就可取得存儲器中的操 作數(shù),運算結果直接由過程寫回存儲器中,回送給調用程序。,例4-76 通過堆棧傳遞參數(shù),實現(xiàn)十進制數(shù)數(shù)組求和, 要求主程序和子程序不在同一代碼段中,要進行段間調用。 源程序如下: MDATA SEGMENT ARY1 DB 20 DUP(?);定義數(shù)組1 SUM1 DW ?,ARY2 DB 100 DUP(?) ;定義數(shù)組2 SUM2 DW ? MDATA ENDS MSTACK SEGMENT STACK SB DW 100 DUP(?) TOP LABEL WORD MSTACK ENDS MCODE SEGMENT ;主程序段 ASSUME CS:MCODE,DS:MDATA,SS:MSTACK MAIN PROC FAR START: MOV AX,MSTACK MOV SS,AX MOV SP,OFFSET TOP;SP指向棧頂 PUSH DS ;為返回DOS作準備 MOV AX,0 PUSH AX MOV AX,MDATA,MOV DS,AX MOV AX,OFFSET ARY1 ;PADD過程 ;入口參數(shù)進棧 PUSH AX MOV AX,SIZE ARY1 PUSH AX CALL FAR PTR PADD MOV AX,OFFSET ARY2 PUSH AX MOV AX,SIZE ARY2 PUSH AX CALL FAR PTR PADD RET MAIN ENDP MCODE ENDS PCODE SEGMENT ;過程段,ASSUME CS:PCODE,DS:MDATA,SS:MSTACK PADD PROC FAR ;PADD子程序 PUSH BX ;寄存器保護 PUSH CX PUSH BP MOV BP,SP PUSHF ;標志寄存器入棧 MOV CX,BP+10;數(shù)組長度CX(?) MOV BX,BP+12;數(shù)組首地址BX MOV AX,0 NEXT: ADD AL,BX ;數(shù)組元素相加 DAA MOV DL,AL MOV AL,0 ADC AL,AH DAA MOV AH,AL,MOV AL,DL INC BX LOOP NEXT MOV BX,AX ;保存數(shù)組元素之和 POPF POP BP POP CX POP BX RET 4 ;返回作廢參數(shù) PADD ENDP PCODE ENDS END START,這是一個用堆棧傳遞參數(shù),完成段間過程調用的實例, 這里要注意幾點:,(1)使用堆棧傳遞參數(shù),調用前要給過程傳遞兩個參數(shù), 主程序中將數(shù)組的偏移地址值及數(shù)組長度壓入堆棧,然后 調用過程,過程完成數(shù)組求和運算。 (2)程序設計要求段間過程調用,因此進入過程時要重新 定義代碼段,使之指向當前有效代碼段PCODE,在過程運 行中可直接調用堆棧中參數(shù),完成累加運算,并將結果送 到指定的存儲單元。 (3)過程返回時用返回指令RET 4,要將堆棧中由CALL 指令之前傳遞過來的4個字節(jié)作廢,然后才能返回主程序, 以保證下面過程調用時參數(shù)傳遞正確。 (4)在整個程序運行中,堆棧中數(shù)據(jù)變化見黑板。,2. 子程序嵌套與遞歸調用,子程序本身又可調用其他子程序,稱為子程序嵌套,嵌 套的層數(shù)不限,只要堆??臻g足夠就可以。但要注意寄存 器的保護和恢復,避免各層子程序之間寄存器使用沖突, 造成程序出錯。圖5-12給出了子程序嵌套示意圖。,子程序調用子程序本身,稱為子程序遞歸調用。 下面舉例說明程序嵌套與遞歸調用:,例4-X3 已知兩個無符號數(shù)125和368,求它們的和并將 和轉換成十六進制數(shù)在屏幕上顯示。,DATA SEGMENT P DW 125,368 SUM DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA MAIN PROC FAR START: PUSH DS MOV AX,0 PUSH AX,MOV AX,DATA MOV DS,AX MOV SI,OFFSET P CALL PADD RET MAIN ENDP PADD PROC NEAR ;兩數(shù)相加子程序 PUSH AX PUSH BX PUSH CX PUSH DX MOV AX,SI ADD AX,SI+2 MOV SUM,AX CALL DISP ;調用顯示子程序 POP DX,POP CX POP BX POP AX RET PADD ENDP DISP PROC NEAR ;顯示子程序 MOV BX,SUM MOV CH,4 L1: MOV CL,4 ROL BX,CL MOV AL,BL AND AL,0FH ADD AL,30H ;變成ASCII碼 CMP AL,3AH JL L2 ADD AL,07H L2: MOV DL,AL,MOV AH,2 INT 21H DEC CH JNZ L1 RET DISP ENDP CODE ENDS END START 此程序中有兩個子程序,其中兩數(shù)相加子程序中又調用 了顯示子程序,實現(xiàn)子程序嵌套。下面看一個子程序遞歸 調用的例子。,例4-77 要求計算N!(N0),這就是一個遞歸調用的計算方法, N!=N(N-1)(N-2)1 N!=1,N=0 N!=N(N-1)!,N0 由上面公式知道求N!即為計算N(N-1)!,而 (N-1)!要調用N!子程序,只要將調用參數(shù)修改即可。 可以通過堆棧將調用參數(shù)、寄存器內容等保護起來,每 調用一次將(N-1)有關信息入棧,直到N=0為止,然后 開始返回,返回時將N乘以(N-1)!,直到N為設置值 為止。,N!子程序說明: ;名稱:FACT ;功能:階乘子程序 ;入口參數(shù):AL=N ;出口參數(shù):DX=N!,ADATA SEGMENT D1 DB 4 ;N=4 D2 DW 2 DUP(?) ;存放運算結果 ADATA ENDS ASTACK SEGMENT PARA STACK STACK SA DW 100 DUP(?) TOP LABEL WORD ASTACK ENDS,ACODE SEGMENT ASSUME CS:ACODE,DS:ADATA,SS:ASTACK MAIN PROC FAR START: MOV AX,ASTACK MOV SS,AX MOV SP,OFFSET TOP;SP指向棧頂 PUSH DS MOV AX,0 PUSH AX MOV AX,ADATA MOV DS,AX MOV DX,0 MOV AH,0 MOV BX,OFFSET D1 MOV AL,BX ;AL=N CALL FACT MOV BX+1,DX,RET MAIN ENDP FACT PROC NEAR;N!子程序 CMP AL,0 JNZ CHN MOV DL,1 ;若N=0,則N!=1 RET CHN: PUSH AX ;N入棧 DEC AL ;N-1 CALL FACT ;遞歸調用FACT子程序 POP AX ;N彈出 MUL DL ;N(N-1)! MOV DX,AX ;送結果到DX RET FACT ENDP ACODE ENDS END START,五、綜合舉例,4-6 宏匯編和條件匯編,一、宏匯編,在匯編語言程序設計中,有的程序段要多次使用,除了 以前談到的過程調用的方法外,還可以用宏匯編的方法實 現(xiàn),尤其在子程序段本身較短,而傳遞的參數(shù)較多的情況 下,使用宏匯編更加有效。宏是源程序中一段獨立的程序 段,首先對它進行定義,然后就可以用宏指令語句多次調 用它了。,1. 宏定義 指令使用前必須先進行宏定義,宏定義格式為:,宏指令名 MACRO 形式參數(shù),形式參數(shù), 宏體 ENDM 宏指令名:宏定義的名字,不可缺省,宏調用時要使用它, 第一個符號必須是字母,其后可以上字母或數(shù)字 MACROENDM:宏定義偽指令助記符,不可缺省。它 們成對出現(xiàn),表示宏定義的開始和結束,ENDM 前不帶宏指令名。 宏體:一段有獨立功能的程序代碼段 形式參數(shù):又稱啞元,各個啞元之間用逗號隔開,可以缺 省。,2. 宏調用,經(jīng)宏定義后的宏指令可以在源程序中調用,宏調用格式 為: 宏指令名 實參,實參 宏調用只需有宏指令名,若宏定義中有形參,那么宏調 用時必須帶有實際參數(shù)來替代形參,實際參數(shù)的個數(shù)、順序 類型與形參一一對應,各個實參之間用逗號隔開。原則上實 參的個數(shù)與形參的個數(shù)相等,但匯編程序不要求它們必須相 等,若實參個數(shù)大于形參個數(shù),則多余的實參不予考慮,若 實參個數(shù)小于形參個數(shù),則多余的形參作空處理。,3. 宏展開 匯編程序在對源程序匯編時,對每個宏調用作宏展開, 即用宏定義中的宏體取代宏指令名,并用實參一一對應代 替形參,每條插入的宏體指令前帶上加號+。下面舉例說 明宏定義、宏調用及宏展開。,例4-83 不帶參數(shù)的宏定義,用宏指令來實現(xiàn)將AL中內 容右移4位。 宏定義: SHIFT MACRO MOV CL,4 SAR AL,CL ENDM,宏調用: SHIFT 宏展開: +MOV CL,4 +SAR AL,CL,4. 宏調用中參數(shù)傳遞 宏定義中的參數(shù)可以有多個,實參可以是數(shù)字,寄存 器或操作碼。下面分別舉例說明:,例4-84 宏定義帶一個參數(shù),用宏指令實現(xiàn)將AL中內容 右移任意次(256)。 宏定義: SHIFT MACRO N MOV CL,N,SAR AL,CL ENDM 宏調用1: SHIFT 4 宏調用2: SHIFT 7 宏展開1: +MOV CL,4 +SAR AL,CL 宏展開1: +MOV CL,7 +SAR AL,CL,例4-86 宏定義帶3個參數(shù),參數(shù)可為操作碼,用宏指令 實現(xiàn)對寄存器的內容左移或右移任意次。 宏定義:,SHIFT MACRO N,M,P MOV CL,N S&P M,CL ENDM 宏調用1: SHIFT 3,AX,HR 宏調用2: SHIFT 5,BH,AL 宏展開1: +MOV CL,3 +SHR AX,CL 宏展開2: +MOV CL,5 +SAL BH,CL,宏定義可用部分操作碼作參數(shù),但在宏定義體中必須用 &作分隔符,&是一個操作符,它在宏定義體中可作為啞 元的前綴,宏展開時,可以把 &前后兩個符號合并成一個 符號。,例4-87 宏定義: SJP MACRO X,Y,Z,W MOV AX,X C&W AX,Y J&Z NEXT ENDM 宏調用: SJP BX,SI,NZ,MP 宏展開: +MOV AX,BX +CMP AX,SI +JNZ NEXT,例4-88 宏定義: SLL MACRO P JMP WA&P ENDM 宏調用: SLL Q 宏展開: +JMP WAQ 如果沒有&連接,宏展開成+JMP WAP,匯編程序將 WAP看成一個標號,而不是將P看成一個啞元(形參), 這樣程序跳轉位置就出錯。,5. 宏定義嵌套 在宏定義中允許使用宏調用,但必須先定義后調用。,例4-89 宏定義: DBF MACRO P,Q ;宏定義1 MOV BX,P ADD AX,Q ENDM DBFS MACRO X1,X2,X3 ;宏定義2 PUSH AX PUSH BX DBF X1,X2;調用宏DBF MOV X3,AX POP BX POP AX ENDM,宏調用: DBFS 3AC0H,BX,3AC4H 宏展開: +PUSH AX +PUSH BX +DBF X1,X2;此語句不占內存 +MOV BX,3AC0H ;DBF宏定義展開 +ADD AX,BX +MOV 3AC4H,AX +POP BX +POP AX,下面看一個宏定義的形式參數(shù)是另一個宏指令名的例子,例4-90 宏定義: DEFM MACRO MACN,OPER MACN MACRO A,B,C PUSH AX MOV AX,A OPER AX,B MOV C,AX POP AX ENDM ENDM 例中MACN為內層宏定義名,又是外層宏定義的啞

溫馨提示

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

評論

0/150

提交評論