匯編語言65129_第1頁
匯編語言65129_第2頁
匯編語言65129_第3頁
匯編語言65129_第4頁
匯編語言65129_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費閱讀

付費下載

下載本文檔

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

文檔簡介

1、匯編語言程序設(shè)計 2005第四章 匯編語言程序設(shè)計回顧:8086的內(nèi)部結(jié)構(gòu)、寄存器功能和工作過程,指令格式、尋址方式和功能。本講重點:了解匯編的概念及其方法, 掌握匯編程序的基本格式,常用運算符的使用方法,匯編的步驟。4.1匯編語言的基本元素一、匯編語言的語句格式 由匯編語言編寫的源程序是由許多語句(也可稱為匯編指令)組成的。每個語句由14個部分組成,其格式是: 標號 指令助記符 操作數(shù) ;注解其中用方括號括起來的部分,可以有也可以沒有。每部分之間用空格(至少一個)分開,一行最多可有132個字符。1. 標識符給指令或某一存儲單元地址所起的名字??捎上铝凶址M成: 字母:A z ; 數(shù)字:0 9

2、 ; 特殊字符:?、· 、一、$ 。 數(shù)字不能作標識符的第一個字符,而圓點僅能用作第一個字符。標識符最長為31個字符。當標識符后跟冒號時,表示是標號。它代表該行指令的起始地址;當標識符后不帶冒號時,表示變量;偽指令前的標識符不加冒號。2. 指令助記符 表示不同操作的指令,可以是8086的指令助記符,也可以是偽指令。3. 操作數(shù) 指令執(zhí)行的對象。依指令的要求,可能有一個、兩個或者沒有,例如: RET ;無操作數(shù) COUNT: INC CX ;一個操作數(shù) 如果是偽指令,則可能有多個操作數(shù),例如: COST DB 3,4,5,6,7 ;5個操作數(shù) MOV AX,BP+4 ;第二個操作數(shù)為表

3、達式4. 注解 該項可有可無,是為源程序所加的注解,用于提高程序的可讀性。二、匯編語言的運算符1. 算術(shù)運算符、邏輯運算符和關(guān)系運算符算術(shù)運算符可以應(yīng)用于數(shù)字操作數(shù),結(jié)果也是數(shù)字。而應(yīng)用于存儲器操作數(shù)時,只有、 運算符有意義。2. 取值運算符SEG、OFFSET、TYPE、SIZE和LENGTH· SEG和OFFSET分別給出一個變量或標號的段地址和偏移量。例如,定義: SLOT DW 25則: MOV AX,SLOT;從SLOT地址中取一個字送入AXMOV AX,SEG SLOT;將SLOT所在段的段地址送入AXMOV AX,OFFSET SLOT;將SLOT所在段的段內(nèi)偏移地址送

4、AX· TYPE操作符返回一個表示存儲器操作數(shù)類型的數(shù)值。各種存儲器地址操作數(shù)類型部分的值如表4-1所示。表4-1存儲器操作數(shù)的類型屬性及返回值字節(jié)1字2雙字4NEAR1FAR2· LENGTH和SIZE操作符只應(yīng)用于數(shù)據(jù)存儲器操作數(shù)。(用DB/DW/DD等定義的操作數(shù))LENGTH返回一個與存儲器地址操作數(shù)相聯(lián)系的單元數(shù),SIZE操作數(shù)返回一個為存儲器操作數(shù)分配的字節(jié)數(shù)。例如:若 MULT-WORD DW 50DUP(0)則 LENGTH(MULT-WORD)=50SIZE(MULT-WORD)=100注意:SIZE(X)=(LENGTH X)* (TYPE X)3. 屬

5、性運算符 屬性運算符用來給指令中的操作數(shù)指定一個臨時屬性,而暫時忽略當前的屬性。常用的有:(1) 合成運算符PTR它作用于操作數(shù)時,則忽略了操作數(shù)當前的類型(字節(jié)或字)及屬性(NEAR或FAR),而給出一個臨時的類型或?qū)傩?,一般格式:類?PTR 表達式功能:建立一個存儲器地址操作數(shù),它與其后的存儲器地址操作數(shù)有相同的段地址偏移量,但有不同的類型。例如:SLOT DW 25 此時SLOT已定義成字單元。若我們想取出它的第一個字節(jié)內(nèi)容,則可用PTR對其作用,使它暫時改變?yōu)樽止?jié)單元,即 MOV AL,BYTE PTR SLOT三、表達式 由運算符和操作數(shù)組成的序列,在匯編時產(chǎn)生一個確定的值。這個值

6、可以僅表示一個常量,也可以表示一個存儲單元的偏移地址,相應(yīng)的表達式稱為常量表達式和地址表達式。1. 常數(shù) 匯編語言語句中出現(xiàn)的常數(shù)可以有7種: 二進制數(shù) 后跟字母B,如01000001B。 八進制數(shù) 后跟字母Q或O,如202Q或202O。 十進制數(shù) 后跟D或不跟字母,如85D或85。 十六進制數(shù) 后跟H,如56H,0FFH。注意,當數(shù)字的第一個字符是AF時,在字符前應(yīng)添加一個數(shù)字0,以示和變量的區(qū)別。 另有,十進制浮點數(shù)、十六進制實數(shù)、字符和字符串2. 常量操作數(shù) 常量操作數(shù)是一個數(shù)值操作數(shù),一般是常量或者是表示常量的標識符??梢詾閿?shù)字常量操作數(shù)或字符串常量操作數(shù)。前者可采用二進制、八進制、十

7、進制或十六進制等計數(shù)形式;而后者則為相應(yīng)字符的ASCII碼。3. 存儲器操作數(shù)存儲器操作數(shù)是一個地址操作數(shù),代表一個存儲單元的地址,通常以標識符的形式出現(xiàn)。存儲器操作數(shù)可以分為變量及標號兩種類型,如果存儲器操作數(shù)所代表的是某個數(shù)據(jù)在數(shù)據(jù)段、附加段或堆棧段中的地址,那么這個存儲器操作數(shù)就稱為變量;如果存儲器操作數(shù)所代表的是某條指令代碼在代碼段中的地址,那么這個存儲器操作數(shù)稱為標號。變量所對應(yīng)的存儲單元內(nèi)容在程序的運行過程中是可以改變的,標號通常作為轉(zhuǎn)移指令或調(diào)用指令的目標操作數(shù),在程序運行過程中不能改變。 存儲器操作數(shù)有三個方面的屬性。 (1) 段地址:即存儲器操作數(shù)所對應(yīng)的存儲單元所在段的段地

8、址; (2) 偏移地址:即存儲器操作數(shù)所對應(yīng)的存儲單元在所在段內(nèi)的偏移地址; (3) 類型:變量的類型是相應(yīng)存儲單元所存放的數(shù)據(jù)項的字節(jié)數(shù);而標號的類型則反映了相應(yīng)存儲單元地址在作為轉(zhuǎn)移或調(diào)用指令的目標操作數(shù)時的尋址方式,可有兩種情況,即 NEAR和FAR。具體值可見表4-14. 常量表達式由常量操作數(shù)及運算符構(gòu)成,在匯編時產(chǎn)生一個常量。如PORT、VAL1、 OFFSET SUM、SEG SUM、TYPE CYCLE等。5. 地址表達式由存儲器操作數(shù)與運算符構(gòu)成,必須有明確的物理意義。 例如 SUM2、CYCLE5表達式SUM2、CYCLE5的值仍然是一個存儲器操作數(shù),該存儲器操作數(shù)的段地址

9、與類型屬性分別與存儲器操作數(shù)SUM及CYCLE相同,但偏移地址分別比SUM及CYCLE大2或小5。表達式是在匯編時計算的,而變量單元的內(nèi)容在程序的運行過程中可以改變。四、匯編語言程序匯編步驟匯編語言程序要能在機器上運行,還必需將匯編源程序匯編成可執(zhí)行程序。為此必須完成以下幾個步驟。 1. 編輯源程序2. 調(diào)用宏匯編對源程序進行匯編3. 對目標程序進行連接 4. 運行可執(zhí)行程序并調(diào)試 【習(xí)題與思考】1.下列語句在存儲器中分別為變量分配多少字節(jié)空間?并畫出存儲空間的分配圖。VAR1 DB10,2VAR2DW5DUP(?),0VAR3DBHOW ARE YOU?,$VAR4DD-1,1,02. 假定

10、VAR1和VAR2為字變量,LAB為標號,試指出下列指令的錯誤之處。(1)ADDVAR1,VAR2(2)SUBAL,VAR1(3)JMPLABSI(4)JNZVAR13. 對于下面的符號定義,指出下列指令的錯誤。A1DB?A2DB10K1EQU1024(1)MOVK1,AX(2)MOVA1,AX(3)CMPA1,A2(4)K1EQU20484.2 偽指令【回顧】匯編的概念及其方法, 掌握匯編程序的基本格式。8086/8088的指令格式?!颈局v重點】了解偽指令的功能,掌握定義數(shù)據(jù)、符號、段、過程等偽指令的使用方法,能編寫格式正確的匯編程序。4.2 偽指令偽指令用來對匯編程序進行控制,對程序中的數(shù)

11、據(jù)實現(xiàn)條件轉(zhuǎn)移、列表、存儲空間分配等處理,其格式和匯編指令一樣,但一般不產(chǎn)生目的代碼,即不直接命令CPU去執(zhí)行什么操作。一、定義數(shù)據(jù)偽指令 該類偽指令用來定義存儲空間及其所存數(shù)據(jù)的長度。 · DB:定義字節(jié),即每個數(shù)據(jù)是1個字節(jié)。 · DW:定義字,即每個數(shù)據(jù)占1個字(2個字節(jié))。 · DD:定義雙字,即每個數(shù)據(jù)占2個字。低字部分在低地址,高字部分在高地址。 · DQ:定義4字長,即每個數(shù)據(jù)占4個字。· DT:定義10個字節(jié)長,用于壓縮式十進制數(shù),例如:DATA1 DB 5,6,8,100 DATA2 DW 7,287TABLE DB ? ;表

12、示在TABLE單元中存放的內(nèi)容是隨機的;當一個定義的存儲區(qū)內(nèi)的每個單元要放置同樣的數(shù)據(jù)時,可用DUP操作符。一般格式:COUNT DUP(?),COUNT 為重復(fù)的次數(shù),“()”中為要重復(fù)的數(shù)據(jù)。如:BUFFER DB 100 DUP(0) ;表示以BUFFER為首地址的100個字節(jié)中存放00H數(shù)據(jù)BUFFER1 DB 100 DUP(3,5,2DUP(10),35),24,NUM)想一想存儲區(qū)的情況?二、符號定義偽指令EQU、=、及PURGE· EQU 偽指令給符號定義一個值。在程序中,凡是出現(xiàn)該符號的地方,匯編時均用其值代替,如:TIMES EQU 50 DATA DB TIME

13、S DUP(?) 上述兩個語句實際等效于如下一條語句:DATA DB 50 DUP(?)· “=”偽指令可給初始變量賦值。如:COUNT=100 ;COUNT=100TIME=50 ;TIME=50· PURGE偽指令用于釋放由EQU偽指令定義的變量,使這些變量可以被重新定義。 PURGE TIMES ; 釋放TIMES變量 TIMES EQU 2 ; 重新定義三、段定義偽指令SEGMENT和ENDS 一般來說,一個完整的匯編源程序由3個段組成,即堆棧段、數(shù)據(jù)段和代碼段。段定義偽指令可將源程序劃分成若干段,以便生成目的代碼和連接時將各同名段進行組合。 段定義偽指令一般格式為

14、 : 段名 SEGMENT 定位類型 組合類型 類別 段名 ENDS SEGMENT和ENDS應(yīng)成對使用,缺不可。其中段名是不可省略的。其它是可選項,是賦予段名的屬性,可以省略。例如: DATA SEGMENT DW 20DUP(?)DATA ENDS四、設(shè)定段寄存器偽指令A(yù)SSUME一般格式: ASSUME 段寄存器:段名,段寄存器:段名,功能:通知匯編程序,哪一個段寄存器是該段的段寄存器,以便對使用變量或標號的指令匯編出正確的目的代碼。在段名中,CODE表示代碼段,DATA表示數(shù)據(jù)段,STACK表示堆棧段。由于ASSUME偽指令只指明某一個段地址應(yīng)存于哪一個段寄存器中,并沒有包含將段地址送

15、入該寄存器的操作。因此要將真實段地址裝入段寄存器還需用匯編指令來實現(xiàn)。這一步是不可缺少的。例如,CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK MOV AX,DATA ;DATA段值送AX MOV DS,AX ;AX內(nèi)容送DS,DS才有實際段值CODE ENDS 當程序運行時,由于DOS的裝入程序負責(zé)把CS初始化成正確的代碼段地址,SS初始化為正確的堆棧段地址,因此用戶在程序中就不必設(shè)置。但是,在裝入程序中DS寄存器由于被用作其它用途,因此,在用戶程序中必須用兩條指令對DS進行初始化,以裝入用戶的數(shù)據(jù)段地址。當使用附加段時,也要用MOV指令給ES賦段地

16、址。五、定義過程的偽指令PROC和ENDP在程序設(shè)計中,可將具有一定功能的程序段看成為一個過程(相當于一個子程序),它可以被別的程序調(diào)用。一個過程由偽指令PROC和ENDP來定義,其格式為: 過程名 PROC 類型 過程體 RET 過程名 ENDP 其中過程名是為過程所起的名稱,不能省略,過程的類型由FAR(遠過程,為段間調(diào)用)和NEAR(近過程,在本段內(nèi)調(diào)用)來確定,如果缺省類型,則該過程就默認為近過程。ENDP表示過程結(jié)束。過程體內(nèi)至少應(yīng)有一條RET指令,以便返回被調(diào)用處。過程可以嵌套,也可以遞歸使用。 例如一個延時100ms的子程序,其過程可定義如下, DELAY PROC PUSH B

17、X PUSH CX MOV BL,10 ;延時10ms,改變BL和CX中的值,即可改變延時時間。AGAIN: MOV CX,2801 ; WAIT; LOOP WAIT DEC BL JNZ AGAIN POP CX POP BX RETDELAY ENDPCALL DELAY ;調(diào)用該過程 遠過程調(diào)用時被調(diào)用過程必定不在本段內(nèi)。例如,有兩個程序段,其結(jié)構(gòu)如下: CODE1 SEGMENT ASSUME CS:CODE1 FARPROC PROC FAR RET FARPROC ENDP CODE1 ENDS CODE2 SEGMENT ASSUME CS:CODE2CALL FARPROC.

18、CODE2 ENDSCODE1 段中的FARPROC 過程被另一段CODE2調(diào)用,故為遠過程。六、宏指令 在匯編語言書寫的源程序中,若有的程序段要多次使用,為了簡化程序書寫,該程序段可以用一條宏指令來代替,而匯編程序匯編到該宏指令時,仍會產(chǎn)生源程序所需的代碼。宏指令的一般格式為:宏指令名 MACRO 形式參量表 宏體 ENDM例如:SHIFT MACRO MOV CL,4 SAL AL,Cl ENDM 這樣定義以后,凡是要使AL中內(nèi)容左移4位的操作都可用一條宏指令SHIFT來代替。宏指令與子程序有許多類似之處。它們都是一段相對獨立的、完成某種功能的、可供調(diào)用的程序模塊,定義后可多次調(diào)用。但在形

19、成目的代碼時,子程序只形成一段目的代碼,調(diào)用時轉(zhuǎn)來執(zhí)行。而宏指令是將形成的目的代碼插到主程序調(diào)用的地方。因此,前者占內(nèi)存少,但執(zhí)行速度稍慢;后者剛好相反。七、ORG 偽指令ORG偽指令規(guī)定了在某一段內(nèi),程序或數(shù)據(jù)代碼存放的起始偏移地址。 一般格式: ORG <表達式>例如:DATASEGMENT BUFF1DB23,56H,EOF ORG2000H BUFF2DBSTRING DATAENDS上述變量定義中,BUFF1從DATA段偏移地址為0的單元開始存放,而BUFF2則從DATA段偏移為2000H的單元開始存放,兩者不是連續(xù)存放。八、匯編結(jié)束偽指令END 該偽指令表示源程序的結(jié)束

20、令匯編程序停止匯編。因此,任何一個完整的源程序均應(yīng)有END指令。一般格式: END 表達式其中表達式表示該匯編程序的啟動地址。例如:END START ;表明該程序的啟動地址為START。習(xí)題與思考:1數(shù)據(jù)定義語句如下所示: FIRST DB 90H,5FH,6EH,69H SECOND DB 5 DUP(?) THIRD DB 5 DUP(?) FORTH DB 5 DUP(?)自FIRST單元開始存放的是一個四字節(jié)的十六進制數(shù)(低位字節(jié)在前),要求:(1)編一段程序?qū)⑦@個數(shù)左移兩位、右移兩位后存放到自SECOND開始的單元(注意保留移出部分。(2)編一段程序?qū)⑦@個數(shù)求補以后存放到自FORT

21、H開始的單元。2試編程序?qū)?nèi)存從40000H到4BFFFH的每個單元中均寫入55H,并再逐個單元讀出比較,看寫入的與讀出的是否一致。若全對,則將AL置7EH;只要有錯,則將AL置81H。3在當前數(shù)據(jù)段4000H開始的128個單元中存放一組數(shù)據(jù),試編程序?qū)⑺鼈冺樞虬嵋频紸000H開始的順序128個單元中,并將兩個數(shù)據(jù)塊逐個單元進行此較;若有錯將BL置00H;全對則將BL置FFH,試編程序。3.3匯編程序設(shè)計【回顧】8086的指令系統(tǒng),匯編程序的基本格式,偽指令的功能,匯編程序的正確格式?!颈局v重點】掌握匯編程序的分析與設(shè)計方法(包括分支程序和循環(huán)程序)一、簡單程序設(shè)計簡單程序設(shè)計是沒有分支,沒有

22、循環(huán)的直線運行程序,程序執(zhí)行按照IP內(nèi)容自動增加的順序進行?!纠?】 利用查表法計算平方值。已知0 9的平方值連續(xù)存在以SQTAB開始的存儲區(qū)域中,求SUR單元內(nèi)容X的平方值,并放在DIS單元中。假定0X 9且為整數(shù)。分析:建立平方表,通過查表完成。STACKSEGMENTDB 100 DUP(?)STACK ENDSDATASEGMENTSUR DB ?DIS DB ?SQTAB DB 0,1,4,9,16,25,36,49,64,81 ; 09的平方表DATA ENDSCODESEGMENTASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATABEGIN:PUSH

23、DSMOVAX,0PUSHAX ;保證返回DOS,MOVAX,DATAMOVDS,AX ;為DS送初值LEA BX,SQTAB ;以下程序部分完成查表求平方值MOVAH,0 ;亦可用查表指令完成(如下程序段)MOVAL,SUR ;AL=X LEA BX, SQTABADDBX,AX ; MOV AL, SURMOVAL,BX ; XLAT MOVDIS,AL ; MOV DIS, ALCODEENDSEND BEGIN【例2】已知Z=(X+Y)-(W+Z),其中X,Y,Z,W均為用壓縮BCD碼表示的數(shù),寫出程序。分析:這也是一種典型的直線程序,在這里要注意是BCD數(shù)相加,要進行十進制調(diào)整。具體

24、程序如下:MOVAL,ZMOVBL,WADDAL,BLDAAMOVBL,AL ; BL=(W+Z)MOVAL,XMOVDL,YADDAL,DL ; AL=(X+Y)DAA ;十進制調(diào)整SUBAL,BL ; AL=(X+Y)-(Z+W)DAS ;十進制調(diào)整MOVZ,AL ;結(jié)果送Z 二、分支程序設(shè)計分支程序的基本思想是根據(jù)邏輯判斷的結(jié)果來形成程序的分支,如圖,若A成立,則執(zhí)行P1;否則執(zhí)行P2。 【例3】 試編寫程序段,實現(xiàn)符號函數(shù)。分析:變量X的符號函數(shù)可表示為: 1 X>0Y= 0 X=0-1 X<0 程序可通過對符號標志的判別來確定執(zhí)行哪一分支。START:MOVAX,BUFF

25、ER ;(BUFFER)=XORAX,AXJEZERO ;X0,則轉(zhuǎn)ZEROJNSPLUS ;X為正數(shù),則轉(zhuǎn)PLUSMOVBX,0FFFFH ;X為負數(shù),則1送BX表4-2 子程序R1R8的入口地址表P1子程序R1的入口偏移地址P2子程序R2的入口偏移地址P3子程序R3的入口偏移地址.P7子程序R7的入口偏移地址P8子程序R8的入口偏移地址JMPCONT1ZERO:MOVBX,0JMPCONT1PLUS:MOVBX,1CONT1: 【例4】 利用表實現(xiàn)分支根據(jù)AL中各位被置位情況,控制轉(zhuǎn)移到8個子程序P1P8之一中去。轉(zhuǎn)移表的結(jié)構(gòu)如表4-2所示。分析:對于這種程序關(guān)鍵要找出每種情況的轉(zhuǎn)移地址,

26、從圖中可見表地址=表基地址+偏移量, 而偏移量可由AL各位所在位置*2求得。DATASEGMENTBASEDW SR0,SR1,SR2,SR3, SR4,SR5,SR6,SR7DATAENDSCODESEGMENT ASSUME CS:CODE,DS:DATA,ES:DATABEGIN: PUSHDSXORAX,AXPUSH AXMOVAX,DATA MOVDS,AX LEABX,BASE ;表頭送BXINAL,PORT GETBIT:RCR AL,1 ;右移一位JC GETAD ;移出位是1?INCBX INC BX ;修改指針JMPGETBI GETAD:JMP WORDPTRBX ;實現(xiàn)

27、散轉(zhuǎn)CODEENDS END BEGIN根據(jù)跳轉(zhuǎn)表構(gòu)成方法不同,實現(xiàn)分支的方法也有所改變,下面有三個問題希望大家思考:(1) 若跳轉(zhuǎn)表地址由段值和偏移量四個字節(jié)構(gòu)成,程序應(yīng)如何實現(xiàn)?(2) 若跳轉(zhuǎn)表中的內(nèi)容由JMP OPRD指令構(gòu)成,表的結(jié)構(gòu)應(yīng)如何組織、程序如何實現(xiàn)?(3) 上述程序若不用間接跳轉(zhuǎn)指令,而改為直接跳轉(zhuǎn),程序如何變動?【例5】 將內(nèi)存中某一區(qū)域的原數(shù)據(jù)塊傳送到另一區(qū)域中。分析 這種程序若源數(shù)據(jù)塊與目的數(shù)據(jù)塊之間地址沒有重疊,則可直接用傳送或串操作實現(xiàn);若地址重疊,則要先判斷源地址+數(shù)據(jù)塊長度是否小于目的地址,若是,則可按增量方式進行,否則要修改指針指向數(shù)據(jù)塊底部,采用減量方式傳送

28、。程序如下:DATASEGMENTSTRDB1000DUP(?)STR1EQUSTR+7STR2EQUSTR+25STRCOUNTEQU50DATAENDSSTACKSEGMENT PARA STACK STACKSTAPNDB100DUP(?)STACKENDSCODESEGMENTASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACKGOO PROCPUSHDSSUBAX,AXPUSHAXMOVAX,DATAMOVDS,AXMOVES,AXMOVAX,STACKMOVSS,AXMOVCX,STRCOUNTMOVSI,STR1MOVDI,STR2CLDPUSHSIAD

29、DSI,STRCOUNT-1CMPSI,DIPOPSIJLOKSTDADDSI,STRCOUNT-1ADDDI,STRCOUNT-1OK:REPMOVSBRETGOOENDPCODEENDSENDGOO 圖4-4 循環(huán)結(jié)構(gòu)示意圖三、循環(huán)程序設(shè)計 循環(huán)程序是經(jīng)常遇到的程序結(jié)構(gòu),一個循環(huán)結(jié)構(gòu)通常由以下幾個部分組成。 1. 循環(huán)初始化部分 一般要進行地址指針、循環(huán)次數(shù)及某標志的設(shè)置,相關(guān)寄存器的清零等操作。只有正確地進行了初始化設(shè)置, 循環(huán)程序才能正確運行,及時停止。2. 循環(huán)體 是要求重復(fù)執(zhí)行的程序段部分,對應(yīng)于要求重復(fù)執(zhí)行的操作。 3. 循環(huán)控制部分 由該部分修改并判斷控制循環(huán)的條件是否滿足。以

30、決定是否繼續(xù)循環(huán)。 4. 循環(huán)結(jié)束部分 如保存循環(huán)運行結(jié)果等。 循環(huán)程序有兩種結(jié)構(gòu)形式,一種是DOWHILE結(jié)構(gòu),另一種是DOUNTIL結(jié)構(gòu)。前者把循環(huán)控制部分放在循環(huán)體的前面,先判斷執(zhí)行循環(huán)體的條件,滿足條件就執(zhí)行循環(huán)體,否則就退出循環(huán),如圖3-4(1)所示。而后者則是在執(zhí)行循環(huán)體之后,再判斷循環(huán)控制條件是否滿足,若滿足條件,則繼續(xù)執(zhí)行循環(huán)操作,否則,則退出循環(huán)。如圖4-4(2)所示。DOWHILE結(jié)構(gòu)的循環(huán)程序,其循環(huán)體有可能并不執(zhí)行,而DOUNTIL循環(huán)程序的循環(huán)體至少必須執(zhí)行一次?!纠?】 設(shè)內(nèi)存BUFF開始的單元中依次存放著30個8位無符號數(shù),求它們的和并放在SUM單元中,試編寫程序

31、。分析:這是一個求累加的程序。程序如下:MOV SI,BUFF ;設(shè)地址指針MOVCX,30 ;設(shè)計數(shù)初值XORAX,AX ;設(shè)累加器初值A(chǔ)GAIN:ADDAL,SIADCAH,0INCSIDECCXJNZAGAIN ;循環(huán)累加MOVSUM,AX【例7】 在給定個數(shù)的16位數(shù)串中,找出大于零、等于零和小于零的個數(shù),并緊跟著原串存放。分析:這是一個統(tǒng)計問題,須設(shè)定三個計數(shù)器分別統(tǒng)計三種情況下的結(jié)果。程序如下:DATASEGMENTBUFFDW X1,X2,X3,XnCOUNT EQU $-BUFF ;此時,COUNT的值為BUFF所占的字節(jié)數(shù)PLUSE DB ?ZERO DB ?MINUSDB

32、?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATAASSUMEES:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVCX,COUNTSHRCX,1 ;相當于除2,正好為BUFF中的數(shù)據(jù)個數(shù)MOVDX,0 ;設(shè)定計數(shù)器初值MOVAX,0 ;設(shè)定計數(shù)器初值LEABX,BUFFAGAIN: CMP WORD PTRBX,0JAEPLU ;大于等于0,則轉(zhuǎn)PIUINCAH ;<0,則統(tǒng)計JMPNEXTPLU: JZZER ;0,則轉(zhuǎn)ZERINCDL ;>0,則統(tǒng)計JMPNEXTZER:INCDH ;0,則統(tǒng)計NEXT:INCB

33、XINCBXLOOPAGAINMOVPLUS,DLMOVZERO,DHMOVMINUS,AHMOVAX,4C00HINT21HCODEENDSENDBEGIN【例8】 在ADDR單元中存放著16位數(shù)Y的地址,試編寫一程序,把Y中1的個數(shù)存入COUNT單元中。分析:這是一個循環(huán)統(tǒng)計的工作。采用DOWHILE結(jié)構(gòu),做16次循環(huán),每次將最高位移入CF中進行測試,先判斷結(jié)果是否為0,若為0,則結(jié)束;否則統(tǒng)計計數(shù)后循環(huán)重復(fù)。程序如下:DATASEGMENTADDRDWNUMBERNUMBERDWYCOUNTDW?DATAENDSPROGRAMSEGMENTMAINPROCFARASSUMECS:PROG

34、RAM,DS:DATASTART:PUSHDSMOVAX,0PUSHAXMOVAX,DATAMOVDS,AXMOVCX,0 ;計數(shù)器初值0MOVBX,ADDRMOVAX,BX ;取Y送AXREPEAT:TESTAX,0FFFFH ;檢測是否為全0JZEXIT ;是,則轉(zhuǎn)EXITJNSSHIFT ;最高位是0,則轉(zhuǎn)SHIFTINCCX ;最高位是1,則統(tǒng)計計數(shù)SHIFT:SHLAX,1 ;處理下一位JMPREPEATEXIT:MOVCOUNT,CXRETMAINENDPPROGRAMENDSENDSTART在實際應(yīng)用中,有些問題較復(fù)雜,一重循環(huán)不夠,必須使用多重循環(huán)實現(xiàn),這些循環(huán)是一層套一層的,

35、通常稱為循環(huán)嵌套?!纠?】在DS所決定的數(shù)據(jù)段,從偏移地址BUFFER開始順序存放100個無符號16位數(shù),現(xiàn)要編寫程序?qū)⑦@100個字數(shù)據(jù)從大到小排序。分析:排序的方法有很多,在這里,我們采用冒泡法。程序如下: LEA DI,BUFFER ;DI作為指針,指向要排序的數(shù)據(jù) MOVBL,99 ;循環(huán)控制初值NEXT0:MOVSI,DI MOVCL,BLNEXT3:MOVAX,SI ;取一個數(shù) ADDSI,2CMPAX,SI ;與下一個數(shù)進行比較JNCNEXT5 ;大于等于時轉(zhuǎn)移MOVDX,SI ;否則,兩數(shù)交換MOVSI-2,DXMOVSI,AXNEXT5:DECCL ;控制進行交換的次數(shù)JNZN

36、EXT3DECBL ;修改交換的次數(shù)JNZNEXT0HLT習(xí)題與思考:1設(shè)變量單元A、B、C存放有三個數(shù),若三個數(shù)都不為零,則求三個數(shù)的和,存放在D中;若有一個為零,則將其余兩個也清零,試編寫程序。2有一個100個字節(jié)的數(shù)據(jù)表,表內(nèi)元素已按從大到小的順序排列好,現(xiàn)給定一元素,試編程序在表內(nèi)查找,若表內(nèi)已有此元素,則結(jié)束;否則,按順序?qū)⒋嗽夭迦氡碇羞m當?shù)奈恢?,并修改表長。3內(nèi)存中以FIRST和SECOND開始的單元中分別存放著兩個16位組合的十進制(BCD碼)數(shù),低位在前。編程序求這兩個數(shù)的組合的十進制和,并存到以THIRD開始的單元。4編寫一段程序,接收從鍵盤輸入的10個數(shù),輸入回車符表示結(jié)

37、束,然后將這些數(shù)加密后存于BUFF緩沖區(qū)中。加密表為:輸入數(shù)字:0,1,2,3,4,5,6,7,8,9;密碼數(shù)字:7,5,9,1,3,6,8,0,2,4四、子程序設(shè)計子程序是程序設(shè)計中經(jīng)常使用的程序結(jié)構(gòu),通過把一些固定的、經(jīng)常使用的功能做成子程序的形式,可以使源程序及目標程序大大縮短,提高程序設(shè)計的效率和可靠性。對于一個子程序,應(yīng)該注意它的入口參數(shù)和出口參數(shù)。入口參數(shù)是由主程序傳給子程序的參數(shù),而出口參數(shù)是子程序運算完傳給主程序的結(jié)果。另外,子程序所使用的寄存器和存儲單元往往需要保護,以免影響返回后主程序的運行。主程序在調(diào)用子程序時,一方面初始數(shù)據(jù)要傳給子程序,另一方面子程序運行結(jié)果要傳給主程

38、序,因此,主子程序之間的參數(shù)傳遞是非常重要的。參數(shù)傳遞一般有三種方法實現(xiàn):(1) 利用寄存器 這是一種最常見方法,把所需傳遞的參數(shù)直接放在主程序的寄存器中傳遞給子程序。(2) 利用存儲單元 這種參數(shù)傳遞方法,把所需傳遞的參數(shù)直接放在子程序調(diào)用指令代碼之后。(3) 利用堆棧 這種方法將參數(shù)壓入堆棧,在子程序運行時從堆棧中取參數(shù)。下面我們通過實例說明子程序設(shè)計及參數(shù)傳遞方法?!纠?0】 兩個6字節(jié)數(shù)相加。分析:將一個字節(jié)相加的程序段設(shè)計為子程序。主程序分3次調(diào)用該子程序,但每次調(diào)用的參數(shù)不同。程序如下:DATASEGMENTADD1DBFEH,86H,7CH,35H,68H,77HADD2DB45

39、H,BCH,7DH,6AH,87H,90HSUMDB 6DUP(0)COUNTDB6DATAENDSSTACKSEGMENTDB100DUP(?)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKMADD:MOVAX,DATAMOVDS,AXMOVAX,STACKMOVSS,AXMOVSI,OFFSETADD1MOVDI,OFFSETADD2MOVBX,OFFSET SUMMOVCX,COUNT ;循環(huán)初值為6CLCAGAIN:CALL SUBADD ;調(diào)用子程序LOOP AGAIN ;循環(huán)調(diào)用6次MOVAX,4C00HINT21H;子程序入口

40、參數(shù):SI,DI,BX 出口參數(shù):SI,DI,BXSUBADDPROC ;完成一個字節(jié)相加PUSHAX ;保護AX的值MOVAL,SI ;SI是一個源操作數(shù)指針ADCAL,DI ;DI是另一個源操作數(shù)指針MOVBX,AL ;BX是結(jié)果操作數(shù)指針I(yè)NCSIINCDIINCBXPOPAX ;恢復(fù)AX的值RETSUBADDENDPCODEENDSEND MADD【例11】 把內(nèi)存中的字變量NUMBER的值,轉(zhuǎn)換為4個ASCII碼表示的十六進制數(shù)碼串,串的起始地址為STRING。分析:把內(nèi)存中的字變量NUMBER的值,轉(zhuǎn)換為4個ASCII碼表示的十六進制數(shù)碼串的工作設(shè)計成一個子程序,在這個子程序中再調(diào)用另一個子程序,由它完成從BCD碼到ASCII碼的轉(zhuǎn)換。程序如下:DATASEGMENTNUMBERDW 25AFHSTR

溫馨提示

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

評論

0/150

提交評論