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

下載本文檔

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

文檔簡(jiǎn)介

第三章匯編程序設(shè)計(jì)

編制匯編語(yǔ)言程序的步驟:(1)分析題意,確定算法(2)根據(jù)算法畫(huà)出程序框圖(3)根據(jù)框圖編寫(xiě)程序(4)上機(jī)調(diào)試程序分支結(jié)構(gòu)子程序結(jié)構(gòu)程序結(jié)構(gòu):

復(fù)合結(jié)構(gòu):多種程序結(jié)構(gòu)的組合…

順序結(jié)構(gòu)循環(huán)結(jié)構(gòu)按照指令執(zhí)行的順序,程序的結(jié)構(gòu)可以劃分成以下三種。

順序結(jié)構(gòu):程序按照它編寫(xiě)的順序執(zhí)行,每條指令只執(zhí)行一

次,這樣的程序稱(chēng)為“順序結(jié)構(gòu)”的程序。

循環(huán)結(jié)構(gòu):一組指令被反復(fù)地執(zhí)行,這樣的程序稱(chēng)為“循環(huán)結(jié)

構(gòu)”或者“重復(fù)結(jié)構(gòu)”的程序。

選擇結(jié)構(gòu):根據(jù)某個(gè)條件,一部分指令被執(zhí)行,另一部分指

令沒(méi)有被執(zhí)行,這樣的程序稱(chēng)為“選擇結(jié)構(gòu)”或者

“分支結(jié)構(gòu)”的程序。

程序基本結(jié)構(gòu)3.1順序程序設(shè)計(jì)順序程序:沒(méi)有分支、循環(huán)等轉(zhuǎn)移指令,按指令書(shū)寫(xiě)的前后順利依次執(zhí)行最基本的程序結(jié)構(gòu)完全采用順序結(jié)構(gòu)編寫(xiě)的程序并不多見(jiàn)例題順序程序設(shè)計(jì)實(shí)例采用查表法,實(shí)現(xiàn)一位16進(jìn)制數(shù)轉(zhuǎn)換為ASCII碼顯示例數(shù)據(jù)段;數(shù)據(jù)段ASCII db30h,31h,32h,33h,34h,35h,36h,37h,38h,39h

;對(duì)應(yīng)0~9的ASCII碼

db41h,42h,43h,44h,45h,46h

;對(duì)應(yīng)A~F的ASCII碼hex db04h,0bh ;假設(shè)兩個(gè)要顯示的數(shù)據(jù)例代碼段

;代碼段movbx,offsetASCII ;BX指向ASCII碼表moval,hex ;AL取得一位16進(jìn)制數(shù) ;恰好就是ASCII碼表中的位移andal,0fh ;只有低4位是有效的,高4位清0Xlat

;換碼:AL←DS:[BX+AL]movdl,al ;入口參數(shù):DL←ALmovah,2 ;02號(hào)DOS功能調(diào)用int21h ;顯示一個(gè)ASCII碼字符例代碼段(續(xù))moval,hex+1 ;轉(zhuǎn)換并顯示下一個(gè)數(shù)據(jù)andal,0fhxlatmovdl,almovah,2int21h【例3?1】將16進(jìn)制數(shù)字轉(zhuǎn)換為對(duì)應(yīng)七段碼七段數(shù)碼管:7段LED發(fā)光管通過(guò)7個(gè)發(fā)光段的不同組合,能較好地顯示16進(jìn)制數(shù)字(0,…,9,A,b,C,d,E,F(xiàn))。每一段由一個(gè)二進(jìn)制位控制它的亮或暗??捎靡粋€(gè)字節(jié)來(lái)控制七段數(shù)碼管的顯示。各段順時(shí)針?lè)謩e稱(chēng)為a、b、c、d、e、f、g,有的產(chǎn)品還附帶有一個(gè)小數(shù)點(diǎn)h,依次對(duì)應(yīng)D0~D7位。假定0表示對(duì)應(yīng)段亮,1表示對(duì)應(yīng)段暗,那么顯示數(shù)字0對(duì)應(yīng)的控制碼應(yīng)為11000000B,顯示數(shù)字1對(duì)應(yīng)的控制代碼為11111001B,依此類(lèi)推,顯示數(shù)字F對(duì)應(yīng)的控制代碼為10001110B。這種用于控制七段數(shù)碼管亮暗的代碼就稱(chēng)為七段碼。hgfedcbaDSEGSEGMENT

LEDTB DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H DB80H,90H,88H,83H,0C6H,0C1H,86H,8EH XDATA DB9 ;要顯示的16進(jìn)制數(shù)字

XCODE DB? ;存放要顯示數(shù)字對(duì)應(yīng)的七段碼DSEG ENDSCSEG SEGMENT ASSUMECS:CSEG,DS:DSEGSTART:MOVAX,DSEG MOVDS,AX

MOVBX,OFFSETLEDtb MOVAL,XDATA ;取16進(jìn)制數(shù)字

ANDAL,0FH XLAT ;查表取得對(duì)應(yīng)的七段碼

MOVXCODE,AL ;保存

MOVAX,4C00H INT21HCSEG ENDS ENDSTART3.2分支程序設(shè)計(jì)根據(jù)條件是真或假?zèng)Q定執(zhí)行與否判斷的條件:各種指令(如CMP、TEST等)執(zhí)行后形成的狀態(tài)標(biāo)志分支控制:轉(zhuǎn)移指令Jcc和JMP可以實(shí)現(xiàn)分支結(jié)構(gòu)有單分支結(jié)構(gòu)雙分支結(jié)構(gòu)多分支結(jié)構(gòu)3.2.1單分支結(jié)構(gòu)條件成立跳轉(zhuǎn),否則順序執(zhí)行分支語(yǔ)句體注意選擇正確的條件轉(zhuǎn)移指令和轉(zhuǎn)移目標(biāo)地址【例3-2】求絕對(duì)值計(jì)算AL中有符號(hào)數(shù)的絕對(duì)值

cmpal,0

jgenonneg

;條件滿(mǎn)足(AL≥0),轉(zhuǎn)移

negal

;條件不滿(mǎn)足,求補(bǔ)nonneg:

movresult,al

;條件滿(mǎn)足

;不恰當(dāng)?shù)姆种?/p>

cmpal,0

jlyesneg

;條件滿(mǎn)足(AL<0),轉(zhuǎn)移

jmpnonnegyesneg:

negal

;條件滿(mǎn)足,求補(bǔ)nonneg:

movresult,al

;條件不滿(mǎn)足3.2.2雙分支結(jié)構(gòu)條件成立跳轉(zhuǎn)執(zhí)行第2個(gè)分支語(yǔ)句體,否則順序執(zhí)行第1個(gè)分支語(yǔ)句體注意第1個(gè)分支體后一定要有一個(gè)JMP指令跳到第2個(gè)分支體后【例3-3】顯示BX的最高位顯示BX的最高位

shlbx,1 ;BX最高位移入CF標(biāo)志

jcone

;CF=1,即最高位為1,轉(zhuǎn)移

movdl,30h ;CF=0,即最高位為0:DL←30H=‘0’

jmptwo

;一定要跳過(guò)另一個(gè)分支體one: movdl,31h ;DL←31H=‘1’two: movah,2 int21h ;顯示可以用JNC替換JC顯示BX的最高位(另解1)

shlbx,1 ;BX最高位移入CF標(biāo)志

jncone

;CF=0,即最高位為0,轉(zhuǎn)移

movdl,31h ;CF=1,即最高位為1:DL←31H=‘1’

jmptwo

;一定要跳過(guò)另一個(gè)分支體one: movdl,30h ;DL←30H=‘0’two: movah,2 int21h ;顯示轉(zhuǎn)換為單分支結(jié)構(gòu)顯示BX的最高位(另解2)

movdl,’0’ ;DL←30H=‘0’ shlbx,1 ;BX最高位移入CF標(biāo)志

jnctwo

;CF=0,即最高位為0,轉(zhuǎn)移

movdl,’1’

;CF=1,即最高位為1:DL←31H=‘1’two: movah,2 int21h ;顯示編寫(xiě)分支程序,需留心分支的開(kāi)始和結(jié)束顯示BX的最高位(無(wú)分支)

movdl,0 shlbx,1 ;BX最高位移入CF標(biāo)志

adcdl,30h ;CF=0,DL←0+30h+0=30H=‘0’

;CF=1,DL←0+30h+1=31H=‘1’two: movah,2 int21h ;顯示大小寫(xiě)字母轉(zhuǎn)換

;如果DL是一個(gè)小寫(xiě)字母,則轉(zhuǎn)換為大寫(xiě)

cmpdl,‘a(chǎn)’ ;小于小寫(xiě)字母a,不需要處理

jbdisp cmpdl,‘z’ ;大于小寫(xiě)字母z,也不需要處理

jadisp

subdl,20h

;是小寫(xiě)字母,則轉(zhuǎn)換為大寫(xiě)disp: ……轉(zhuǎn)換原理大小寫(xiě)字母的比較和轉(zhuǎn)換‘A’=41H=01000001B‘B’=42H…‘Z’=5AH=01011001B‘a(chǎn)’=61H=01100001B‘b’=62H…‘z’=7AH=01111001B結(jié)論1:大小寫(xiě)字母的ASCII碼值相差20H結(jié)論2:大小寫(xiě)字母的ASCII碼值僅D5位不同方法1(加減指令):“ADDDL,20H”“SUBDL,20H”方法2(邏輯指令):“ORDL,20H”“ANDDL,0DFH”大小寫(xiě)互換(異或指令):“XORDL,20H”[例3-4]將4位二進(jìn)制轉(zhuǎn)換成對(duì)應(yīng)的十六進(jìn)制字符

MOV AL,X CMP AL,9 JA ALPH

ADD AL,30H JMP DONEALPH:

ADD AL,37HDONE: MOV Y,AL

MOV AL,X OR AL,30H CMP AL,‘9’ JBE DONE

ADD AL,7DONE: MOV Y,AL3.2.3多分支結(jié)構(gòu)如果可供選擇的程序塊多于兩個(gè),這樣的結(jié)構(gòu)稱(chēng)為多分支選擇結(jié)構(gòu),如下圖(a)所示,下圖(b)是匯編語(yǔ)言程序的實(shí)現(xiàn)方法?!纠??5】編程實(shí)現(xiàn)符號(hào)函數(shù):變量X和Y均為數(shù)據(jù)段中字節(jié)變量。

1(X>0)Y=0(X=0)X范圍:(-128~+127)-1(X<0)

MOVAL,X CMPAL,0 JGEBIGER

MOVAL,0FFH;X<0,-1送Y單元

JMPOKBIGER:JEOK;X=0,0送Y單元

MOVAL,1;X>0,1送Y單元

OK: MOVY,AL

DATA SEGMENTPROMPT DB 0DH,0AH,“Inputanumber(1~3):$”MSG1 DB 0DH,0AH,“FUNCTION1EXECUTED.$”MSG2 DB 0DH,0AH,“FUNCTION2EXECUTED.$”MSG3 DB 0DH,0AH,“FUNCTION3EXECUTED.$”DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX[例3-6]從鍵盤(pán)上輸入數(shù)字“1”到“3”,根據(jù)輸入選擇對(duì)應(yīng)程序塊執(zhí)行。INPUT: LEA DX,PROMPT MOV AH,9 INT 21H ;輸出提示信息

MOV AH,1 INT 21H ;輸入一個(gè)數(shù)字

CMP AL,‘1’ JB INPUT ;“0”或非數(shù)字,重新輸入

JE F1 ;數(shù)字“1”,轉(zhuǎn)F1 CMP AL,‘2’ JE F2 ;數(shù)字“2”,轉(zhuǎn)F2 CMP AL,‘3’ JE F3 ;數(shù)字“3”,轉(zhuǎn)F3 JMP INPUT ;大于“3”,重新輸入F1: LEA DX,MSG1 ;F1程序塊

JMP OUTPUTF2: LEA DX,MSG2 ;F2程序塊

JMP OUTPUTF3: LEA DX,MSG3 ;F3程序塊

JMP OUTPUTOUTPUT: MOV AH,9 INT 21H

MOV AX,4C00H INT 21HCODE ENDS END START

DATA SEGMENT

PROMPT DB0DH,0AH,“Inputanumber(1~3):$” MSG1 DB0DH,0AH,“FUNCTION1EXECUTED.$” MSG2 DB0DH,0AH,“FUNCTION2EXECUTED.$” MSG3 DB0DH,0AH,“FUNCTION3EXECUTED.$”ADDTBL DWF1,F2,F3DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA用地址表實(shí)現(xiàn)多分支START:MOVAX,DATA MOV DS,AXINPUT:LEA DX,PROMPT MOV AH,9 INT 21H ;顯示提示信息

MOV AH,1 INT 21H ;輸入一個(gè)數(shù)字

CMP AL,‘1’ JB INPUT ;不正確輸入,重新輸入

CMP AL,‘3’ JA INPUT ;不正確輸入,重新輸入

SUB AL,‘1’ ;將數(shù)字字符“1”到“3”轉(zhuǎn)換為0,1,2 SHL AL,1 ;轉(zhuǎn)換為0,2,4 MOV BL,AL MOV BH,0 ;轉(zhuǎn)入BX

JMP ADDTBL[BX] ;相對(duì)尋址,轉(zhuǎn)移到對(duì)應(yīng)程序塊F1: LEA DX,MSG1 ;F1程序塊

JMP OUTPUT F2: LEA DX,MSG2 ;F2程序塊

JMP OUTPUTF3: LEA DX,MSG3 ;F3程序塊

JMP OUTPUT ;這條指令可以省略O(shè)UTPUT: MOV AH,9 INT 21H

MOV AX,4C00H INT 21HCODE ENDS END START3.3循環(huán)程序設(shè)計(jì)

循環(huán)結(jié)構(gòu)也稱(chēng)“重復(fù)結(jié)構(gòu)”,一般由以下3個(gè)部分組成:(1)初始化部分:為循環(huán)做準(zhǔn)備。 如:累加器清零,設(shè)置地址指針和計(jì)數(shù)器的初始值等。

工作部分:實(shí)現(xiàn)循環(huán)的基本操作。

修改部分:修改指針、計(jì)數(shù)器的值,為下一次循環(huán)做準(zhǔn)備。

控制部分:判斷循環(huán)條件,確定結(jié)束或繼續(xù)循環(huán)。(3)結(jié)束部分:用來(lái)分析和存放程序的結(jié)果。(2)循環(huán)體部分兩種結(jié)構(gòu)的循環(huán):WHILE循環(huán):先判斷循環(huán)條件,條件滿(mǎn)足則進(jìn)入循環(huán),循環(huán)次數(shù)最少為0次。DO-WHILE循環(huán):先執(zhí)行工作部分,然后判斷循環(huán)條件,條件滿(mǎn)足則轉(zhuǎn)向工作部分繼續(xù)循環(huán),循環(huán)次數(shù)最少1次。計(jì)數(shù)循環(huán):循環(huán)的次數(shù)事先已知,用一個(gè)變量(寄存器或存儲(chǔ) 器單元)記錄循環(huán)的次數(shù)(稱(chēng)為“循環(huán)計(jì)數(shù)器”)。條件循環(huán):循環(huán)的次數(shù)事先并不確定,根據(jù)某個(gè)條件是否滿(mǎn)足 來(lái)決定是否繼續(xù)循環(huán)。按照循環(huán)結(jié)束的條件,有以下兩類(lèi)循環(huán):用循環(huán)計(jì)數(shù)器的值來(lái)控制循環(huán),也可以結(jié)合其它條件共同控制。[例]從鍵盤(pán)上輸入一個(gè)字符串(不超過(guò)80個(gè)字符),將它逆序后輸出。DATA SEGMENT BUFFERDB 81,?,81DUP(?) MESS DB 0AH,0DH,“Inputastringplease:”0AH,0DH,“$”DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX LEA DX,MESS MOV AH,09H INT 21H ;輸出提示信息

MOV AH,0AH LEA DX,BUFFER INT 21H ;輸入字符串

LEA BX,BUFFER ;緩沖區(qū)首地址送BX MOV CL,BUFFER+1 MOV CH,0 ;輸入字符個(gè)數(shù)送CX(循環(huán)次數(shù)) ADD BX,CX

INC BX ;計(jì)算字符串末地址送BX(指針)DISP: MOV DL,[BX] MOV AH,02H INT 21H ;逆序輸出一個(gè)字符

DEC BX ;修改指針

LOOP DISP ;計(jì)數(shù)循環(huán)

MOV AX,4C00H INT 21HCODE ENDS END START【例3-7】字節(jié)數(shù)組ARRAY存放有10個(gè)有符號(hào)數(shù),找出最大數(shù)送字節(jié)變量MAX。DATASEGMENT

ARRAYDB-1,59,23,-45,116,107,159,25,218,-14 MAXDB?

DATAENDS

CODESEGMENT ASSUMECS:CODE,DS:DATASTART:MOVAX,DATA MOVDS,AX

MOVAL,ARRAY ;取數(shù)組第一個(gè)元素預(yù)設(shè)為最大數(shù)初值

MOVBX,OFFSETARRAY ;設(shè)置地址指針初值

MOVCX,9 ;設(shè)置比較次數(shù)3.3.1計(jì)數(shù)循環(huán)LOOPl:INC

BX

;修改地址指針,指向下一個(gè)要比較的數(shù)

CMPAL,[BX];比較

JGENEXT

;AL的數(shù)較大,直接結(jié)束本次比較,采用帶符號(hào)數(shù)轉(zhuǎn)移指令

MOVAL,[BX]

;AL的數(shù)較小,將該數(shù)置入AL,使AL始終是當(dāng)前較大值NEXT: LOOPLOOPl

;計(jì)數(shù)循環(huán)控制,cx是否為0

MOVMAX,AL

;比較結(jié)束,保存最大值

MOVAX,4C00H INT 21HCODEENDS ENDSTART3.3.2條件循環(huán)DATA SEGMENT STRING DB “Astringfortesting.”,0

LENTH DW?DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX[例]字符串STRING以代碼0結(jié)束,求這個(gè)字符串的長(zhǎng)度(字符個(gè)數(shù))

LEA SI,STRING ;設(shè)置地址指針初值

MOV CX,0 ;設(shè)置計(jì)數(shù)器初值TST: CMP BYTEPTR[SI],0;比較

JE DONE ;字符串結(jié)束,轉(zhuǎn)向DONE保存結(jié)果

INC SI ;修改指針

INC CX ;計(jì)數(shù)

JMP TST

;轉(zhuǎn)向TST,繼續(xù)循環(huán)DONE: MOV LENTH,CX ;保存結(jié)果

MOV AX,4C00H INT 21HCODE ENDS END START

……

LEA SI,STRING-1 ;裝載字符串指針

MOV CX,-1

;裝載計(jì)數(shù)器初值TST: INC SI ;修改指針

INC CX ;計(jì)數(shù)

CMP BYTEPTR[SI],0

;比較

JNE TST ;未結(jié)束,轉(zhuǎn)TST繼續(xù)循環(huán)

MOV LENTH,CX ;字符串結(jié)束,保存結(jié)果

……比較一下,您喜歡這種風(fēng)格嗎?【例3-8】編程完成求1+2+3+…N的累加和,直到累加和超過(guò)1000為止。統(tǒng)計(jì)被累加的自然數(shù)個(gè)數(shù)送N,累加和送SUM。假定N和SUM為已定義的字變量。DATASEGMENT

SUMDW?NDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AX;設(shè)置DS

MOVAX,0;累加器AX清0

MOVBX,0;BX統(tǒng)計(jì)累加自然數(shù)個(gè)數(shù),清0

LP:

INCBX;BX加1

ADDAX,BX;求累加和

CMPAX,1000;比較累加和是否大于1000

JBELP;≤1000轉(zhuǎn),繼續(xù)累加

MOVSUM,AX;否則結(jié)束累加,保存累加和

MOVN,BX;保存累加的自然數(shù)個(gè)數(shù)

MOVAX,4C00HINT21H;返回DOSCODEENDSENDSTART;匯編結(jié)束【例3-9】統(tǒng)計(jì)BX寄存器中1的個(gè)數(shù),并將結(jié)果存放在DL寄存器中。方法一:條件循環(huán)

MOVAX,BX XORDL,DL

L: ANDAX,AX

;測(cè)試AX中的數(shù)據(jù)是否為0,形成循環(huán)判斷條件

JZEXIT

;循環(huán)控制

SALAX,1

;循環(huán)體:實(shí)現(xiàn)一次統(tǒng)計(jì)。將AX中的最高位移入CF中

JNCL

;如果CF=0,轉(zhuǎn)L

INCDL

;如果CF=1,則(DL)+1→DL

JMPL

;轉(zhuǎn)L處繼續(xù)循環(huán)

EXIT: …方法二:計(jì)數(shù)循環(huán)

MOVAX,BX MOVCX,16 XORDL,DLNEXT:SALAX,1

;循環(huán)體:實(shí)現(xiàn)一次統(tǒng)計(jì)。

;將AX中的最高位移入CF中

JNCL

;如果CF=0,轉(zhuǎn)L處結(jié)束本次循環(huán)

INCDL;如果CF=1,則(DL)+1→DL

L:

LOOPNEXT

;循環(huán)控制:CX減1,判斷CX是否為0,不是0則循環(huán)EXIT: …DATA SEGMENT POSITION DW ? STRING DB “Thisisastringforexample.”,0DATA ENDSCODE SEGMENT ASSUME DS:DATA,CS:CODESTART:MOV AX,DATA MOV DS,AX

[例]查找字母’a’在字符串STRING中第一次出現(xiàn)的位置,如果未出現(xiàn),置位置值為-1。 MOV SI,-1 ;SI用作字符串字符指針

MOV CX,30 ;字符串長(zhǎng)度30L0: INC SI

;修改指針

CMP STRING[SI],‘a(chǎn)’ ;一個(gè)字符與’a’進(jìn)行比較

LOOPNE L0 ;字符串未結(jié)束,未找到,繼續(xù)

JNE NOTFOUND ;未找到,轉(zhuǎn)“NOTFOUND”

MOV POSITION,SI ;保存位置值

JMP EXITNOTFOUND:MOV POSITION,-1 ;未找到,置位置值為-1EXIT: MOV AX,4C00H INT 21HCODE ENDS END START

字符串內(nèi)找到字符’a’:循環(huán)結(jié)束時(shí)ZF=1,SI內(nèi)是字符的出

現(xiàn)位置(從0開(kāi)始);字符串內(nèi)未找到字符’a’:循環(huán)結(jié)束時(shí)ZF=0,SI內(nèi)是字符串

的長(zhǎng)度-1(30-1=29)。程序使用LOOPNE指令來(lái)控制循環(huán),既有計(jì)數(shù)控制,又有條件控制。循環(huán)結(jié)束有兩種可能性:3.3.3多重循環(huán)如果一個(gè)循環(huán)的循環(huán)體內(nèi)包含了另一個(gè)循環(huán),稱(chēng)這個(gè)循環(huán)為“多重循環(huán)”,各層循環(huán)可以是計(jì)數(shù)循環(huán)或者條件循環(huán)。例:在多重循環(huán)的程序結(jié)構(gòu)中,CX計(jì)數(shù)器的保存和恢復(fù)

MOVCX,MAGAIN:

……

PUSHCXMOVCX,NNEXT:……LOOPNEXT……

POPCX

LOOPAGAIN

MOVDI,MAGAIN:……MOVCX,NNEXT:……LOOPNEXT

……

DECDIJNZAGAIN【例3-10】有符號(hào)字節(jié)元素?cái)?shù)組存有N個(gè)有符號(hào)數(shù),要求將這N個(gè)數(shù)由小到大排列。DATA SEGMENT

ARRAY1DB 15H,0A7H,34H,55H,90H,7EH,3CH,25H,56H,0D6H N EQU$-ARRAY1DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX ;***********開(kāi)始排序***************

MOV CX,N-1

;設(shè)置外層循環(huán)計(jì)數(shù)器,CX中為排序的“遍數(shù)”(N-1);===================外層循環(huán)循環(huán)體開(kāi)始=============LOOP1:PUSH CX ;保存外循環(huán)計(jì)數(shù)器

MOV BX,0

;BX=整序元素在數(shù)組內(nèi)的位移,每一遍從第一個(gè)元素開(kāi)始;-------內(nèi)層循環(huán)循環(huán)體開(kāi)始,CX的值是內(nèi)層循環(huán)的次數(shù)------LOOP2:MOVAL,ARRAY1[BX] CMPAL,ARRAY1[BX+1] ;鄰元素比較

JLENEXT ;不需要整序,轉(zhuǎn)NEXT

XCHGAL,ARRAY1[BX+1] ;交換鄰元素位置

XCHGAL,ARRAY1[BX]NEXT:

INC BX ;修改指針

LOOP LOOP2 ;本遍未結(jié)束,轉(zhuǎn)LOOP2繼續(xù);----------內(nèi)層循環(huán)循環(huán)體結(jié)束---------------

POP CX ;恢復(fù)外層循環(huán)計(jì)數(shù)器

LOOP LOOP1 ;“遍數(shù)”未滿(mǎn),轉(zhuǎn)LOOP1繼續(xù);=============外層循環(huán)循環(huán)體結(jié)束================ MOV AX,4C00H INT 21HCODE ENDS END START【例3-11】有4名學(xué)生參加5門(mén)課程的考試,試計(jì)算每個(gè)學(xué)生的平均成績(jī)和每門(mén)課的平均成績(jī)。DATASEGMENT

GRADEDB80,95,76,83,92DB65,81,78,84,78DB90,86,96,100,83DB79,69,88,73,56 STUDB4DUP(?)

COURSEDB5DUP(?)DATAENDS

CODESEGMENT

ASSUMECS:CODE,DS:DATASTART:MOVAX,DATA MOVDS,AX

;*****************求每個(gè)學(xué)生的平均成績(jī)****************

MOVDI,4;設(shè)置外層循環(huán)計(jì)數(shù)器,DI中為學(xué)生人數(shù)

LEABX,GRADE;設(shè)置地址指針,BX指向成績(jī)表GRADELEASI,STU;設(shè)置地址指針,SI指向?qū)W生平均分表STU;===================外層循環(huán)循環(huán)體開(kāi)始=============

L11:MOVAX,0;累加器清0

MOVCX,5;設(shè)置內(nèi)層循環(huán)計(jì)數(shù)器,CX中為課程數(shù);-----------------內(nèi)層循環(huán)循環(huán)體開(kāi)始----------------

L22:ADDAL,[BX]ADCAH,0;累加,考慮可能的進(jìn)位

INCBX;修改地址指針

LOOPL22;內(nèi)層循環(huán)控制;------內(nèi)層循環(huán)循環(huán)體結(jié)束,AX中為某學(xué)生5門(mén)課總成績(jī)-----

MOVDL,5DIVDL;求平均值,保存在A(yíng)L中

MOV[SI],AL;保存平均值

INCSI;修改地址指針

DECDI;修改外層循環(huán)計(jì)數(shù)值DIJNZL11;外層循環(huán)控制;===================外層循環(huán)循環(huán)體結(jié)束=============;**************以下為求每門(mén)課的平均成績(jī)**************

LEADI,GRADE;設(shè)置地址指針,DI指向成績(jī)表GRADELEASI,COURSE;設(shè)置地址指針,SI指向課程平均分表COURSE;MOVDI,BXMOVCX,5;設(shè)置外層循環(huán)計(jì)數(shù)器,CX中為課程數(shù);===================外層循環(huán)循環(huán)體開(kāi)始=============

L01:PUSHCX;外層循環(huán)計(jì)數(shù)值CX入棧保護(hù)

MOVBX,DI;設(shè)置內(nèi)層循環(huán)地址指針

MOVAX,0;累計(jì)器清0MOVCX,4;設(shè)置內(nèi)曾循環(huán)計(jì)數(shù)器,CX中為學(xué)生數(shù);-----------------內(nèi)層循環(huán)循環(huán)體開(kāi)始----------------

L02:ADDAL,[BX]ADCAH,0;累加,考慮可能的進(jìn)位

ADDBX,5;修改地址指針,指向下一個(gè)學(xué)生本課程地址

LOOPL02;內(nèi)層循環(huán)控制;----內(nèi)層循環(huán)循環(huán)體結(jié)束,AX中為某門(mén)課4名學(xué)生的總成績(jī)----MOVDL,4DIVDL;求課程平均成績(jī),在A(yíng)L中

MOV[SI],AL;保存課程平均成績(jī)

INCSI;修改外層循環(huán)COURSE表地址指針

INCDI;修改外層循環(huán)GRADE表地址指針

POPCX;恢復(fù)外層循環(huán)計(jì)數(shù)值

LOOPL01;外層循環(huán)控制;===================外層循環(huán)循環(huán)體結(jié)束=============

MOVAX,4C00HINT21HCODEENDSENDSTART3.4子程序設(shè)計(jì)

子程序名 PROC [NEAR/FAR]

PUSH …… ;保護(hù)現(xiàn)場(chǎng)(寄存器/存儲(chǔ)器)

PUSH …… ;個(gè)數(shù)根據(jù)具體情況決定

…… ;子程序主體

……

POP …… ;恢復(fù)現(xiàn)場(chǎng),注意出棧次序

POP …… ;先進(jìn)棧的寄存器后出棧

RET ;返回

子程序名

ENDP子程序的基本格式設(shè)計(jì)一個(gè)子程序之前,首先應(yīng)該明確:子程序的名字;子程序的功能;入口參數(shù):主程序調(diào)用子程序時(shí),提供給子程序的參數(shù)出口參數(shù):子程序執(zhí)行結(jié)束返回給主程序的參數(shù)影響寄存器:執(zhí)行這個(gè)子程序會(huì)改變哪幾個(gè)寄存器的值?其它需要說(shuō)明的事項(xiàng)。上述內(nèi)容連同子程序源代碼等合稱(chēng)為“子程序文件”。常常把上述內(nèi)容以“程序注釋”的方式書(shū)寫(xiě)在一個(gè)子程序的首部。;名稱(chēng):Square;功能:求16Bit無(wú)符號(hào)數(shù)的平方根;入口參數(shù):16Bit無(wú)符號(hào)數(shù)在A(yíng)X中;出口參數(shù):8Bit平方根數(shù)在A(yíng)L中;影響寄存器:AX(AL)例3-12,一個(gè)名為“SQUARE”的子程序,用來(lái)求一個(gè)數(shù)的平方根,源程序如下:SQUARE PROC NEAR PUSH CX ;保護(hù)現(xiàn)場(chǎng)

PUSH BX

MOV BX,AX ;要求平方根的數(shù)送BX MOV AL,0 ;AL中存放平方根,初值0 MOV CX,1 ;CX置入第一個(gè)奇數(shù)1

;利用公式:N2=1+3+……+(2N-1)求平方根NEXT: SUB BX,CX JB DONE ADD CX,2 ;形成下一個(gè)奇數(shù)

INC AL ;AL存放已減去奇數(shù)的個(gè)數(shù)

JMP NEXTDONE: POP BX ;恢復(fù)現(xiàn)場(chǎng)

POP CX RET ;返回SQUARE ENDP子程序應(yīng)用每調(diào)用一次子程序,主程序需要做三件事:(1)為子程序準(zhǔn)備入口參數(shù)(2)調(diào)用子程序(3)處理子程序的返回參數(shù)DATA SEGMENTX DW 59,3500,139,199,77;欲求平方根的數(shù)組ROOT DB 5DUP(?)

;存放平方根內(nèi)存區(qū)DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX[例3-12]

求5個(gè)無(wú)符號(hào)數(shù)的平方根,主程序如下:

LEA BX,X ;初始化指針

LEA SI,ROOT MOV CX,5 ;設(shè)置計(jì)數(shù)器初值ONE: MOV AX,[BX] ;設(shè)置入口參數(shù)

CALL SQUARE ;調(diào)用子程序

MOV [SI],AL ;保存返回參數(shù)(平方根)

ADD BX,2 ;修改指針

INC SI ;修改指針

LOOP ONE ;循環(huán)控制

MOV AX,4C00H ;返回DOS INT 21H

主程序部分;名稱(chēng):Square;功能:求16Bit無(wú)符號(hào)數(shù)的平方根;入口參數(shù):16Bit無(wú)符號(hào)數(shù)在A(yíng)X中;出口參數(shù):8Bit平方根數(shù)在A(yíng)L中;影響寄存器:AX(AL)SQUARE PROC NEAR PUSH CX ;保護(hù)現(xiàn)場(chǎng)

PUSH BX

MOV BX,AX ;要求平方根的數(shù)送BX MOV AL,0 ;AL中存放平方根,初值0 MOV CX,1 ;CX置入第一個(gè)奇數(shù)1

;利用公式:N2=1+3+……+(2N-1)求平方根NEXT:

SUB BX,CX JB DONE ADD CX,2 ;形成下一個(gè)奇數(shù) INC AL ;AL存放已減去奇數(shù)的個(gè)數(shù) JMP NEXTDONE: POP BX ;恢復(fù)現(xiàn)場(chǎng) POP CX RET ;返回SQUARE

ENDPCODE ENDS

END

START子程序安排在主程序執(zhí)行終止返回DOS后的位置子程序編寫(xiě)注意事項(xiàng)⑴子程序要利用過(guò)程定義偽指令聲明⑵子程序最后利用RET指令返回主程序,主程序執(zhí)行CALL指令調(diào)用子程序⑶子程序中對(duì)堆棧的壓入和彈出操作要成對(duì)使用,保持堆棧的平衡⑷子程序開(kāi)始應(yīng)該保護(hù)使用到的寄存器內(nèi)容,子程序返回前相應(yīng)進(jìn)行恢復(fù)⑸子程序應(yīng)安排在代碼段的主程序之外,最好放在主程序執(zhí)行終止后的位置(返回DOS后、匯編結(jié)束END偽指令前),也可以放在主程序開(kāi)始執(zhí)行之前的位置子程序編寫(xiě)注意事項(xiàng)⑹子程序可以與主程序共用一個(gè)數(shù)據(jù)段,也可以使用不同的數(shù)據(jù)段(注意修改DS),還可以在子程序最后設(shè)置數(shù)據(jù)區(qū)(利用CS尋址)⑺子程序允許嵌套和遞歸⑼處理好子程序與主程序間的參數(shù)傳遞問(wèn)題⑽提供必要的子程序說(shuō)明信息【例3-13】含數(shù)據(jù)區(qū)的子程序;子程序HTOASC:將AL低4位表示的十六進(jìn)制數(shù)轉(zhuǎn)換為ASCII碼HTOASC proc pushbx movbx,offsetASCII andal,0fh xlatCS:ASCII

;換碼:AL←CS:[BX+AL] popbx

ret;數(shù)據(jù)區(qū)ASCII db30h,31h,32h,33h,34h,35h,36h,37h,38h,39h db41h,42h,43h,44h,45h,46hHTOASC endp【例3-14】

子程序嵌套示例,本例中子程序嵌套調(diào)用了例3-13子程序HTOASC。;入口參數(shù):AL中為要顯示輸出的二進(jìn)制數(shù)ALDISPPROC

PUSHAX;保護(hù)入口參數(shù)PUSHCX

PUSHAX;暫存數(shù)據(jù)

MOVCL,4SHRAL,CL;轉(zhuǎn)換AL的高4位

CALLHTOASC;子程序調(diào)用(嵌套)

POPAX;轉(zhuǎn)換AL的低4位

CALLHTOASC;子程序調(diào)用(嵌套)POPCXPOPAXRET;子程序返回ALDISPENDP【例3-15】子程序遞歸調(diào)用示例。編程計(jì)算N!,N!=N×(N-1)×(N-2)×…×2×1(N≥0)DATASEGMENT

NDW3 RESULTDW? ;保存結(jié)果DATAENDSCODESEGMENT ASSUMECS:CODE,DS:DATASTART:MOVAX,DATA MOVDS,AX

PUSHN ;入口參數(shù)N入棧

CALLFACT ;子程序FACT調(diào)用,求N!

POPRESULT ;出口參數(shù)彈出至RESULT MOVAX,4C00H ;返回DOS INT21H主程序部分;入口參數(shù):N壓入堆棧(采用堆棧傳遞參數(shù));出口參數(shù):N!值在棧頂FACTPROC

PUSHAX PUSHBP PUSHDX

MOVBP,SP MOVAX,[BP+8] ;從堆棧中取入口參數(shù)

CMPAX,0 ;比較入口參數(shù)是否為0

JNEFACT1 ;不為0,則轉(zhuǎn)遞歸調(diào)用控制

INCAX ;如果為0,設(shè)置出口參數(shù)為0!=1

JMPFACT2子程序部分FACT1:DECAX ;設(shè)置求(N-1)!的入口參數(shù)值

PUSHAX ;入口參數(shù)入棧

CALLFACT ;遞歸調(diào)用,求(N-1)!

POPAX ;出口參數(shù)彈出至AX

MULWORDPTR[BP+8] ;求(N)!=N×(N-1)!FACT2:MOV[BP+8],AX

;設(shè)置出口參數(shù),假定N!不會(huì)超出AX的表示范圍 POPDX POPBP POPAX

RETFACTENDPCODEENDS ENDSTART子程序部分多出口子程序;子程序HTOASC:將AL低4位表示的十六進(jìn)制數(shù)轉(zhuǎn)換為ASCII碼HTOASC proc andal,0fh cmpal,9 jbehtoasc1 addal,37h ;是A~F,加37H ret ;子程序返回htoasc1: addal,30h ;是0~9,加30H

ret ;子程序返回HTOASC endp子程序的參數(shù)傳遞主程序與子程序間一個(gè)主要問(wèn)題是參數(shù)傳遞入口參數(shù)(輸入?yún)?shù)):主程序調(diào)用子程序時(shí),提供給子程序的參數(shù)出口參數(shù)(輸出參數(shù)):子程序執(zhí)行結(jié)束返回給主程序的參數(shù)參數(shù)的具體內(nèi)容傳數(shù)值:傳送數(shù)據(jù)本身傳地址:傳送數(shù)據(jù)的主存地址常用的參數(shù)傳遞方法寄存器共享變量堆棧1.用寄存器傳遞參數(shù)最簡(jiǎn)單和常用的參數(shù)傳遞方法是通過(guò)寄存器,只要把參數(shù)存于約定的寄存器中就可以了由于通用寄存器個(gè)數(shù)有限,這種方法對(duì)少量數(shù)據(jù)可以直接傳遞數(shù)值,而對(duì)大量數(shù)據(jù)只能傳遞地址采用寄存器傳遞參數(shù),注意帶有出口參數(shù)的寄存器不能保護(hù)和恢復(fù),帶有入口參數(shù)的寄存器可以保護(hù)、也可以不保護(hù),但最好能夠保持一致2.用共享變量傳遞參數(shù)子程序和主程序使用同一個(gè)變量名存取數(shù)據(jù)就是利用共享變量(全局變量)進(jìn)行參數(shù)傳遞如果變量定義和使用不在同一個(gè)源程序中,需要利用PUBLIC、EXTRN聲明如果主程序還要利用原來(lái)的變量值,則需要保護(hù)和恢復(fù)利用共享變量傳遞參數(shù),子程序的通用性較差,但特別適合在多個(gè)程序段間、尤其在不同的程序模塊間傳遞數(shù)據(jù)3.用堆棧傳遞參數(shù)參數(shù)傳遞還可以通過(guò)堆棧這個(gè)臨時(shí)存儲(chǔ)區(qū)。主程序?qū)⑷肟趨?shù)壓入堆棧,子程序從堆棧中取出參數(shù);子程序?qū)⒊隹趨?shù)存入堆棧,主程序彈出堆棧取得它們采用堆棧傳遞參數(shù)是程式化的,它是編譯程序處理參數(shù)傳遞、以及匯編語(yǔ)言與高級(jí)語(yǔ)言混合編程時(shí)的常規(guī)方法【例3-16】編程采用子程序結(jié)構(gòu)實(shí)現(xiàn)數(shù)組元素求和DATASEGMENT

ARY1DW1,2,3,4,5,6,7,8,9,10COUNT1DW($-ARY1)/2 ;ARY1元素個(gè)數(shù)

SUM1DW?DATAENDS入口參數(shù): 數(shù)組的邏輯地址(傳址) 元素個(gè)數(shù)(傳值)出口參數(shù): 求和結(jié)果(傳值)

;設(shè)置入口參數(shù)(含有DS←數(shù)組的段地址)

MOVBX,OFFSETARY1 ;BX←數(shù)組的偏移地址

MOVCX,COUNT1 ;CX←數(shù)組的元素個(gè)數(shù)

CALLPROADD1 ;調(diào)用求和子程序

MOVSUM1,AX ;處理出口參數(shù)

主程序1、通過(guò)寄存器傳遞參數(shù);子程序名:PROADD1;功能:求字?jǐn)?shù)組各元素之和;入口參數(shù):

DS:BX=數(shù)組的段地址:偏移地址

CX=元素個(gè)數(shù),

;出口參數(shù):

AX=數(shù)組元素和;影響寄存器:AX子程序PROADD1PROC

PUSHCX

PUSHBX

XORAX,AX ;累加器清0

SUMA:

ADDAX,[BX] ;求和

INCBX;修改地址指針,指向下一個(gè)數(shù)據(jù)

INCBX

LOOPSUMA

POPBX POPCX

RETPROADD1ENDPdatasegmentary1dw1,2,3,4,5,6,7,8,9,10count1dw($-ARY1)/2sum1dw?ary2dw10,20,30,40,50,60,70,80,90,100count2dw($-ARY2)/2sum2dw?dataends2.通過(guò)共享變量傳遞參數(shù)datasegmentary1dw1,2,3,4,5,6,7,8,9,10count1dw($-ARY1)/2sum1dw?

ary2dw10,20,30,40,50,60,70,80,90,100count2dw($-ARY2)/2sum2dw?

tabledw3dup(?);地址表dataends累加數(shù)組中的元素(地址表)codesegmentassumecs:code,ds:datastart:pushdssubax,axpushaxmovax,datamovds,ax

movtable,offsetary1movtable+2,offsetcoun

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論