版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 27728.3-2024濕巾及類似用途產(chǎn)品第3部分:消毒濕巾專用要求
- 大學(xué)生兼職勞動合同書2
- 聯(lián)機手環(huán)測量儀器項目運營指導(dǎo)方案
- 電動鋸商業(yè)機會挖掘與戰(zhàn)略布局策略研究報告
- 沖床金屬加工用產(chǎn)品供應(yīng)鏈分析
- 電動指甲刀商業(yè)機會挖掘與戰(zhàn)略布局策略研究報告
- 眉刷商業(yè)機會挖掘與戰(zhàn)略布局策略研究報告
- 自動電話交換機商業(yè)機會挖掘與戰(zhàn)略布局策略研究報告
- 粉餅盒用粉芯項目運營指導(dǎo)方案
- 空手道用護腿板項目運營指導(dǎo)方案
- 天津市紅橋區(qū)2024-2025學(xué)年八年級上期中-生物試卷
- GB/T 11017.2-2024額定電壓66 kV(Um=72.5 kV)和110 kV(Um=126 kV)交聯(lián)聚乙烯絕緣電力電纜及其附件第2部分:電纜
- 生 物2024-2025學(xué)年人教版生物七年級上冊期中模擬生物試卷
- 5.4+環(huán)境參與調(diào)節(jié)植物的生命活動課件高二上學(xué)期生物人教版(2019)選擇性必修1
- 7.2 共建美好集體(課件)-2024-2025學(xué)年七年級道德與法治上冊 統(tǒng)編版
- 2023-2024學(xué)年全國初中八年級上歷史人教版期中考試試卷(含答案解析)
- 2023-2024學(xué)年北京西城區(qū)三十五中高一(上)期中化學(xué)試題及答案
- 廣東省深圳市(2024年-2025年小學(xué)三年級語文)統(tǒng)編版質(zhì)量測試(上學(xué)期)試卷(含答案)
- (高清稿)DB44∕T 2494-2024 河道水域岸線保護與利用規(guī)劃編制技術(shù)規(guī)程
- 兒童青少年視力普查規(guī)范
- 汽車修理工勞動合同三篇
評論
0/150
提交評論