版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
主要內(nèi)容:系統(tǒng)功能調(diào)用簡介1、MS-DOS設(shè)置了幾十個內(nèi)部子程序,可以完成I/O設(shè)備管理,存儲管理,文件管理,進(jìn)程管理.它們被做成中斷服務(wù)程序,其入口地址已由系統(tǒng)置入中斷向量表中,可以用軟中斷指令調(diào)用.2、類型號:20~27H3、系統(tǒng)功能調(diào)用:INT21HDOS系統(tǒng)功能調(diào)用1.DOS系統(tǒng)功能調(diào)用格式
1)在AH中設(shè)置功能號
2)在指定的寄存器中設(shè)置入口參數(shù)
3)用INT21H指令執(zhí)行系統(tǒng)功能調(diào)用
4)根據(jù)出口參數(shù)分析執(zhí)行情況2.DOS系統(tǒng)功能調(diào)用INT21H的部分I/O操作
1).鍵盤輸入一個字符并回顯計算機(jī)等待從標(biāo)準(zhǔn)輸入設(shè)備(主要指鍵盤)輸入,直到按下一個鍵。如果按下的是數(shù)字、字母等可用ASCII碼表示的字符,則這個字符就被送到屏幕顯示,并把其對應(yīng)的ASCII碼值送到AL寄存器。如果按下Tab制表鍵,則光標(biāo)通過添加空格。如按下的鍵是組合的Ctrl-Break兩鍵,則執(zhí)行23H的中斷而退出命令執(zhí)行。功能號AH=01H,出口參數(shù)
AL=字符;使用格式:MOVAH,01HINT21HEx2.asm2).鍵盤輸入字符到緩沖區(qū):
功能號:AH=0AH,入口參數(shù):DS:DX=緩沖區(qū)首址
(DS:DX)=緩沖區(qū)最大字符數(shù)
(DS:DX+1)=緩沖區(qū)實際輸入字符數(shù)
(AL)=00有輸入
(AL)=FF無輸入從鍵盤接收字符串存入內(nèi)存。要求事先定義一個輸入緩沖區(qū),它的始址放于DS:DX,第一個字節(jié)指出緩沖區(qū)能容納的最大字符數(shù)(1~255),不能為零,該值由用戶設(shè)置;第二字節(jié)保留以用作由D0S返回實際讀入的字符數(shù)(回車除外);從第三個字節(jié)開始存放從鍵盤上接收的字符。若實際輸入的字符數(shù)少于定義的字節(jié)數(shù),緩沖區(qū)內(nèi)其余字節(jié)填零;若多于定義的字節(jié)數(shù),則后來輸入的字符丟掉并且響鈴。DOS還自動在輸入字符串的末尾加上回車字符,然而這個回車字符未被計入由DOS填到第二個輔助字節(jié)內(nèi)的數(shù)目之中。因此,在設(shè)立輸入緩沖區(qū)最大尺寸時要比所希望輸入的字節(jié)數(shù)多一個字節(jié)。Ex3.asm
3).輸出一個字符功能號
:AH=2
入口參數(shù):DL=字符,光標(biāo)隨字符移動
使用格式:MOVDL,‘A’MOVAH,02HINT21H
執(zhí)行上面程序后,將在屏幕上顯示字符A.Ex4.asm4).輸出字符串,功能號:AH=9,
入口參數(shù):DS:DX=串地址,字串結(jié)束為“$”符號
使用格式:BUFDB‘HELLO!’
……MOVDX,OFFSETBUFMOVAH,09HINT21H
……….Ex5.asm4.5.4DOS系統(tǒng)功能調(diào)用:I/O5)鍵盤輸入一個字符無回顯,支持CTRL_BREAK,CTRL_C檢查處理。功能號:AH=08H
出口參數(shù):AL=字符;6)返回DOS系統(tǒng)功能號:AH=4CH7)清鍵盤緩沖區(qū),并調(diào)用一種鍵盤功能功能號:AH=0CHAL=鍵盤功能號(1、7、8、0AH)
第5章循環(huán)與分支程序設(shè)計編制一個匯編程序的步驟:分析題意,確定算法。這一步是能否編制出高質(zhì)量程序的關(guān)鍵,因此不應(yīng)該一拿到題目就急于寫程序,而是應(yīng)該仔細(xì)地分析和理解題意,找出合理的算法及適當(dāng)?shù)臄?shù)據(jù)結(jié)構(gòu)。根據(jù)算法畫出程序框圖。這樣可以減少出錯的可能性。畫框圖時可以由粗到細(xì)把算法逐步地具體化。根據(jù)框圖編寫程序。上機(jī)調(diào)試程序。任何程序必須經(jīng)過調(diào)試才能檢查出你的設(shè)計思想是否正確以及你的程序是否符合你的設(shè)計思想,結(jié)果是否正確。5.1順序結(jié)構(gòu)程序
例1:自然數(shù)0~15的平方表,存在內(nèi)存TABLE開始的連續(xù)16個單元中,現(xiàn)XAD單元存有任意一自然數(shù)(0X<15),查表求X的平方,存入YAD單元中。X2
的值的地址:TABLE表的首地址+Xdatasegmenttabledb0,1,4,9,16,25,36,49,64,81db100,121,144,169,196,225xaddb3yaddb?dataendscodesegmentassumecs:code,ds:data,ss:stackstartprocfarpushds;將DS入棧
movax,0000h;AX置零
pushax;將0入棧
movax,data;初始化DSmovds,ax
movbx,offsettable;表的首址送BXmovah,0;AH送0moval,xad;將X送ALaddadd bx,ax;求X平方值的地址moval,byteptr[bx];X平方值送ALmovyad,almovah,4chint21hstartendpcodeendsendstart例2:編程求y=((a+b)*c-d)/e其中a、b、c、d、e依次放在VARA、VARB、VARC、VARD、VARE單元開始的內(nèi)存中,結(jié)果存放在VARY單元中。
DATA SEGMEN;定義數(shù)VARA DW6 ;a=6VARB DW7 ;b=7VARC DW8 ;c=8VARD DW9 ;d=9VARE DW10 ;e=10VARY DW? ;yDATA ENDSSTACK SEGMENT;定義堆棧段DW20HDUP(?)STACK ENDSCODE SEGMENT;定義代碼段START PROCFARASSUMECS:CODE,DS:DATA,SS:STACKBEGIN: PUSH DSMOV AX,0 ;DS:00壓棧PUSH AXMOV AX,DATAMOV DS,AX ;置數(shù)據(jù)段MOV AX,VARAADD AX,VARB;a+b
IMUL VARC ;(a+b)*cMOVCX,AXMOVBX,DXMOV AX,VARD;(a+b)*c-dCWDSUBCX,AXSBBBX,DXMOVAX,CXMOVDX,BXIDIV VARE ;((a+b)*c-d)/eMOV VARY,AXRETSTARTENDPCODEENDSEND BEGIN5.2分支結(jié)構(gòu)程序設(shè)計1.分支程序的結(jié)構(gòu)形式分支程序結(jié)構(gòu)可以有兩種形式4.5.2分支結(jié)構(gòu)程序IF_THEN_ELSE語句和CASE語句。IF_THEN_ELSE語句可以引出兩個分支,CASE語句則可以引出多個分支,不論哪一種形式,在某一種確定條件下,只能執(zhí)行多個分支中的一個分支。1:符號函數(shù):DATA SEGMENT;定義數(shù)據(jù)段XX DB 10YY DB ?DATA ENDSCODE SEGMENT;定義代碼段ASSUME CS:CODE,DS:DATASTART PROC FARBEGIN: PUSH DS;DS:00壓棧MOV AX,0PUSH AXMOV AX,DATAMOV DS,AX ;置數(shù)據(jù)段MOV AL,XX ;AL=XXCMP AL,0 ;AL與0比較JGE BIGR ;大于,等于轉(zhuǎn)BIGRMOV AL,0FFH ;AL=-1JMP EQUT ;轉(zhuǎn)EQUTBIGR: JE EQUT;等于0,轉(zhuǎn)EQUTMOV AL,01 ;AL=1EQUT: MOV YY,AL ;符號函數(shù)的結(jié)果存入YY單元RETSTART ENDPCODE ENDSEND BEGIN2:
某車站需編寫一個計算行李托運(yùn)費(fèi)的程序,其要求為:
其中G為托運(yùn)質(zhì)量,當(dāng)G=0時,退出程序,G>60Kg不受理。程序:DATA SEGMENT ;定義數(shù)據(jù)段XX DW25 ;設(shè)托運(yùn)質(zhì)量為25KgYY DW?DATA ENDSSTACK SEGMENTPARASTACK;定義堆棧段
DW50hDUP(?)STACK ENDSCODE SEGMENT ;定義代碼段START PROCFAR ASSUMECS:CODE,DS:DATA,SS:STACKDEGIN: PUSH DS MOV AX,0 ;DS:00壓棧
PUSH AX MOV AX,DATA MOV DS,AX ;置數(shù)據(jù)段
MOV AX,XX ;取托運(yùn)質(zhì)量
CMP AX,0 ;AX與0比較是否大于
JLE EXIT ;小于、等于轉(zhuǎn)EXIT CMP AX,20 ;質(zhì)量是否大于20Kg JLE OK ;小于、等于轉(zhuǎn)OK
CMP AX,40 ;質(zhì)量是否大于40Kg JG LAB ;大于轉(zhuǎn)LAB SUB AX,20 ;G-20 MUL 2 ;(G-20)*2 ADD AX,20 ;(G-20)*2+20 JMP OK ;轉(zhuǎn)OKLAB: CMPAX,60 ;質(zhì)量是否大于60Kg JG EXIT ;大于60Kg轉(zhuǎn)EXIT SUB AX,40 ;(G-40) MUL 3 ;(G-40)*3 ADDAX,60 ;(G-40)*3+60OK: MOV YY,AX ;托運(yùn)費(fèi)存入YY中EXIT: RETSTART ENDPCODE ENDS ENDBEGIN3根據(jù)AL中的被放置位的情況控制轉(zhuǎn)移到8個子程序(R1~R8)中的一個: 若AL為 00000001 則轉(zhuǎn)移至R1; 若AL為 00000010 則轉(zhuǎn)移至R2; 若AL為 00000100 則轉(zhuǎn)移至R3; 若AL為 00001000 則轉(zhuǎn)移至R4; 若AL為 00010000 則轉(zhuǎn)移至R5; 若AL為 00100000 則轉(zhuǎn)移至R6; 若AL為 01000000 則轉(zhuǎn)移至R7; 若AL為 10000000 則轉(zhuǎn)移至R8。分析:實現(xiàn)CASE結(jié)構(gòu)時,可以使用跳躍表法,使程序能根據(jù)不同的條件轉(zhuǎn)移到多個程序分支中去。變址尋址方式、寄存器間接尋址方式、基址變址尋址方式實現(xiàn)跳躍表法的程序。DATA SEGMENT ;定義數(shù)據(jù)段BRTAB DW R11 ;子程序R1入口偏移地址,段地址
DW R21 DW R31 DW R41 DW R51 DW R61 DW R71 DW R81DATA ENDSSTACK SEGMENT PARASTACK‘STACK’
;定義堆棧段DB 100DUP(?)TOP EQU $-STACKSTACK ENDSCODE SEGMENT ;定義代碼段START PROC FAR ASSUME CS:CODE,DS:DATA,SS:STACKDEGIN: PUSH DS MOV AX,0 ;DS:00壓棧
PUSH AX ;使程序能返回DOS MOV AX,DATA MOV DS,AX ;置數(shù)據(jù)段
MOV AX,STAC MOV SS,AX ;置堆棧段
MOV AX,TOP MOV SP,AX ;置棧頂指針
LEA BX,BRTAB ;BX指向跳轉(zhuǎn)表GTBIT: RCR AL,1 JC GETAD ;順序檢查AL中各位的狀態(tài)
INC BX ;BX加2,指向跳轉(zhuǎn)表中
INC BX ;下一個子程序地址
JMP GTBITGETAD:JMP DWORDPTR[BX] ;轉(zhuǎn)移到相應(yīng)的子程序
START ENDP CODE ENDS END BEGIN基址變址尋址方式lea
bx,branch_tablemov
si,7*typebranch_table
mov
cx,8
;循環(huán)次數(shù)8送cxl: shl
al,1
;把a(bǔ)l邏輯左移1位
jnb
not_yet
;CF=0轉(zhuǎn)到not_yetjmp
wordptr[bx][si]
;CF=1轉(zhuǎn)到相應(yīng)程序分支not_yet:sub
si,typebranch_table;修改地址loop
l
;循環(huán)4、在附加段中,有一個按從小到大順序排列的無符號數(shù)數(shù)組,其首地址存放在DI寄存器中,數(shù)組中的第一個單元存放著數(shù)組長度。在AX中有一個無符號數(shù),要求在數(shù)組中查找(AX),如找到,則使CF=0,并在SI中給出該元素在數(shù)組中的偏移地址;如未找到,則使CF=1。
折半查找算法:折半查找法先取有序數(shù)組的中間元素與查找值相比較,如相等則查找成功;如查找值大于中間元素,則再取高半部的中間元素與查找值相比較;如查找值小于中間元素,則再取低半部的中間元素與查找值相比較;如此重復(fù)直到查找成功或最終未找到該數(shù)(查找不成功)為止。折半查找法的效率高于順序查找法,對于長度為N的表格,順序查找法平均要作N/2次比較,而折半查找法的平均比較次數(shù)為log2N。所以,如果數(shù)組長度為100,則順序查找法平均要作50次比較,而折半查找法平均作7次比較就可以了。
初始化被查找數(shù)組的首尾下標(biāo),low=1,high=n若low>high,則查找失敗,置CF=1,退出程序。否則,計算中點:mid=(low+high)/2K與中點元素r[mid]比較。若k=r[mid],則查找成功,程序結(jié)束;若k<r[mid],則跳轉(zhuǎn)步驟3;若k>r[mid],則轉(zhuǎn)步驟4低半部分查找(lower),high=mid-1返回步驟2繼續(xù)查找。高半部分查找(higher),low=mid+1返回步驟2繼續(xù)查找。
dseg segment low_idx dw ? high_idx dw ? dseg ends cseg segmentb_search proc near assume cs:cseg,ds:dseg,es:dseg push ds push ax mov ax,dseg mov ds,ax mov es,ax pop ax cmp ax,es:[di+2] ja chk_last lea si,es:[di+2] je exit stc jmp exitchk_last:
mov si,es:[di]
shl si,1
add si,di
cmp ax,es:[si]
jb search
je exit
stc
jmp exitsearch:
mov low_idx,1
mov bx,es:[di]
mov high_idx,bx
mov bx,dimid:
mov cx,low_idx
mov dx,high_idx
cmp cx,dx
ja no_match
add cx,dx
shr cx,1
mov si,cx
shl si,1compare:
cmp ax,es:[bx+si]
je exit
ja higher
dec cx
mov high_idx,cx
jmp midhigher:
inc cx
mov low_idx,cx
jmp midno_match:
stcexit: pop ds
retb_search endp cseg ends end5.3循環(huán)結(jié)構(gòu)程序設(shè)計1、循環(huán)程序的結(jié)構(gòu)形式DO_WHILE結(jié)構(gòu)形式。
DO_WHILE結(jié)構(gòu)把對循環(huán)控制條件的判斷放在循環(huán)的入口,先判斷條件,滿足條件就執(zhí)行循環(huán)體,否則則退出循環(huán)。
DO_UNTIL結(jié)構(gòu)形式。
先執(zhí)行循環(huán)體然后再判斷條件,不滿足則繼續(xù),否則退出循環(huán)。
4.5.3循環(huán)結(jié)構(gòu)程序循環(huán)結(jié)構(gòu)程序設(shè)計(2)循環(huán)程序的結(jié)構(gòu)形式流程圖:
循環(huán)結(jié)構(gòu)程序設(shè)計(3)循環(huán)程序由三部分組成:設(shè)置循環(huán)的初始狀態(tài)。設(shè)置循環(huán)次數(shù)的計數(shù)值,以及循環(huán)體正常工作而建立的初始狀態(tài)等。(2)循環(huán)體。由循環(huán)的工作部分及修改部分組成,循環(huán)的工作部分是為完成程序功能而設(shè)計的主要程序段,循環(huán)的修改部分則是為保證每一次重復(fù)(循環(huán))時,參加執(zhí)行的信息能發(fā)生有規(guī)律的變化而建立的程序段。(3)循環(huán)控制部分。每個循環(huán)程序必須選擇一個循環(huán)控制條件來控制循環(huán)的運(yùn)行和結(jié)束。循環(huán)結(jié)構(gòu)程序設(shè)計(4)例1求S=1+2+3+…+100DATA SEGMENT;定義數(shù)據(jù)段
MAX DW100 SUM DW ?DATA ENDSSTACK SEGMENTPARASTACK ;定義堆棧段
DW20HDUP(?)STACK ENDSCODE SEGMENT;定義代碼段START PROC FARASSUMECS:CODE,DS:DATA,SS:STACKBEGIN: PUSH DS ;DS壓棧
MOV AX,0 PUSH AX;00壓棧
MOV AX,DATA MOV DS,AX ;置數(shù)據(jù)段
MOV AX,0;累加器清0 MOV CX,MAX;循環(huán)控CX=MAX MOV BX,1;初始加數(shù)用1AGAIN: ADD AX,BX;累加求和
INC BX ;下一個數(shù)
LOOP AGAIN;循環(huán)轉(zhuǎn)AGAIN MOV SUM,AX ;求和結(jié)果存SUM中
RET STARTENDP CODE ENDS ENDBEGIN循環(huán)結(jié)構(gòu)程序設(shè)計(5)例2求N!DATA SEGMENT;定義數(shù)據(jù)段
N DW5 YY DW?DATA ENDSSTACK SEGMENT;定義堆棧段
DW 50HDUP(?)STACK ENDSCODE SEGMENT ;定義代碼段START PROCFARASSUME CS:CODE,DS:DATA,SS:STACKBEGIN: PUSH DS;DS壓棧
MOV AX,0 PUSH AX ;00壓棧
MOV AX,DATA MOV DS,AX ;置數(shù)據(jù)段
MOV AX,N ;AX=N CMP AX,0;比較是否為0 JNE NOZ ;非0轉(zhuǎn)NOZ INC AX ;0則AX=1 JMP EXIT ;轉(zhuǎn)EXITNOZ: MOV BX,AX ;BX=AX=N MOV AX,1;累積AX=1AGAIN: MUL BX;相乘AX*BX->AX DEC BX;BX減1 JNE AGAIN;非0繼續(xù)EXIT: MOV YY,AX;保存N!結(jié)果到Y(jié)Y中
RETSTART ENDPCODE ENDSEND BEGIN循環(huán)結(jié)構(gòu)程序設(shè)計(6)例3:求2+4+6+…直到和剛大于500,保存實際和及項數(shù)nDATA SEGMENT;定義數(shù)據(jù)段
VARA DW500 ;min VARB DW? VARC DW?DATA ENDSSTACK SEGMENT;定義堆棧段
DW20HDUP(?)STACK ENDSCODE SEGMENT ;定義代碼段START PROC FAR ASSUMECS:CODE,DS:DATA,SS:STACKBEGIN: PUSH DS ;DS壓棧
MOV AX,0 PUSH AX ;0壓棧
MOV AX,DATA MOV DS,AX MOV DX,VARA MOV AX,0;累加器清0 MOV BX,2;加數(shù)初值
MOV CX,0;項數(shù)記錄CXAGAIN: ADD AX,BX;求和
INC CX ;項數(shù)記錄CX加1 INC BX INC BX ;加數(shù)加2 CMP AX,DX ;是否大于VARA JGE EXIT ;大于、等于轉(zhuǎn)
JMP AGAIN ;否則,繼續(xù)EXIT: MOV VARB,AX;保存和
MOV VARC,CX;保存項數(shù)n RETSTART ENDPCODE ENDSEND BEGIN循環(huán)結(jié)構(gòu)程序設(shè)計(7)例4試編制一個程序把BX寄存器內(nèi)的二進(jìn)制數(shù)用十六進(jìn)制數(shù)的形式在屏幕上顯示出來。循環(huán)結(jié)構(gòu)程序設(shè)計(9)PROGNAM SEGMENT ;代碼段定義MAIN PROCFAR ;主程序
ASSUMECS:PROGNAMSTART: PUSH DS SUB AX,AX ;DS:00壓棧
PUSH AX MOV CH,4 ;CH循環(huán)次數(shù)ROTATE:MOV CL,4 ;每次循環(huán)輸出一位十六進(jìn)制數(shù)
ROL BX,CL ;即移位4個二進(jìn)制位
MOV AL,BL ;AL=BL AND AL,0FH ;取低4位
ADD AL,30H ;轉(zhuǎn)變?yōu)锳SCII碼
CMP AL,3AH ;是否為’0’-‘9’ JL PRINTIT;是轉(zhuǎn)PRINTIT ADD AL,7H ;否轉(zhuǎn)為’A’-‘F’PRINTIT:MOV DL,AL ;DL=輸出字符
MOV AH,2 INT 21H ;調(diào)用DOS中斷,顯示字符
DEC CH JNZ ROTATE ;沒循環(huán)結(jié)束,繼續(xù)
RET ;返回MAIN ENDPPROGNAM ENDSEND START循環(huán)結(jié)構(gòu)程序設(shè)計(10)例5:在ADDR單元中存放著數(shù)Y的地址,試編制一程序把Y中1的個數(shù)存入COUNT單元中。程序框圖循環(huán)結(jié)構(gòu)程序設(shè)計(11)DATAREASEGMENT ;數(shù)據(jù)段定義ADDR DWNUMBERNUMBER DWYCOUNT DW?DATAREAENDSPROGNAM SEGMENT;代碼段定義MAIN PROCFAR ASSUMECS:PROGNAM,DS:DATAREASTART: PUSH DS SUB AX,AX ;DS:00壓棧
PUSH AX MOV AX,DATAREA MOV DS,AX ;置數(shù)據(jù)段
MOV CX,0 ;CX計數(shù)器清0 MOV BX,ADDR MOV AX,[BX] ;取Y值給AXREPEAT: TEST AX,0FFFFH JZ EXIT ;測試AX是否為0?,是轉(zhuǎn)EXIT JNS SHIFT ;符號為不為1轉(zhuǎn)SHIFT INC CX ;計數(shù)器加1SHIFT: SHL AX,1 ;左移一位
JMP REPEAT ;繼續(xù)找1EXIT: MOV COUNT,CX ;保存計數(shù)值
RET MAIN ENDP PROGNAMENDS ENDS
例6:學(xué)生成績統(tǒng)計,要求鍵盤輸入成績、人數(shù),并統(tǒng)計優(yōu)、良、中、及格和不及格各多少人。循環(huán)結(jié)構(gòu)程序設(shè)計(12)循環(huán)結(jié)構(gòu)程序設(shè)計(13)DATA SEGMENT ;定義數(shù)據(jù)段STUNUM EQU 30 ;學(xué)生人數(shù)SCORE DB 68,75,37,93,65,80,78,70,84,67;學(xué)生成績
DB 86,74,65,54,56,77,85,69,78,95 DB 69,53,77,68,88,93,84,76,77,80LT60 DB 0 ;存放不及格人數(shù)GE60 DB 0 ;存放及格人數(shù)GE70 DB 0 ;存放中人數(shù)GE80 DB 0 ;存放良人數(shù)GE90 DB 0 ;存放優(yōu)人數(shù)DATA SEGMENTSTACK SEGMENT ;定義堆棧段STA DW 20H DUP(?)TOP DW ?STACK ENDSCODE SEGMENT ;定義代碼段MAIN PROC FAR ASSUME CS:CODE,DS:DATA,SS:STACKSTART: PUSH DS ;DS壓棧
MOV AX,0 PUSH AX ;0壓棧
MOV AX,DATA MOV DS,AX ;置數(shù)據(jù)段
循環(huán)結(jié)構(gòu)程序設(shè)計(14) MOV CX,STUNUM ;取學(xué)生人數(shù)
MOV BX,OFFSETSCORE ;BX指向?qū)W生成績表首地址B60: MOV AL,[BX] ;取出一個學(xué)生成績
CMP AL,60 ;是否大于60 JA M60 ;大于、等于轉(zhuǎn)M60 LEA SI,LT60 ;SI指向LT60單元
INC [SI] ;SI加1 JMP NEXT ;繼續(xù)統(tǒng)計下一個成績M60: CMP AL,70 ;是否大于70 JA M70 ;大于、等于轉(zhuǎn)M70 LEA SI,GE60 ;SI指向GE60單元
INC [SI] ;SI加1 JMP NEXT ;繼續(xù)統(tǒng)計下一個成績M70: CMP AL,80 ;是否大于80 JA M80 ;大于、等于轉(zhuǎn)M80 LEA SI,GE70 ;SI指向GE70單元
INC [SI] ;SI加1 JMP NEXT ;繼續(xù)統(tǒng)計下一個成績M80: CMP AL,90 ;是否大于90 JA M90 ;大于、等于轉(zhuǎn)M90 LEA SI,GE80 ;SI指向GE80單元
INC [SI] ;SI加1 JMP NEXT ;繼續(xù)統(tǒng)計下一個成績M90: LEA SI,GE90 ;SI指向GE90單元
INC [SI] ;SI加1NEXT: INC BX ;BX加1 LOOP B60 ;沒有統(tǒng)計完,繼續(xù)
RETMAIN ENDP END START循環(huán)結(jié)構(gòu)程序設(shè)計(14)
在附加段中有一個首地址為LIST和未經(jīng)排序的字?jǐn)?shù)組,在數(shù)組的第一個中存放著該數(shù)組的長度,數(shù)組首地址已存放在DI寄存器中。AX寄存器中存放著一個數(shù)。要求:在數(shù)組中查找該數(shù),如果找到此數(shù)則把它從數(shù)組中刪除。循環(huán)結(jié)構(gòu)程序設(shè)計(15)del_ul procfar cld pushdi movcx,es:[di] adddi,2 repnescasw jedelete popdi jmpshortexit delet: jcxzdec_cnt next_el: movbx,es:[di] moves:[di-2],bx adddi,2 loopnext_el dec_cnt: popdi decwordptres:[di] exit: movah,4ch int21h del_ul endp
循環(huán)結(jié)構(gòu)程序設(shè)計(16)
將正數(shù)N插入一個已整序的字?jǐn)?shù)組中的正確位置。該數(shù)組的首地址和末地址分別為ARRAY_HEAD,ARRAY_END,其中所有數(shù)均為正數(shù)且已按遞增的次序排列。循環(huán)結(jié)構(gòu)程序設(shè)計(17)datareasegment xdw? array_headdw3,5,15,23,37,49,52,65,78,99 array_enddw105 ndw32 datareaends prognamsegment mainprocfar assumecs:prognam,ds:datarea start: pushds subax,ax pushax movax,datarea movds,ax movax,n movarray_head-2,0ffffh ;array_head-2=-1 movsi,0
循環(huán)結(jié)構(gòu)程序設(shè)計(18)compare:
cmparray_end[si],ax jleinsert movbx,array_end[si] movarray_end[si+2],bx subsi,2 jmpshortcompareinsert: movarray_end[si+2],ax movah,4ch int21h mainendp prognamends endstart
循環(huán)結(jié)構(gòu)程序設(shè)計(19)
編寫一程序:從鍵盤輸入一行字符,要求第一個鍵入的字符必須是空格,如不是空格則推出程序;如是則開始接收鍵入的字符并順序存放在首地址為BUFFER的緩沖區(qū)中(空格不存入),直到接收到第二個空格字符時退出程序。循環(huán)結(jié)構(gòu)程序設(shè)計(20)datareasegment bufferdb80dup(?) flagdb? datareaends prognamsegment mainprocfar assumecs:prognam,ds:datarea start: pushds subax,ax pushax movax,datarea movds,ax leabx,buffer movflag,0
循環(huán)結(jié)構(gòu)程序設(shè)計(20)next: movah,01 int21h testflag,01h jnzfollow cmpal,20h jnzexit movflag,1 jmpnextfollow: cmpal,20h jzexit mov[bx],al incbx jmpnextexit: movah,4ch int21hmain endpprognamends endstart
循環(huán)結(jié)構(gòu)程序設(shè)計(12)多重循環(huán)程序設(shè)計例1、延時程序DELAY: MOV DX,3FFH ;外層循環(huán)3FFH次TIME: MOV AX,0FFFFH;內(nèi)層循環(huán)FFFFH次TIME1: DEC AX NOP ;空操作,起延時作用
JNE TIME1 ;內(nèi)循環(huán)是否結(jié)束,否則繼續(xù)
DEC DX JNE TIME ;外循環(huán)是否結(jié)束,否則繼續(xù)
RET循環(huán)結(jié)構(gòu)程序設(shè)計(13)例2:有一個首地址為A的N個數(shù)的數(shù)組,請編制程序使該數(shù)組中的數(shù)按照從大到小的次序整序。起泡排序算法舉例總結(jié):在做第一遍的(N-1)次比較后,最小的數(shù)已經(jīng)放到了最后,所以第二遍比較只需要考慮(N-1)個數(shù)即只需要比較(N-2)次,第三遍則只需做(N-3)次比較……總共最多(N-1)遍比較就可以完成排序。
循環(huán)結(jié)構(gòu)程序設(shè)計(13)DATAREASEGMENT ;定義數(shù)據(jù)段ADWNDUP(?)DATAREA ENDSPROGNAM SEGMENT ;定義代碼段MAIN PROCFAR ASSUMECS:PROGNAM,DS:DATAREASTART: PUSH DS SUB AX,AX ;DS:00壓棧
PUSH AX MOV AX,DATAREA MOV DS,AX ;置數(shù)據(jù)段
MOV CX,N ;數(shù)組元素個數(shù)
DEC CXLOOP1: MOV DI,CX ;外層循環(huán),共N-1次
MOV BX,0 ;內(nèi)層循環(huán)量BX置0LOOP2: MOV AX,A[BX] CMP AX,A[BX+2] ;相鄰兩個數(shù)比較
JGE COTINUE ;前者大,轉(zhuǎn)COTINUE XCHG AX,A[BX+2] ;后者大,交換
MOV A[BX],AXCOTINUE:ADD BX,2 ;繼續(xù)向后循環(huán)
LOOP LOOP2 MOV CX,DI ;恢復(fù)CX值
LOOP LOOP1 ;繼續(xù)外層循環(huán)
RETMAIN ENDPPROGNAMENDS END START子程序結(jié)構(gòu)(1)子程序又稱為過程,它相當(dāng)于高級語言中的過程和函數(shù)。1、在一個程序的不同部分,往往用功能和結(jié)構(gòu)形式都相同的程序段,只是某些變量的賦值不同,此時就可以把這些程序段寫成子程序形式,在需要時可以調(diào)用它。2、有些程序段對于某個用戶可能只用到一次,但它是一般用戶經(jīng)常用到的,如十進(jìn)制數(shù)轉(zhuǎn)換成二進(jìn)制數(shù),二進(jìn)制數(shù)轉(zhuǎn)換為十六進(jìn)制數(shù)并顯示輸出等,對于這些常用的特定功能的程序段也經(jīng)常編制成子程序形式供用戶使用。子程序結(jié)構(gòu)(1)過程定義偽指令其格式為:PROCEDURENAMEPROCATTRIBUTEPROCEDURENAMEENDP1、其中過程名為標(biāo)識符,它又是子程序入口的符號地址。2、屬性(Attribute)是指類型屬性,它可以是NEAR或FAR。3、IBMPC的匯編程序用PROC偽操作的類型屬性來確定CALL和RET指令的屬性。子程序結(jié)構(gòu)(2)過程屬性的確定①調(diào)用程序和過程在同一個代碼段中則使用NEAR屬性;②調(diào)用程序和過程不在同一個代碼段中則使用FAR屬性。子程序結(jié)構(gòu)(3)假設(shè)調(diào)用程序和子程序在同一代碼段中MAIN PROCFAR
CALLSUBR1 RETMAIN ENDPSUBR1PROCNEAR RETSUBR1ENDP子程序結(jié)構(gòu)(4)過程定義也可以嵌套,一個過程定義中可以包括多個過程定義。MAINPROCFARCALLSUBR1RETSUBR1PROCNEARRETSUBR1ENDPMAINENDP子程序結(jié)構(gòu)(5)調(diào)用程序和子程序不在同一個代碼段內(nèi)SEGXSEGMENT
SUBTPROCFARRET SUBTENDPCALLSUBTSEGXENDS;SEGYSEGMENTCALLSUBTSEGYENDS子程序結(jié)構(gòu)(6)子程序參數(shù)的傳送通過寄存器傳送參數(shù) 通過寄存器傳送參數(shù)是最常用的一種方式,使用方便,但參量很多時不能使用這種方法。例1十進(jìn)制到十六進(jìn)制數(shù)轉(zhuǎn)換程序。程序要求從鍵盤取得一個十進(jìn)制數(shù),然后把該數(shù)以十六進(jìn)制形式在屏幕上顯示出來。分析:模塊劃分:
1、用一個子程序DECIBIN實現(xiàn)從鍵盤取得十進(jìn)制數(shù)并把它轉(zhuǎn)換為二進(jìn)制數(shù)。
2、一個子程序BINIHEX把此二進(jìn)制數(shù)以十六進(jìn)制數(shù)的形式在屏幕上顯示出來。
3、為避免屏幕上的重疊,另外用CRLF子程序取得回車和換行效果。子程序結(jié)構(gòu)(7)DECIHEX SEGMENT ;定義代碼段
ASSUMECS:DECIHEXMAIN PROC FAR ;主程序REPEAT: CALL DECIBIN ;調(diào)用子程序輸入十進(jìn)制數(shù)
CALL CRLF ;顯示回車、換行
CALLBINIHEX ;以十六進(jìn)制數(shù)輸出
CALLCRLF ;顯示回車、換行
JMPREPEAT ;轉(zhuǎn)REPEAT,繼續(xù)MAIN ENDP子程序結(jié)構(gòu)(8)DECIBIN PROC NEAR ;十進(jìn)制數(shù)輸入子程序
MOV BX,0 ;BX保存輸入數(shù)NEWCHAR: MOV AH,1 INT 21H ;調(diào)用DOS功能輸入字符
SUB AL,30H ;轉(zhuǎn)為數(shù)0-9 JL EXIT ;小于0,不是數(shù)字
CMP AL,9D ;與9比較
JG EXIT ;大于,不是數(shù)字
CBW ;AL=>AX XCHG AX,BX ;AX、BX互換
MOV CX,10D ;CX=10 MUL CX ;AX=AX*CX XCHG AX,BX ;AX、BX互換
ADD BX,AX ;BX為前面輸入的結(jié)果
JMP NEWCHAREXIT: RETDECIBIN ENDP子程序結(jié)構(gòu)(9)BINIHEXPROC NEAR MOV CH,4 ;CH循環(huán)次數(shù)ROTATE: MOV CL,4 ;每次循環(huán)輸出一位十六進(jìn)制數(shù)
ROL BX,CL ;即移位4個二進(jìn)制位
MOV AL,BL ;AL=BL AND AL,0FH ;取低4位
ADD AL,30H ;轉(zhuǎn)變?yōu)锳SCII碼
CMP AL,3AH ;是否為’0’-‘9’ JL PRINTIT;是轉(zhuǎn)PRINTIT ADD AL,7H ;否轉(zhuǎn)為’A’-‘F’PRINTIT: MOV DL,AL ;DL=輸出字符
MOV AH,2 INT 21H ;調(diào)用DOS中斷,顯示字符
DEC CH JNZ ROTATE ;沒循環(huán)結(jié)束,繼續(xù)
RET ;返回BINIHEX ENDP子程序結(jié)構(gòu)(10)CRLF PROC NEAR ;輸出回車、換行
MOV DL,0DH MOV AH,2 INT 21H ;輸出回車
MOV DL,0AH MOV AH,2 INT 21H ;輸出換行
RETCRLF ENDPDECIHEXENDS ENDMAIN子程序結(jié)構(gòu)(10)(2)如過程和調(diào)用程序在同一源文件(同一程序模塊)中,則過程可直接訪問模塊中的變量。例2:主程序MAIN和過程PROADD在同一源文件中,要求用過程PROADD累加數(shù)組中的所有元素,并把和(不考慮溢出的可能性)送到指定的存儲單元中去。在這里過程PROADD直接訪問模塊的數(shù)據(jù)區(qū)。DATA SEGMENT ;定義數(shù)據(jù)段
ARY DW 100DUP(?) COUNT DW 100 SUM DW ?DATA ENDSCODE SEGMENT 定義代碼段MAIN PROCFAR ASSUMECS:CODE,DS:DATASTART: CALLNEARPTRPROADD ;調(diào)用累計求和子程序
RETMAIN ENDP子程序結(jié)構(gòu)(11)PROAD PROC NEAR PUSH AX ;保存寄存器值
PUSH CX PUSH SI LEA SI,ARY ;置循環(huán)初值,SI指向數(shù)組ARY MOV CX,COUNT ;CX賦循環(huán)次數(shù)
XOR AX,AX ;和初值為0NEXT: ADD AX,[SI] ;累加求和
ADD SI,2 ;指向下一個元素
LOOP NEXT ;繼續(xù)循環(huán)
MOV SUM,AX ;和存入SUM中
POP SI ;恢復(fù)寄存器的值
POP CX POP AX RET ;返回PROADD ENDPCODE ENDS子程序結(jié)構(gòu)(12)(3)通過地址表傳送參數(shù)地址采用通過地址表傳送參數(shù)法是在主程序中建立一個地址表,把要傳送給子程序的參數(shù)都存放在地址表中,然后把地址表的首地址通過寄存器傳送到子程序中去。子程序通過地址表從存儲器中取得所需參數(shù),并把結(jié)果存入指定的存儲單元中去。例1:求數(shù)組中的所有元素的和,并把和送到指定的存儲單元中去。子程序結(jié)構(gòu)(13)DATA SEGMENT ;定義數(shù)據(jù)段
ARY DW 100DUP(?) COUNT DW 100 SUM DW ? TABLE DW 3DUP(?) DATA ENDSPROG_SEGSEGMENTORG 100H ASSUMECS:PROG_SEG,DS:DATA,SS:PROG_SEGMAIN PROC NEAR
MOV TABLE,OFFSETARY ;參數(shù)表TABLE存數(shù)組ARY地址
MOV TABLE+2,OFFSETCOUNT ;參數(shù)表TABLE+2存COUNT地址
MOV TABLE+4,OFFSETSUM ;參數(shù)表TABLE+4存SUM地址
MOV BX,OFFSETTABLE ;BX指向TABLE表
CALL PROADD ;調(diào)用PROADD求和
INT 20HMAIN ENDP END START子程序結(jié)構(gòu)(14)PROADD PROC NEAR ;求和子程序
PUSH AX ;保存寄存器的值
PUSH CX PUSH SI PUSH DI MOV SI,[BX] ;SI指向ARY數(shù)組
MOV DI,[BX+2] ;DI指向COUNT地址
MOV CX,[DI] ;CX=COUNT MOV DI,[BX+4] ;DI指向SUM地址
XOR AX,AX ;累加器清0NEXT: ADD AX,[SI] ;求和
ADD SI,2 ;SI指向下一個數(shù)
LOOP NEXT MOV [DI],AX ;保存和
POP DI ;恢復(fù)寄存器的值
POP SI POP CX POP AX RETPROADD ENDPPROG_SEGENDSEND MAIN子程序結(jié)構(gòu)(15)(4)通過堆棧傳送參數(shù)或參數(shù)地址通過堆棧傳送參數(shù)或參數(shù)地址的方法是在主程序里把參數(shù)地址保存到堆棧中,在子程序里從堆棧中取出參數(shù)以達(dá)到傳送參數(shù)的目的。
注意:子程序結(jié)束時的RET指令應(yīng)使用帶常數(shù)的返回指令,以便返回主程序后堆棧能恢復(fù)原始狀態(tài)不變。例:求數(shù)組中的所有元素的和,并把和送到指定的存儲單元中去。子程序結(jié)構(gòu)(15)PARM_SEG SEGMENTARY DW 100DUP(?) ;求和數(shù)組ARYCOUNT DW 100 ;求和數(shù)組個數(shù)COUNTSUM DW ? ;SUM存放求和結(jié)果
PARM_SEG ENDSSTACK_SEG SEGMNET ;堆棧段
DW 100 DUP(?) ;堆??臻g
TOS LABEL WORDSTACK_SEG ENDSCODE1 SEGMENT ;代碼段MAIN PROCFAR ASSUMECS:CODE1,DS:PARM_SEG,SS:STACK_SEGSTART: MOV AX,STACK_SEG ;置堆棧段
MOV SS,AX MOV SP,OFFSETTOS ;置棧頂指針
PUSH DS ;DS:00壓棧
SUB AX,AX PUSH AX MOV AX,PARM_SEG ;置數(shù)據(jù)段
MOV DS,AX MOV BX,OFFSETARY ;參數(shù)ARY偏移地址壓棧
PUSH BX MOV BX,OFFSETCOUNT ;參數(shù)COUNT偏移地址壓棧
PUSH BX MOV BX,OFFSETSUM ;參數(shù)SUM偏移地址壓棧
PUSH BX CALL FARPTRPROADD ;調(diào)用求和子程序
RETMAIN ENDPCODE1 ENDS子程序結(jié)構(gòu)(16)CODE2 SEGMENT ASSUME CS:CODE2PROADD PROC FAR ;數(shù)組求和子程序
PUSH BP MOV BP,SP ;BP指向棧頂
PUSH AX ;保存寄存器值
PUSH CX PUSH SI PUSH DI MOV SI,[BP+0AH] ;取ARY偏移地址
MOV DI,[BP+8] ;取COUNT偏移地址
MOV CX,[DI] ;COUNT值賦給CX MOV DI,[BP+6] ;取SUM偏移地址
XOR AX,AX ;AX存放求和值,先清0NEXT: ADD AX,[SI] ;累計求和
ADD SI,2 ;SI指向下一個數(shù)
LOOP NEXT MOV [DI],AX ;求和值存入SUM中
POP DI POP SI ;恢復(fù)寄存器值
POP CX POP AX POP BP RET 6 ;恢復(fù)堆棧
PROADDENDP CODE2 ENDS ENDSTART子程序結(jié)構(gòu)(17)(5)多個模塊之間的參數(shù)傳送多個模塊的程序相連接時,不一定要把所有的代碼段或數(shù)據(jù)段分別連接在一起,形成大的代碼段或數(shù)據(jù)段。在很多情況下,各程序模塊仍有各自的分段,通過模塊之間的調(diào)用來進(jìn)行工作。子程序結(jié)構(gòu)(17)外部符號源程序用戶定義的符號可以分為局部符號和外部符號兩種。在本模塊中定義,又在本模塊中引用的符號為局部符號;而在某一個模塊中定義,而又在另一個模塊中引用的符號稱為外部符號。PUBLIC偽操作定義外部符號格式:PUBLICsymbol[,……]在一個模塊中定義的符號(包括變量、標(biāo)號、過程名等)在提供其他模塊使用時,必須要用PUBLIC定義該符號為外部符號。EXTRN偽操作格式:EXTRNsymbolname:type[,……]子程序結(jié)構(gòu)(17)EXTRN偽操作格式:EXTRNsymbolname:type[,……]在另一個模塊中定義而要在本模塊中使用的符號必須使用EXTRN偽操作。如符號為變量則應(yīng)為byte,word,dword等;如符號為標(biāo)號或過程名,則類型應(yīng)為near或far。這兩個偽操作的使用必須相匹配。連接程序會檢查每個模塊中的EXTRN語句中每個符號是否能和與其相連接的其他模塊中的PUBLIC語句中的一個符號相匹配。如果不匹配,則給出出錯信息;如果相匹配,則給予確定值。子程序結(jié)構(gòu)(17)例:三個模塊中外部符號的定義如下:Sourcemodule1extrn var2:word,lab2:farpublic var1,lab1data1 segment var1 db ? var3 dw ? var4 dw ?data1 endscode1 segment assumecs:code1,ds:data1main proc farstart: mov ax,data1 mov ds,axlab1: mov ax,4c00h int 21hmain endpcode1 endsend startsourcemodule2extrn var1:byte,var4:wordpublic var2data2 segment var2 dw 0 var3 db 5dup(?)data2 endscode2 segment assumecs:code2,ds:data2
code2 ends endsourcemodu
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030年中國旅游管理咨詢服務(wù)行業(yè)全國市場開拓戰(zhàn)略制定與實施研究報告
- 2025-2030年中國餐飲供應(yīng)鏈行業(yè)營銷創(chuàng)新戰(zhàn)略制定與實施研究報告
- 市政道路工程監(jiān)理評估報告
- 2024年幼兒園大班健康教案
- 2025年冶金機(jī)械配件項目可行性研究報告
- 縫紉初步知識培訓(xùn)課件
- 廣東省深圳市龍崗區(qū)2023-2024學(xué)年五年級上學(xué)期英語期末試卷
- 輪船玻璃鋼接閃桿 CMCE電場補(bǔ)償避雷器 無源驅(qū)雷避雷針
- 輕紡城糧油冷鏈物流中心新建項目可行性研究報告寫作模板-備案審批
- 年產(chǎn)100萬只高適配性大電流管式接頭智能化技改項目可行性研究報告模板-立項備案
- 北京2025年首都醫(yī)科大學(xué)附屬北京友誼醫(yī)院招聘140人歷年參考題庫(頻考版)含答案解析
- 《工商管理專業(yè)畢業(yè)實習(xí)》課程教學(xué)大綱
- 國開電大本科《西方經(jīng)濟(jì)學(xué)(本)》網(wǎng)上形考(作業(yè)一至六)試題及答案
- 提高有風(fēng)險患者預(yù)防跌倒墜床護(hù)理措施落實率品管圈PDCA案例匯報
- 2024年行政執(zhí)法人員執(zhí)法資格知識考試題庫(附含答案)
- 西那卡塞治療甲旁亢
- 二次砌筑配管(JDG)技術(shù)交底
- 施工升降機(jī)定期檢驗原始記錄
- AI技術(shù)打造智能客服機(jī)器人
- 油氣儲存企業(yè)安全風(fēng)險評估指南(試行)
- 快速了解陌生行業(yè)的方法論及示例PPT課件
評論
0/150
提交評論