




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)第5章程序設(shè)計(jì)基本技術(shù)
順序程序設(shè)計(jì)分支程序設(shè)計(jì)循環(huán)程序設(shè)計(jì)子程序設(shè)計(jì)DOS功能子程序的調(diào)用2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)5.1概述我們知道,8086/8088CPU把存儲(chǔ)器分成若干段,而每一個(gè)段是可獨(dú)立尋址的邏輯單位。段是8086/8088系列微機(jī)的匯編語(yǔ)言程序的基礎(chǔ)。一個(gè)段就是若干指令和數(shù)據(jù)的集合。因此,我們?cè)诰幹茀R編語(yǔ)言源程序時(shí),首先要使用段定義偽指令來(lái)構(gòu)造一個(gè)由若干指令和數(shù)據(jù)組成的程序段。程序中邏輯段的數(shù)目由實(shí)際情況確定,通常根據(jù)程序中的用途來(lái)劃分段,如作堆棧使用的段、存放數(shù)據(jù)的段,存放程序的段等等。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)程序基本段結(jié)構(gòu)DATA SEGMENT …DATA ENDSSTACK1SEGMENTPARASTACK DW 20HDUP(0)STACK1ENDSCODE SEGMENTBEGIN : MOV AX,DATA MOV DS,AX;裝入數(shù)據(jù)段寄存器
… MOV AH,4CH INT 21H ;返回到DOS,返回碼為0CODE ENDS END BEGIN2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)在程序中,代碼段、數(shù)據(jù)段、附件段和堆棧段這4個(gè)段的順序是任意的。程序的功能是由代碼段來(lái)實(shí)現(xiàn)的。程序的代碼段的基本結(jié)構(gòu)有4類(lèi):順序程序、循環(huán)程序、分支程序和子程序。分支結(jié)構(gòu)子程序結(jié)構(gòu)…
順序結(jié)構(gòu)循環(huán)結(jié)構(gòu)2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)編制匯編語(yǔ)言源程序的步驟(1)分析問(wèn)題,確定算法(2)根據(jù)算法畫(huà)出程序流程圖(3)合理分配存儲(chǔ)空間和寄存器(4)根據(jù)流程圖編寫(xiě)程序(5)調(diào)試程序分析問(wèn)題,確定算法就是確定解決問(wèn)題的方法和步驟。編制流程圖是將解決問(wèn)題的方法、步驟用框圖的形式表示出來(lái)。如果要解決的問(wèn)題比較復(fù)雜,那么可以逐步細(xì)化,直到每一框圖都可以很容易編制程序?yàn)橹埂?023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)編制匯編語(yǔ)言源程序的步驟流程圖不僅便于編寫(xiě)程序,而且對(duì)程序邏輯上的正確性也比較容易查找和修改。流程圖主要由處理框、判定框、起止框、連接框和流向線5種框圖符號(hào)組成。處理框判定框起始框連接框流向線2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)(1)處理框:用于說(shuō)明一程序段(或一條指令)所完成的功能。這種框圖通常只有一個(gè)入口和一個(gè)出口。(2)判斷框:表示進(jìn)行程序的分支流向判斷,框內(nèi)記入判定條件。這種框圖通常有一個(gè)入口,兩個(gè)或兩個(gè)以上的出口。在每個(gè)出口上要注明分支流向的條件。(3)起止框:表示一個(gè)程序或一個(gè)程序模塊的開(kāi)始和結(jié)束。起始框內(nèi)通常用程序名、標(biāo)號(hào)或“開(kāi)始”字符來(lái)表示,它僅有一個(gè)出口。終止框內(nèi)通常用“結(jié)束”或“返回”字符表示,它僅有一個(gè)入口。(4)連接框:當(dāng)程序比較復(fù)雜時(shí),流程圖的連線較多,且常??v橫交錯(cuò),這時(shí)可以用連接框來(lái)表示兩根流向線的連接關(guān)系。所以連接框種常用字母或數(shù)字來(lái)表示。框內(nèi)有相同字母或數(shù)學(xué)就表示它們有連線關(guān)系。通常它只有一個(gè)入口或出口。(5)流向線:表示程序的流向。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)存儲(chǔ)器和寄存器的分配存儲(chǔ)器和寄存器時(shí)進(jìn)行匯編語(yǔ)言程序設(shè)計(jì)的舞臺(tái)。由于CPU中的寄存器數(shù)量有限而且有些操作要使用特定的寄存器,所以程序中要合理分配各寄存器的用途。程序運(yùn)行時(shí),其目標(biāo)代碼時(shí)存放在存儲(chǔ)器中的,而且操作數(shù)和程序執(zhí)行的結(jié)果也是存儲(chǔ)在存儲(chǔ)單元中的。因此,充分利用存儲(chǔ)空間,節(jié)約使用存儲(chǔ)空間時(shí)我們編制一個(gè)好的應(yīng)用程序應(yīng)該注意的問(wèn)題。為了編程方便,我們通常給這些存儲(chǔ)單元賦予一個(gè)名字(例如變量名)。存儲(chǔ)器中的存儲(chǔ)單元有3種類(lèi)型的用途:(1)常數(shù)單元:在這些存儲(chǔ)單元中存放的數(shù)據(jù)是整個(gè)程序的常量,且不因程序運(yùn)行的次數(shù)發(fā)生改變。在程序中不能修改它的值。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)存儲(chǔ)器和寄存器的分配(2)數(shù)據(jù)單元:數(shù)據(jù)單元是程序運(yùn)行中處理的對(duì)象,除非程序要求處理變動(dòng)這些單元的內(nèi)容,可以在程序中設(shè)置新值外,通常不要輕易修改這些單元的內(nèi)容,以便程序可以多次運(yùn)行。(3)工作單元:工作單元用于存放中間結(jié)果和最后結(jié)果,因此工作單元的內(nèi)容在程序運(yùn)行期間是經(jīng)常變化的。為了合理的利用存儲(chǔ)器單元,在程序設(shè)計(jì)時(shí)要合理分配常數(shù)單元,數(shù)據(jù)單元和工作單元,并充分利用寄存器來(lái)減少存放中間結(jié)果的工作單元,這樣不僅可以節(jié)約存儲(chǔ)單元,還能提高程序運(yùn)行速度。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)編制匯編語(yǔ)言源程序的步驟完成了存儲(chǔ)單元和寄存器的分配后,就要根據(jù)程序框圖進(jìn)行匯編語(yǔ)言源程序的編寫(xiě)。在進(jìn)行匯編語(yǔ)言源程序編寫(xiě)時(shí),首先按程序中各部分的用途分段,在使用指令語(yǔ)句和偽指令語(yǔ)句的時(shí)候要分清其功能,并且正確使用各種尋址方式。編寫(xiě)好源程序后,就要對(duì)源程序進(jìn)行調(diào)試。調(diào)試的步驟:(1)用MASM匯編.ASM文件(2)用LINK連接.OBJ文件(3)用DEBUG調(diào)試.EXE文件2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)5.2順序程序設(shè)計(jì)順序程序是最簡(jiǎn)單,也是最基本的一種程序結(jié)構(gòu)形式。順序程序結(jié)構(gòu)是從開(kāi)始到結(jié)尾都一直是順序執(zhí)行的,中途沒(méi)有任何分支。程序一直按指令序列在存儲(chǔ)器中的存放順序來(lái)執(zhí)行,由CS:IP提供的指令地址來(lái)控制。例5.2.1試編寫(xiě)一程序計(jì)算以下表達(dá)式:Z=(3X+Y-5)/2。設(shè)X、Y的值存放在字變量VARX、VARY中,結(jié)果放在VARZ中。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)順序程序設(shè)計(jì)算法分析:1、乘2和除2可以使用算術(shù)左移和右移實(shí)現(xiàn)2、3X可以分解成2X+X流程圖:開(kāi)始計(jì)算3X計(jì)算3X+Y計(jì)算3X+Y-5計(jì)算(3X+Y-5)/2存結(jié)果結(jié)束2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)TITLEEXAMPLE1DATASEGMENTVARXDW15VARYDW10VARZDW?DATAENDSSTACK1SEGMENTPARASTACKDW20HDUP(0)
STACK1ENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACK1COMPPROCFARPUSHDS;保護(hù)返回DOS地址
MOVAX,0PUSHAX2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)MOVAX,DATA;初始化DSMOVDS,AXMOVAX,VARX;AXX
SHLAX,1;AX2X
ADDAX,VARX;AX3X
ADDAX,VARY;AX3X+Y
SUBAX,5;AX3X+Y-5
SARAX,1;AX
(3X+Y-5)/2
MOVVARZ,AX;存結(jié)果RET;返回DOSCOMPENDPCODEENDSENDCOMP2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)順序程序設(shè)計(jì)當(dāng)一個(gè)用戶程序的可執(zhí)行文件裝入內(nèi)存后,無(wú)論用戶程序有幾個(gè)段,也不管這些段的排列順序如何,用戶程序的目的代碼一定是直接加載在程序段前綴(ProgramSegmentPrefix)PSP段的后面。PSP段給出了用戶可執(zhí)行文件的若干控制信息。其中PSP段的開(kāi)始處(第1、2字節(jié))有一條軟中斷指令“INT20H”。這條指令可以用來(lái)實(shí)現(xiàn)結(jié)束用戶程序,返回操作系統(tǒng)的功能。如果使用這種方式返回,則首先用戶要把用戶程序設(shè)置成一個(gè)過(guò)程,且類(lèi)型屬性為FAR,由于可執(zhí)行文件轉(zhuǎn)入內(nèi)存后DS和ES兩個(gè)段寄存器是指向PSP段的。所以將DS和偏移量00H分別壓入堆棧,用戶程序結(jié)束時(shí)用RET指令完成將原先壓入堆棧的PSP段基值和00H的偏移量分別送入CS和IP。執(zhí)行完RET指令后,就可以轉(zhuǎn)去執(zhí)行PSP段開(kāi)始處的“INT20H”軟中斷指令了。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)順序程序設(shè)計(jì)除了用上述方法來(lái)結(jié)束用戶程序,返回操作系統(tǒng)外,還可以使用另外一種方法:使用軟中斷指令“INT21H”。如果使用軟中斷指令“INT21H”來(lái)返回,則用戶程序可以不設(shè)置過(guò)程,只要在用戶程序結(jié)束時(shí),使用兩條指令即可。指令如下:
MOVAH,4CHINT21H如果使用此返回方式,程序代碼可以修改為:2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)TITLEEXAMPLE1DATASEGMENTVARXDW15VARYDW10VARZDW?DATAENDSSTACK1SEGMENTPARASTACKDW20HDUP(0)
STACK1ENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACK1STRAT:
MOVAX,DATAMOVDS,AX;初始化DS2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)MOVAX,VARX;AXX
SHLAX,1;AX2X
ADDAX,VARX;AX3X
ADDAX,VARY;AX3X+Y
SUBAX,5;AX3X+Y-5
SARAX,1;AX
(3X+Y-5)/2
MOVVARZ,AX;存結(jié)果MOVAH,4CHINT21H;返回DOSCODEENDSENDSTRAT例2、P822023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)順序程序設(shè)計(jì)換碼指令(XLAT)指令格式:
XLAT表首址指令功能:
((AL)+(BX)) AL使用這條指令時(shí),將表首址的偏移量送入BX中,而把要查表內(nèi)的單元的偏移量(0~255)送入AL中,兩者的和就是要查找元素的實(shí)際偏移量,執(zhí)行指令后,結(jié)果存放在AL中。該指令的執(zhí)行不影響標(biāo)志寄存器中的標(biāo)志位。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)5.3分支程序設(shè)計(jì)8086/8088指令系統(tǒng)提供了許多指令來(lái)完成對(duì)程序流向的控制和轉(zhuǎn)移,以便在程序運(yùn)行過(guò)程中改變指令的執(zhí)行順序。在程序運(yùn)行過(guò)程中,對(duì)指令執(zhí)行的控制是由CS和IP決定的。因此,程序流向的控制和轉(zhuǎn)移,主要是改變CS和IP。若轉(zhuǎn)移僅在同一個(gè)段內(nèi)進(jìn)行(段內(nèi)轉(zhuǎn)移),則只需要修改IP;若是在兩個(gè)段之間進(jìn)行(段間轉(zhuǎn)移),則CS和IP都要修改。一、轉(zhuǎn)移指令轉(zhuǎn)移指令分為無(wú)條件轉(zhuǎn)移指令和條件轉(zhuǎn)移指令兩種。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)分支程序設(shè)計(jì)無(wú)條件轉(zhuǎn)移指令JMP指令格式:JMP目標(biāo)JMP指令使程序無(wú)條件轉(zhuǎn)移到“目標(biāo)”處,“目標(biāo)”通常用標(biāo)號(hào)來(lái)表達(dá)。例如:
…JMPTARGET…TARGET:…….JMP指令的轉(zhuǎn)移可以分為段內(nèi)轉(zhuǎn)移和段間轉(zhuǎn)移。JMP指令的執(zhí)行不影響標(biāo)志寄存器。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)分支程序設(shè)計(jì)1、段內(nèi)轉(zhuǎn)移:段內(nèi)轉(zhuǎn)移時(shí),JMP指令和要轉(zhuǎn)移的目標(biāo)指令同屬一個(gè)段。因此,只需要修改IP,而CS保持不變。(1)段內(nèi)轉(zhuǎn)移直接尋址:JMP指令的操作數(shù)部分直接給出目標(biāo)單元。格式:JMP標(biāo)號(hào)(2)段內(nèi)轉(zhuǎn)移間接尋址:JMP指令轉(zhuǎn)移的目標(biāo)地址在某一個(gè)通用寄存器中,或在某一個(gè)字存儲(chǔ)單元中。格式:JMPR/M例如:JMPCX或者JMPWORDPTR[BX]2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)分支程序設(shè)計(jì)2、段間轉(zhuǎn)移:轉(zhuǎn)移時(shí),是從一個(gè)代碼段轉(zhuǎn)移到另一個(gè)代碼段。因此,既需要修改IP,CS也要修改。(1)段間轉(zhuǎn)移直接尋址:JMP指令的操作數(shù)部分直接給出目標(biāo)單元。格式:JMPFARPTR標(biāo)號(hào)(2)段間轉(zhuǎn)移間接尋址:JMP指令轉(zhuǎn)移的目標(biāo)地址在一個(gè)作地址指針的雙字單元中。地址指針前兩個(gè)字節(jié)存放目標(biāo)的偏移量,后兩個(gè)字節(jié)存放目標(biāo)的段基值。格式:JMPDWORDPTRM例如:JMPDWORDPTRADDR[BX]或者JMPDWORDPTR[BX][SI]2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)分支程序設(shè)計(jì)二、比較指令CMP指令格式:CMPDEST,SRC比較指令屬于減法類(lèi)操作指令,它在完成兩個(gè)操作數(shù)相減((DEST)-(SRC))后,僅把減法運(yùn)算的某些結(jié)果特征記錄在標(biāo)記寄存器的相應(yīng)標(biāo)志位上:OF、SF、ZF、AF、PF、CF,而不保留差的結(jié)果。比較指令主要用于判定兩個(gè)操作數(shù)的大小。如ZF=1,表示(DEST)=(SRC)對(duì)于無(wú)符號(hào)數(shù),如CF=0,表示(DEST)≥(SRC),否則(DEST)<(SRC)對(duì)于有符號(hào)數(shù),如CF=SF,表示(DEST)>(SRC),如CF≠SF,則(DEST)<(SRC)2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)分支程序設(shè)計(jì)三、條件轉(zhuǎn)移指令8086/8088指令系統(tǒng)提供了18條條件轉(zhuǎn)移指令。其指令格式為:
JXX目標(biāo)其中J后面的“XX”是指條件,若條件成立,則轉(zhuǎn)移至“目標(biāo)”處指令,否則順序執(zhí)行。條件轉(zhuǎn)移指令都以標(biāo)志寄存器中某一個(gè)或幾個(gè)標(biāo)志位的狀態(tài)作為判斷條件。因此在條件轉(zhuǎn)移指令前,通常由一些算術(shù)運(yùn)算、邏輯運(yùn)算或者比較、測(cè)試指令的執(zhí)行結(jié)果來(lái)設(shè)置有關(guān)標(biāo)志位,然后根據(jù)要求,選擇相關(guān)條件轉(zhuǎn)移指令。簡(jiǎn)單條件轉(zhuǎn)移指令是根據(jù)單個(gè)標(biāo)志位的狀態(tài)判斷轉(zhuǎn)移條件的。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)簡(jiǎn)單條件轉(zhuǎn)移指令指令轉(zhuǎn)移條件含義JCCF=1有進(jìn)位/借位轉(zhuǎn)移JNCCF=0無(wú)進(jìn)位/借位轉(zhuǎn)移JE/JZZF=1相等/等于0轉(zhuǎn)移JNE/JNZZF=0不相等/不等于0轉(zhuǎn)移JSSF=1是負(fù)數(shù)轉(zhuǎn)移JNSSF=0是正數(shù)轉(zhuǎn)移JOOF=1有溢出轉(zhuǎn)移JNOOF=0無(wú)溢出轉(zhuǎn)移JP/JPEPF=1有偶數(shù)個(gè)“1”轉(zhuǎn)移JNP/JPOPF=0有奇數(shù)個(gè)“1”轉(zhuǎn)移2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)分支程序設(shè)計(jì)(2)無(wú)符號(hào)數(shù)條件轉(zhuǎn)移指令如果在條件轉(zhuǎn)移指令前使用比較指令,比較兩個(gè)無(wú)符號(hào)數(shù)或者偏移量A、B,指令進(jìn)行的操作是A–B,其轉(zhuǎn)移指令如下:
指令轉(zhuǎn)移條件含義JA/JNBECF=0ANDZF=0A>B轉(zhuǎn)移JAE/JNBCF=0ORZF=1A
B轉(zhuǎn)移JB/JNAECF=1ANDZF=0A<
B轉(zhuǎn)移JBE/JNACF=1ORZF=1A
B轉(zhuǎn)移2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)分支程序設(shè)計(jì)(3)帶符號(hào)數(shù)條件轉(zhuǎn)移指令在條件轉(zhuǎn)移指令前使用比較指令,比較兩個(gè)帶符號(hào)數(shù)A、B,其轉(zhuǎn)移指令如下:條件轉(zhuǎn)移指令的執(zhí)行不影響標(biāo)志寄存器的標(biāo)志位。
指令轉(zhuǎn)移條件含義JG/JNLESF=OFANDZF=0A>B轉(zhuǎn)移JGE/JNLSF=OFORZF=1A
B轉(zhuǎn)移JL/JNGESFOFANDZF=0A<
B轉(zhuǎn)移JLE/JNGSF
OFORZF=1A
B轉(zhuǎn)移2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)分支程序設(shè)計(jì)常用的分支程序有兩種結(jié)構(gòu)形式:比較/測(cè)試分支結(jié)構(gòu)分支表(跳轉(zhuǎn)表)結(jié)構(gòu)1、比較/測(cè)試分支結(jié)構(gòu)使用這種結(jié)構(gòu)時(shí),在產(chǎn)生分支前,通常用比較/測(cè)試的辦法來(lái)設(shè)置標(biāo)志寄存器中相應(yīng)的標(biāo)志位,然后再選用適當(dāng)?shù)臈l件轉(zhuǎn)移指令來(lái)實(shí)現(xiàn)不同情況的分支轉(zhuǎn)移。使用比較/測(cè)試分支結(jié)構(gòu)來(lái)設(shè)計(jì)程序時(shí),首先根據(jù)要處理的問(wèn)題進(jìn)行比較、測(cè)試、算術(shù)運(yùn)算,或邏輯運(yùn)算以產(chǎn)生標(biāo)志寄存器中能表達(dá)的“標(biāo)志”。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)例:編寫(xiě)一程序段計(jì)算以下公式:Y=1X>00X=0–1X<0X0?X=0?Y
–1Y0Y1NYNYNEXT設(shè)X、Y為字節(jié)變量,需3個(gè)分支,用帶符號(hào)數(shù)條件轉(zhuǎn)移指令判斷CMPX,0;X0?
JGEBIGER;若X0轉(zhuǎn)到BIGER,否則順序執(zhí)行
MOVY,
–1;X<0,Y
–1
JMPNEXTBIGER:JZEQUL;若X=0轉(zhuǎn)到EQUL,否則順序執(zhí)行
MOVY,
1;X>0,Y1
JMPNEXTEQUL:MOVY,
0;X=0,Y0
NEXT:2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)分支程序設(shè)計(jì)使用比較/測(cè)試分支結(jié)構(gòu)可以實(shí)現(xiàn)多分枝程序設(shè)計(jì),但是當(dāng)分支過(guò)多,有三個(gè)缺陷:
(1)繁瑣。
(2)多次測(cè)試將花費(fèi)大量時(shí)間
(3)到達(dá)不同分支的時(shí)間不一。
而使用跳轉(zhuǎn)表來(lái)實(shí)現(xiàn)多路分支則可以避免這些問(wèn)題。跳轉(zhuǎn)表是一段連續(xù)的存儲(chǔ)區(qū),根據(jù)其內(nèi)容可以分為分支地址標(biāo)和轉(zhuǎn)移指令表兩種。由此對(duì)應(yīng)兩種跳轉(zhuǎn)表法分支程序設(shè)計(jì)。(1)分支地址標(biāo)法(2)轉(zhuǎn)移指令表法2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)分支程序設(shè)計(jì)如果程序需要n路分支,每路程序的入口地址分別為SUB1、SUB2、…、SUBn。把這些轉(zhuǎn)移的入口地址組成一個(gè)表,就稱(chēng)為跳轉(zhuǎn)表。在跳轉(zhuǎn)表中每?jī)蓚€(gè)字節(jié)存放一個(gè)入口地址的偏移量。跳轉(zhuǎn)表也可由若干跳轉(zhuǎn)指令組成,這時(shí)用無(wú)條件轉(zhuǎn)移指令,且每條指令的目標(biāo)代碼長(zhǎng)度要一致,否則分支程序的編制將非常麻煩。因此我們?cè)诰幹瞥绦虻臅r(shí)候,通常將分支程序的入口地址存放在跳轉(zhuǎn)表中,來(lái)實(shí)現(xiàn)多路分支程序。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)例:設(shè)指定的參數(shù)是1、2、3、…、n,當(dāng)參數(shù)為1時(shí),轉(zhuǎn)移到SUB1,當(dāng)參數(shù)為2時(shí),轉(zhuǎn)移到SUB2,依次類(lèi)推。這時(shí)跳轉(zhuǎn)表里存放地址則是按SUB1、SUB2、SUB3、…、SUBn的順序排列的。源程序:TITLEEXAMPLEOFJMP_TABLEDATASEGMENTTABLEDWSUB1,SUB2,SUB3,…,SUBnPARAMDB3DATAENDSSTACK1SEGMENTPARASTACKDW10HDUP(0)STACK1ENDS2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)COSEGSEGMENTASSUMECS:COSEG,DS:DATA,SS:STACK1BEGIN:MOVAX,DATAMOVDS,AXMOVAL,PARAMXORAH,AHDECALSHLAL,1MOVBX,OFFSETTABLEADDBX,AXJMP[BX]SUB1:…JMPEND02023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)SUB2:…JMPEND0SUB3:…JMPEND0…SUBn:…END0:MOVAH,4CHINT21HCOSEGENDSENDBEGIN2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)5.4循環(huán)程序設(shè)計(jì)一、循環(huán)指令8086/8088指令系統(tǒng)有4種循環(huán)指令,能夠靈活實(shí)現(xiàn)各種循環(huán)。1、LOOP指令指令格式:LOOP目標(biāo)執(zhí)行LOOP指令,在進(jìn)行循環(huán)次數(shù)的計(jì)數(shù),即執(zhí)行(CX)=(CX)-1,若(CX)≠0,則轉(zhuǎn)移到目標(biāo)單元,否則順序執(zhí)行。例數(shù)據(jù)段的ARY數(shù)組中存放有10個(gè)無(wú)符號(hào)數(shù),試找出其中最大者送入MAX單元。要求使用循環(huán)指令實(shí)現(xiàn),試編制源程序。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)DATASEGMENTARYDB17,5,40,0,67,12,34,78,32,10MAXDB?DATAENDS…MOVSI,OFFSETARY;SI指向ARY的第一個(gè)元素
MOVCX,9;CX作循環(huán)次數(shù)計(jì)數(shù)
MOVAL,[SI]LOP:INCSICMPAL,[SI]JAEBIGERMOVAL,[SI]BIGER:LOOPLOPMOVMAX,AL…2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)循環(huán)指令2、LOOPE/LOOPZ指令指令格式:LOOPE/LOOPZ目標(biāo)執(zhí)行LOOPE/LOOPZ指令,在進(jìn)行循環(huán)次數(shù)的計(jì)數(shù),即執(zhí)行(CX)=(CX)-1,若(CX)≠0且ZF=1,則轉(zhuǎn)移到目標(biāo)單元,否則順序執(zhí)行。例:編寫(xiě)一程序,在一數(shù)組中查找第一非0數(shù),并將其在數(shù)組中的偏移量(1~n)送入INDEX單元中。若未找到,則將INDEX單元置為全1。源程序如下:2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)TITLECHECKNO_ZERONUMBERDATASEGMENTARRAYDB0,0,0,0,3,5,0,7,0AHLENGEQU$-ARRAYINDEXDB?DATAENDSSTACK1SEGMENTPARASTACKDW20HDUP(0)STACK1ENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACK1START:MOVAX,DATAMOVDS,AX2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)MOVCX,LENG;數(shù)組長(zhǎng)度送入CXMOVBX,-1;設(shè)地址指針初值NEXT:INCBXCMPARRAY[BX],0;該數(shù)值是否為0LOOPENEXT;是0且計(jì)數(shù)不為0,繼續(xù)查找
JNZFOUND;找到非0數(shù),轉(zhuǎn)FOUNDMOVBL,0FFH;未找到非0數(shù)FOUND:MOVINDEX,BL;存結(jié)果
MOVAH,4CHINT21HCODEENDSENDSTART2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)循環(huán)指令3、LOOPNE/LOOPNZ指令格式:LOOPNE/LOOPNZ目標(biāo)執(zhí)行LOONPE/LOOPNZ指令,在進(jìn)行循環(huán)次數(shù)的計(jì)數(shù),即執(zhí)行(CX)=(CX)-1,若(CX)≠0且ZF=0,則轉(zhuǎn)移到目標(biāo)單元,否則順序執(zhí)行。例:編制一程序,求兩個(gè)數(shù)組對(duì)應(yīng)的數(shù)據(jù)之和,并把和存入新數(shù)組SUM中。計(jì)算一直進(jìn)行到兩數(shù)之和為零或者數(shù)組結(jié)束。將新數(shù)組的長(zhǎng)度存于LEN單元中。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)TITLEARRAYSUMDATASEGMENTARRAY1DB2,5,0,3,-4,5,0,0AH,0FFHARRAY2DB3,5,4,-2,0,8,3,-0AH,20HCOUNTDB$-ARRAY2LENDB?SUMDB20HDUP(0)STACK1SEGMENTPARASTACKDW20HDUP(0)STACK1ENDSCOSEGSEGMENTASSUMECS:COSEG,DS:DATA,SS:STACK12023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)START:MOVAX,DATAMOVDS,AXMOVBX,-1;初始化地址指針
MOVCX,0MOVCL,COUNT;初始化數(shù)組長(zhǎng)度NOZERO:INCBXMOVAL,ARRAY1[BX]ADDAL,ARRAY2[BX]MOVSUM[BX],ALLOOPNENOZERO;CX≠0且ZF=0繼續(xù)循環(huán)
INCBLMOVLEN,BLMOVAH,4CHINT21HCOSEGENDSENDSTART2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)循環(huán)指令指令格式:JCXZ目標(biāo)地址指令功能:測(cè)試CX的內(nèi)容是否為0,如果(CX)=0,則轉(zhuǎn)移到目標(biāo)處執(zhí)行,否則順序執(zhí)行。JCXZ指令用于在循環(huán)前測(cè)試循環(huán)次數(shù),因?yàn)槿绻h(huán)初始值為0,將會(huì)產(chǎn)生次數(shù)非常大的循環(huán),這樣就不應(yīng)去執(zhí)行此循環(huán)了。JCXZ指令與其它循環(huán)指令的區(qū)別是:JCXZ指令沒(méi)有將CX寄存器內(nèi)容減1的功能。程序中使用JCXZ指令的格式:
MOVCX,COUNTJCXZNEXTLOP:…LOOPLOPNEXT:…2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)循環(huán)程序的結(jié)構(gòu)循環(huán)程序通常由5部分組成:1、初始化部分建立循環(huán)初始值。如初始化地址指針、計(jì)數(shù)器及其他循環(huán)參數(shù)的起始值。2、工作部分在循環(huán)過(guò)程中做具體事情,完成若干操作,是循環(huán)程序的主要部分。工作部分根據(jù)具體情況可以是一個(gè)順序程序、分支程序或者循環(huán)程序。如果工作部分是另外一個(gè)循環(huán)程序,則叫做多重循環(huán)。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)循環(huán)程序的結(jié)構(gòu)3、修改部分為執(zhí)行下一個(gè)循環(huán)而修改某些參數(shù)。如修改地址指針,其他循環(huán)參數(shù)等。4、控制部分判斷循環(huán)結(jié)束條件是否成立。判斷方法通常有兩種:(1)用計(jì)數(shù)器控制循環(huán):循環(huán)進(jìn)行完預(yù)定次數(shù)后結(jié)束循環(huán)。(2)用條件控制循環(huán):根據(jù)循環(huán)終止的條件來(lái)控制循環(huán)結(jié)束。5、結(jié)束處理部分對(duì)循環(huán)結(jié)束進(jìn)行適當(dāng)處理,如存儲(chǔ)結(jié)果。這部分在有些循環(huán)程序不是必需的。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)循環(huán)程序的結(jié)構(gòu)循環(huán)程序有兩種結(jié)構(gòu),一種是先執(zhí)行循環(huán)體然后再判斷循環(huán)條件,另一種是先判斷循環(huán)條件,滿足條件才執(zhí)行循環(huán)體。先循環(huán)再判斷就是指執(zhí)行完初始化部分后,接著執(zhí)行工作部分和修改部分,然后再執(zhí)行控制部分進(jìn)行循環(huán)條件的判斷。這種循環(huán)結(jié)構(gòu)至少能完成一次循環(huán)體的執(zhí)行過(guò)程。(P95圖5.11)先判斷再循環(huán)就是指在執(zhí)行完初始化部分后就執(zhí)行控制部分進(jìn)行循環(huán)條件的判斷,如果循環(huán)終止條件成立就不執(zhí)行工作部分和控制部分,轉(zhuǎn)入結(jié)束處理部分。這種循環(huán)結(jié)構(gòu)可能一次也不執(zhí)行循環(huán)體。(P95圖5.12)2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)循環(huán)程序的結(jié)構(gòu)通常我們有兩種方法判斷循環(huán)結(jié)束條件是否成立:用計(jì)數(shù)器控制循環(huán)和用條件控制循環(huán)。1、用計(jì)數(shù)器控制循環(huán)用計(jì)數(shù)器控制循環(huán)的方法直觀、方便、易于程序設(shè)計(jì)。如果循環(huán)次數(shù)已知我們就可以使用這種方法設(shè)計(jì)循環(huán)程序。然后大部分時(shí)候,我們?cè)诰幹瞥绦虻臅r(shí)候并不能確切知道循環(huán)次數(shù),但是知道循環(huán)次數(shù)是前面運(yùn)算或操作的結(jié)果或者被存放某內(nèi)存單元中。因此,在進(jìn)入循環(huán)前進(jìn)行初始化工作的時(shí)候就可以獲得循環(huán)次數(shù)。凡是在執(zhí)行循環(huán)前已知道循環(huán)次數(shù)的,都稱(chēng)為循環(huán)次數(shù)已知。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)例:試編制已程序,統(tǒng)計(jì)DA數(shù)據(jù)區(qū)中0、正數(shù)、負(fù)數(shù)的個(gè)數(shù)并將數(shù)值存放在DA數(shù)據(jù)區(qū)后面的連續(xù)3個(gè)字節(jié)單元中。問(wèn)題分析:循環(huán)次數(shù)CX為DA數(shù)據(jù)區(qū)內(nèi)字?jǐn)?shù)據(jù)的個(gè)數(shù);分別用AH,AL,BL存放0、正數(shù)和負(fù)數(shù)的個(gè)數(shù),將其初始化為0;將DA中的數(shù)據(jù)分別跟0比較判斷出0、正數(shù)和負(fù)數(shù),將對(duì)應(yīng)的計(jì)數(shù)器加一。流程圖:
P96圖5.13循環(huán)程序的結(jié)構(gòu)2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)源程序:
TITLESTATISTICSDATASEGMENTDADW-1,0,8,-4,-5,9,0,7,9,34,-5,0,45CUNTDB?;存放正數(shù)的個(gè)數(shù)
DB?;存放0的個(gè)數(shù)
DB?;存放負(fù)數(shù)的個(gè)數(shù)DATAENDSSTACK1SEGMENTPARASTACKDW10DUP(0)STACK1ENDS2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)CODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACK1START:MOVAX,DATAMOVDS,AXMOVAX,0;初始化統(tǒng)計(jì)個(gè)數(shù)計(jì)數(shù)器
MOVBX,0LEASI,DAMOVCX,CUNT-DASHRCX,1LOP:CMPWORDPRT[SI],0JZZERO;等于0JNSPLUS;大于02023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)INCBL;負(fù)數(shù)個(gè)數(shù)加1JMPNEXTZERO:INCAH;JMPNEXTPLUS:INCALNEXT:ADDSI,2LOOPLOPMOVCUNT,ALMOVCUNT+1,AHMOVCUNT+2,BLMOVAH,4CHINT21HCODEENDSENDSTART2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)循環(huán)程序的結(jié)構(gòu)用計(jì)數(shù)器控制循環(huán)的方法直觀、方便、易于程序設(shè)計(jì)。但要求在執(zhí)行循環(huán)前已知道循環(huán)次數(shù)的,在有些情況下就不能確定循環(huán)的次數(shù)。這時(shí)候,循環(huán)結(jié)束是用某些條件來(lái)確定的。用條件控制循環(huán)時(shí),編制程序主要是尋找控制條件及對(duì)控制條件的檢測(cè)。例如:編制一程序,產(chǎn)生給定數(shù)以內(nèi)的裴波納契數(shù)列,并將數(shù)列的數(shù)據(jù)個(gè)數(shù)存放在LEN字節(jié)單元中。分析:循環(huán)結(jié)束條件為產(chǎn)生裴波納契數(shù)列數(shù)據(jù)大于給定數(shù)(P97)。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)5.5子程序設(shè)計(jì)為了能夠增強(qiáng)代碼的可重用性,在程序中,如果在不同地方需要多次使用某程序段,我們往往單獨(dú)編制一指令序列。當(dāng)程序運(yùn)行時(shí),需要完成此功能時(shí)就轉(zhuǎn)移到該指令序列,執(zhí)行完后又返回到原來(lái)位置繼續(xù)執(zhí)行。這個(gè)單獨(dú)編制的指令序列就是子程序。轉(zhuǎn)移到子程序就稱(chēng)為調(diào)用子程序。調(diào)用子程序也是一種轉(zhuǎn)移指令的形式。在8086/8088宏匯編程序中,子程序是以過(guò)程的形式表示的。由于程序可以在不同的邏輯段中,因此子程序的調(diào)用與返回有段內(nèi)調(diào)用與返回和段間調(diào)用與返回兩種情況。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)子程序設(shè)計(jì)子程序的定義:PROCEDURE_NAMEPROC[NEAR/FAR]…RET…RETPROCEDURE_NAMEENDP2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)子程序設(shè)計(jì)(1)段內(nèi)調(diào)用與返回:調(diào)用子程序指令與子程序在同一個(gè)段內(nèi)。因此,這種子程序的調(diào)用與返回同段內(nèi)轉(zhuǎn)移指令一樣,僅需修改指令指針I(yè)P。(2)段間調(diào)用與返回:調(diào)用子程序指令與子程序分別在不同的段。因此,這種子程序的調(diào)用與返回同段間轉(zhuǎn)移指令一樣,需同時(shí)修改CS和IP。段內(nèi)調(diào)用和段間調(diào)用時(shí),尋找目標(biāo)地址均有直接尋址和間接尋址兩種方式。調(diào)用子程序指令和轉(zhuǎn)移指令的區(qū)別是,調(diào)用子程序指令需要保留“斷點(diǎn)”,在子程序結(jié)束后返回到原來(lái)的斷點(diǎn)繼續(xù)運(yùn)行。而轉(zhuǎn)移指令則不考慮目標(biāo)處指令序列運(yùn)行結(jié)束后的去向,無(wú)需保留“斷點(diǎn)”。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)子程序設(shè)計(jì)一、調(diào)用指令指令格式:CALL過(guò)程名執(zhí)行CALL指令時(shí),首先保留斷點(diǎn)于堆棧中,如果是段內(nèi)調(diào)用則只將偏移量壓入堆棧中,而段間調(diào)用則需將偏移量和段基值都?jí)喝攵褩#缓筠D(zhuǎn)移到目標(biāo)單元。CALL指令的執(zhí)行對(duì)標(biāo)志寄存器無(wú)影響。1、段內(nèi)調(diào)用(1)段內(nèi)直接調(diào)用:調(diào)用指令CALL后直接書(shū)寫(xiě)過(guò)程名。例如:CALLPROCA(2)段內(nèi)間接調(diào)用:這種調(diào)用方式的子程序起始地址(段內(nèi)偏移量)在一個(gè)通用寄存器或一個(gè)字存儲(chǔ)單元中。例如:CALLBX或CALLWORDPTR20H[BX]2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)子程序設(shè)計(jì)2、段間調(diào)用(1)段內(nèi)直接調(diào)用:調(diào)用指令CALL后直接書(shū)寫(xiě)過(guò)程名,或用屬性修改運(yùn)算符PTR說(shuō)明“類(lèi)型”是FAR。例如:CALLFARPTRPROCB(2)段內(nèi)間接調(diào)用:這種調(diào)用方式的子程序起始地址存放在一個(gè)4字節(jié)組成的地址指針中,兩個(gè)低字節(jié)存放偏移量,兩個(gè)高字節(jié)存放段基值。例如:CALLDWORDPTRADDR[BX][SI]2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)子程序設(shè)計(jì)二、返回指令子程序執(zhí)行的最后一條指令一點(diǎn)是返回指令(RET),用來(lái)返回到調(diào)用此子程序的斷點(diǎn)處。為了保證從子程序正確的返回,返回指令RET必須與調(diào)用時(shí)的調(diào)用指令一致。段內(nèi)和段間返回都使用指令RET,但它們的目標(biāo)代碼不同。(1)段內(nèi)返回,指令編碼為C3,執(zhí)行返回后,從堆棧頂部彈出一個(gè)字的內(nèi)容送入IP中。(2)段間返回,指令編碼為CB,執(zhí)行返回后,從堆棧頂部彈出兩個(gè)字的內(nèi)容送入IP和CS中。(3)段內(nèi)和段間返回指令RET后面可以跟一個(gè)立即數(shù)n,n總是偶數(shù),表示堆棧彈出返回地址后,再次修改堆棧指針SP的值,SP=SP+n,即把CALL前壓入的參數(shù)彈出堆棧。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)編制子程序的基本要求
返回指令RET的執(zhí)行不影響標(biāo)志寄存器。三、編制子程序的基本要求子程序是在程序中多次重復(fù)使用的實(shí)現(xiàn)一定功能的程序段,因此編制子程序有較高要求,要求子程序的執(zhí)行時(shí)間短,占用內(nèi)存少,而且要使用方便。1、具有一定的通用性入口參數(shù)和出口參數(shù)的設(shè)計(jì)。為了使子程序擁有較好的通用性,在子程序中常常有些允許變化的數(shù)據(jù)和地址,以便主程序調(diào)用前給定,在子程序運(yùn)行結(jié)束時(shí),又會(huì)得到一些結(jié)果,以供調(diào)用程序使用。這就是程序的入口參量和出口參量。編寫(xiě)子程序一個(gè)重要的問(wèn)題就是決定入口參量和出口參量。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)編制子程序的基本要求2、選擇適當(dāng)?shù)膮?shù)傳遞方法(1)使用通用寄存器最簡(jiǎn)便的方法,但通用寄存器屬數(shù)量有限。(2)使用指定的存儲(chǔ)單元此方法不受參量數(shù)量的限制,但使用專(zhuān)門(mén)的存儲(chǔ)單元,編制調(diào)用程序時(shí)比較麻煩,特別是這些存儲(chǔ)單元與調(diào)用程序所用的數(shù)據(jù)段不在同一段時(shí)就更為復(fù)雜。(3)使用堆棧這種方法最為靈活,堆棧中的參量通常是存放在存放在斷點(diǎn)返回地址的下面。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)編制子程序的基本要求3、注意信息保存在執(zhí)行子程序前,需要保持主程序中的信息,以便能正確返回主程序。信息保存有兩種方法:(1)在主程序中保存子程序中將要使用的一些寄存器的內(nèi)容。(2)在子程序中保存將要使用的一些寄存器的內(nèi)容。4、正確使用堆棧在調(diào)用子程序時(shí)會(huì)將斷點(diǎn)的返回地址壓入堆棧,而執(zhí)行返回指令時(shí)又需要從棧頂彈出斷點(diǎn)的返回地址,如果子程序中使用了堆棧,那么在執(zhí)行RET指令前應(yīng)該保證SP指向剛進(jìn)入子程序時(shí)的位置。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)編制子程序的基本要求5、編制子程序文件子程序文件應(yīng)該由兩部分組成:文字說(shuō)明和子程序本身。文字說(shuō)明部分是為子程序的使用提供方便的,使用戶可以無(wú)需查看子程序的內(nèi)部結(jié)構(gòu)和程序就可以正確使用。子程序的文字說(shuō)明通常包括:(1)子程序名(2)子程序功能描述(3)子程序的入口參數(shù)與出口參數(shù)(4)使用哪些寄存器和存儲(chǔ)單元(5)本子程序是否又調(diào)用其他子程序(6)子程序的調(diào)用形式、舉例2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)關(guān)于子程序的嵌套調(diào)用不要求掌握。子程序設(shè)計(jì):例:將兩個(gè)給定的二進(jìn)制數(shù)轉(zhuǎn)換為對(duì)應(yīng)字符ASCII碼。問(wèn)題分析:由于要將兩個(gè)數(shù)轉(zhuǎn)換成ASCII碼,因此我們可以用子程序來(lái)完成數(shù)到其字符ASCII碼轉(zhuǎn)換的功能。主程序提供被轉(zhuǎn)換的數(shù)和轉(zhuǎn)換后ASCII碼的存儲(chǔ)區(qū)首地址。因此,子程序的入口參量是被轉(zhuǎn)換的數(shù)和轉(zhuǎn)換后ASCII碼的存儲(chǔ)區(qū)首地址,沒(méi)有出口參量。程序流程圖:子程序設(shè)計(jì)2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)開(kāi)始取出待轉(zhuǎn)換數(shù)據(jù)給出存放結(jié)果首址給出待轉(zhuǎn)換數(shù)的位數(shù)調(diào)用轉(zhuǎn)換子程序取出待轉(zhuǎn)換數(shù)據(jù)給出存放結(jié)果首址給出待轉(zhuǎn)換數(shù)的位數(shù)調(diào)用轉(zhuǎn)換子程序結(jié)束B(niǎo)INASC待轉(zhuǎn)換的一位二進(jìn)制數(shù)送AL的第0位DX<=待轉(zhuǎn)換數(shù)據(jù)DI<=存放ASCII碼首址CX<=轉(zhuǎn)換二進(jìn)制位數(shù)AL<=(AL)^01HAL<=(AL)+30H存ASCII碼:(DI)<=(AL)修改指針:DI<=(DI)+1計(jì)數(shù):CX<=(CX)-1(CX)=0?返回NY主程序子程序2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)源程序的數(shù)據(jù)段和堆棧安排如下:DATASEGMENTBIN1DB35HBIN2DW0AB48HASCBUFDB20HDUP(?)DATAENDSSTACK1SEGMENTPARASTACKDW20HDUP(0)STACK1ENDS參數(shù)的傳遞方法有:1、用寄存器傳遞參量2、用堆棧傳遞參量3、用堆棧傳遞參量(參見(jiàn)教材P106)2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)使用寄存器傳遞參數(shù),在調(diào)用子程序前,把要轉(zhuǎn)換的數(shù)存放DX中(若數(shù)位<16,便從高到低地存放),存放ASCII碼的首址存放在DI中,轉(zhuǎn)換數(shù)的位數(shù)存放在AX中。而保持信息則由主程序完成。其代碼段為:DATASEGMENTBIN1DB35HBIN2DW0AB48HASCBUFDB20HDUP(?)DATAENDSSTACK1SEGMENTPARASTACKDW20HDUP(0)STACK1ENDSCOSEGSEGMENTASSUMECS:COSEG,DS:DATA,SS:STACK1BEGIN:MOVAX,DATAMOVDS,AX2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì) MOVDX,0MOVDH,BIN1;待轉(zhuǎn)換數(shù)存DX中
LEADI,ASCBUF;存放ASCII碼首址
MOVAX,8;待轉(zhuǎn)換二進(jìn)制位數(shù)
PUSHDI;保存信息
CALLBINASC;調(diào)用轉(zhuǎn)換子程序
POPDI;恢復(fù)信息
MOVDX,BIN2;待轉(zhuǎn)換數(shù)據(jù)存放DX中
ADDDI,10H;存放ASCII碼首址
MOVAX,10H;待轉(zhuǎn)換二進(jìn)制位數(shù)
CALLBINASCMOVAH,4CHINT21H2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì);轉(zhuǎn)換子程序BINASCPROCMOVCX,AXLOP:ROLDX,1;通過(guò)不帶進(jìn)位的循環(huán)左移取1位二進(jìn)制數(shù)
MOVAL,DLANDAL,1;清除AL高字節(jié),保留最低位
ADDAL,30HMOV[DI],ALINCDILOOPLOPRETBINASCENDPCOSEGENDSENDBEGIN2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)使用堆棧傳遞參數(shù),在調(diào)用子程序前,已把要轉(zhuǎn)換的數(shù)、存放ASCII碼的首址和轉(zhuǎn)換的位數(shù)壓入堆棧。而保持信息則由子程序完成。其代碼段為:COSEGSEGMENTASSUMECS:COSEG,DS:DATA,SS:STACK1BEGIN:MOVAX,DATAMOVDS,AX MOVAX,0MOVAL,BIN1PUSHAX;待轉(zhuǎn)換數(shù)據(jù)壓棧
MOVAX,8PUSHAX;轉(zhuǎn)換位數(shù)壓棧
LEAAX,ASCBUFPUSHAX;存放ASCII碼的首址壓棧
CALLBINASC;調(diào)用轉(zhuǎn)換子程序2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì) MOVAX,BIN2 PUSHAX MOVAX,16 PUSHAXLEAAX,ASCBUF+10H PUSHAXCALLBINASC MOVAH,4CHINT21HBINASCPROC;轉(zhuǎn)換子程序
MOVBP,SP;當(dāng)前SP送BPPUSHAXPUSHCXPUSHDXPUSHDI MOVDI,[BP+2] ;從堆棧取入口參數(shù)
MOVCX,[BP+4]MOVDX,[BP+6]2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)CMPCX,8JNETRANSMOVDH,DLTRANS:ROLDX,1MOVAL,DLANDAL,1ADDAL,30HMOV[DI],ALINCDILOOPTRANSPOPDIPOPDXPOPCXPOPAXRET6;返回并從堆棧中彈出6個(gè)字節(jié)
BINASCENDPCOSEGENDSENDBEGIN2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)5.6DOS功能子程序調(diào)用操作系統(tǒng)為程序設(shè)計(jì)人員提供了許多可直接調(diào)用的功能子程序。調(diào)用時(shí)需使用軟中斷指令:
INTn其中,n為中斷調(diào)用類(lèi)型號(hào),其值為00~0FFH。在使用INT指令前,應(yīng)將調(diào)用的功能號(hào)送入AH,有關(guān)入口參量送入指定寄存器中;若有出口參量,中斷調(diào)用返回后,其結(jié)果存放在知道的寄存器或存儲(chǔ)單元中。DOS功能子程序的調(diào)用使用軟中斷指令“INT21H”。DOS功能子程序共有84個(gè)功能子程序。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)DOS功能子程序調(diào)用DOS功能子程序的主要功能有:磁盤(pán)的讀寫(xiě)控制、文件操作、目錄操作、內(nèi)存管理、基本輸入輸出管理及設(shè)置/讀出系統(tǒng)日期、時(shí)間等。對(duì)于DOS功能子程序我們只需按下列步驟調(diào)用就可:(1)送入口參量給指定寄存器(2)功能號(hào)送入到AH中(3)INT21H而對(duì)于DOS功能子程序的具體實(shí)現(xiàn)則是由操作系統(tǒng)實(shí)現(xiàn)的。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)DOS功能子程序調(diào)用1、帶顯示的鍵盤(pán)輸入(1號(hào)功能)
MOVAH,01HINT21H
該功能子程序等待鍵盤(pán)輸入,直到按下一個(gè)鍵,把輸入字符的ASCII碼送入到AL寄存器中,并在屏幕上顯示該字符。如果按下的鍵是Ctrl–C組合鍵,則停止程序的運(yùn)行。如果按下的是TAB制表鍵,屏幕上光標(biāo)自動(dòng)擴(kuò)展到緊接的8個(gè)字符位置后面。1號(hào)功能調(diào)用,毋需入口參量,出口參量在AL中。2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)DOS功能子程序調(diào)用2、不帶顯示的鍵盤(pán)輸入(8號(hào)功能)該功能調(diào)用與1號(hào)功能調(diào)用基本類(lèi)同,差異僅在8號(hào)功能調(diào)用時(shí),鍵盤(pán)輸入的字符不在屏幕上顯示。調(diào)用方法:MOVAH,08HINT21H3、不帶顯示的鍵盤(pán)字符輸入(7號(hào)功能)與8號(hào)功能調(diào)用基本類(lèi)同,差異僅在7號(hào)功能調(diào)用,如果按下Ctrl–C組合鍵和TAB制表鍵,程序無(wú)反應(yīng),繼續(xù)等待輸入。調(diào)用方法:
MOVAH,07HINT21H2023/10/228086/8088宏匯編語(yǔ)言程序設(shè)計(jì)DOS功能子程序調(diào)用4、字符串輸入(0A號(hào)功能)一次調(diào)用接受一串字符,以回車(chē)鍵
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 兩部門(mén)要求做好“三區(qū)”人才支持計(jì)劃教師專(zhuān)項(xiàng)計(jì)劃工作
- 醫(yī)美運(yùn)營(yíng)合同范本
- 仁懷酒廠收購(gòu)合同范本
- 廚師勞務(wù)合同范本單位
- 出售恒安小區(qū)房子合同范本
- 個(gè)人買(mǎi)賣(mài)狗狗合同范本
- 廠區(qū)門(mén)面房租賃合同范例
- 《荷葉圓圓》說(shuō)課稿
- 叉車(chē) 吊車(chē)合同范本
- 農(nóng)村私房承建合同范本
- 汽機(jī)組拆除方案
- 脊柱損傷搬運(yùn)(共18張)課件
- 新教材人教版高中化學(xué)選擇性必修3全冊(cè)各章節(jié)知識(shí)點(diǎn)考點(diǎn)重點(diǎn)難點(diǎn)歸納總結(jié)
- 生產(chǎn)組織供應(yīng)能力說(shuō)明
- 碳酸丙烯酯法脫碳工藝工程設(shè)計(jì)
- 藥劑學(xué)-名詞解釋
- 口語(yǔ)課件Unit 1 Ways of Traveling Possibility and Impossibility
- 城市支路施工組織設(shè)計(jì)
- 耐堿玻纖網(wǎng)格布檢測(cè)報(bào)告
- 20米往返跑教案 (2)
- 甲醛安全周知卡
評(píng)論
0/150
提交評(píng)論