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

下載本文檔

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

文檔簡介

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

編制匯編語言程序的步驟:(1)分析題意,確定算法(2)根據(jù)算法畫出程序框圖(3)根據(jù)框圖編寫程序(4)上機調(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):程序按照它編寫的順序執(zhí)行,每條指令只執(zhí)行一

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

MOVXCODE,AL ;保存

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

cmpal,0

jgenonneg

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

negal

;條件不滿足,求補nonneg:

movresult,al

;條件滿足

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

cmpal,0

jlyesneg

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

jmpnonnegyesneg:

negal

;條件滿足,求補nonneg:

movresult,al

;條件不滿足3.2.2雙分支結(jié)構(gòu)條件成立跳轉(zhuǎn)執(zhí)行第2個分支語句體,否則順序執(zhí)行第1個分支語句體注意第1個分支體后一定要有一個JMP指令跳到第2個分支體后【例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

;一定要跳過另一個分支體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

;一定要跳過另一個分支體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 ;顯示編寫分支程序,需留心分支的開始和結(jié)束顯示BX的最高位(無分支)

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 ;顯示大小寫字母轉(zhuǎn)換

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

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

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

jadisp

subdl,20h

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

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)如果可供選擇的程序塊多于兩個,這樣的結(jié)構(gòu)稱為多分支選擇結(jié)構(gòu),如下圖(a)所示,下圖(b)是匯編語言程序的實現(xiàn)方法。【例3?5】編程實現(xiàn)符號函數(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]從鍵盤上輸入數(shù)字“1”到“3”,根據(jù)輸入選擇對應(yīng)程序塊執(zhí)行。INPUT: LEA DX,PROMPT MOV AH,9 INT 21H ;輸出提示信息

MOV AH,1 INT 21H ;輸入一個數(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用地址表實現(xiàn)多分支START:MOVAX,DATA MOV DS,AXINPUT:LEA DX,PROMPT MOV AH,9 INT 21H ;顯示提示信息

MOV AH,1 INT 21H ;輸入一個數(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] ;相對尋址,轉(zhuǎn)移到對應(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è)計

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

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

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

控制部分:判斷循環(huán)條件,確定結(jié)束或繼續(xù)循環(huán)。(3)結(jié)束部分:用來分析和存放程序的結(jié)果。(2)循環(huán)體部分兩種結(jié)構(gòu)的循環(huán):WHILE循環(huán):先判斷循環(huán)條件,條件滿足則進入循環(huán),循環(huán)次數(shù)最少為0次。DO-WHILE循環(huán):先執(zhí)行工作部分,然后判斷循環(huán)條件,條件滿足則轉(zhuǎn)向工作部分繼續(xù)循環(huán),循環(huán)次數(shù)最少1次。計數(shù)循環(huán):循環(huán)的次數(shù)事先已知,用一個變量(寄存器或存儲 器單元)記錄循環(huán)的次數(shù)(稱為“循環(huán)計數(shù)器”)。條件循環(huán):循環(huán)的次數(shù)事先并不確定,根據(jù)某個條件是否滿足 來決定是否繼續(xù)循環(huán)。按照循環(huán)結(jié)束的條件,有以下兩類循環(huán):用循環(huán)計數(shù)器的值來控制循環(huán),也可以結(jié)合其它條件共同控制。[例]從鍵盤上輸入一個字符串(不超過80個字符),將它逆序后輸出。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 ;輸入字符個數(shù)送CX(循環(huán)次數(shù)) ADD BX,CX

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

DEC BX ;修改指針

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

MOV AX,4C00H INT 21HCODE ENDS END START【例3-7】字節(jié)數(shù)組ARRAY存放有10個有符號數(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ù)組第一個元素預(yù)設(shè)為最大數(shù)初值

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

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

BX

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

CMPAL,[BX];比較

JGENEXT

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

MOVAL,[BX]

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

;計數(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é)束,求這個字符串的長度(字符個數(shù))

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

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

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

INC SI ;修改指針

INC CX ;計數(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

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

INC CX ;計數(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的累加和,直到累加和超過1000為止。統(tǒng)計被累加的自然數(shù)個數(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)計累加自然數(shù)個數(shù),清0

LP:

INCBX;BX加1

ADDAX,BX;求累加和

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

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

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

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

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

MOVAX,BX XORDL,DL

L: ANDAX,AX

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

JZEXIT

;循環(huán)控制

SALAX,1

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

JNCL

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

INCDL

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

JMPL

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

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

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

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

;將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 ;字符串長度30L0: INC SI

;修改指針

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

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é)束時ZF=1,SI內(nèi)是字符的出

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

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

MOVCX,MAGAIN:

……

PUSHCXMOVCX,NNEXT:……LOOPNEXT……

POPCX

LOOPAGAIN

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

……

DECDIJNZAGAIN【例3-10】有符號字節(jié)元素數(shù)組存有N個有符號數(shù),要求將這N個數(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 ;***********開始排序***************

MOV CX,N-1

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

MOV BX,0

;BX=整序元素在數(shù)組內(nèi)的位移,每一遍從第一個元素開始;-------內(nèi)層循環(huán)循環(huán)體開始,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)計數(shù)器

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

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

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

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

L11:MOVAX,0;累加器清0

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

L22:ADDAL,[BX]ADCAH,0;累加,考慮可能的進位

INCBX;修改地址指針

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

MOVDL,5DIVDL;求平均值,保存在AL中

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

INCSI;修改地址指針

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

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

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

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

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

L02:ADDAL,[BX]ADCAH,0;累加,考慮可能的進位

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

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

MOV[SI],AL;保存課程平均成績

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

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

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

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

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

子程序名 PROC [NEAR/FAR]

PUSH …… ;保護現(xiàn)場(寄存器/存儲器)

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

…… ;子程序主體

……

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

POP …… ;先進棧的寄存器后出棧

RET ;返回

子程序名

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

PUSH BX

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

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

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

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

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個無符號數(shù)的平方根,主程序如下:

LEA BX,X ;初始化指針

LEA SI,ROOT MOV CX,5 ;設(shè)置計數(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

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

PUSH BX

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

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

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

ENDPCODE ENDS

END

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

PUSHAX;保護入口參數(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)用示例。編程計算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!不會超出AX的表示范圍 POPDX POPBP POPAX

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

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

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

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

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

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

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

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

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

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

CX=元素個數(shù),

;出口參數(shù):

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

PUSHCX

PUSHBX

XORAX,AX ;累加器清0

SUMA:

ADDAX,[BX] ;求和

INCBX;修改地址指針,指向下一個數(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.通過共享變量傳遞參數(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. 本站所有資源如無特殊說明,都需要本地電腦安裝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)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論