第6章 子程序設(shè)計(jì)_第1頁
第6章 子程序設(shè)計(jì)_第2頁
第6章 子程序設(shè)計(jì)_第3頁
第6章 子程序設(shè)計(jì)_第4頁
第6章 子程序設(shè)計(jì)_第5頁
已閱讀5頁,還剩32頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)第六章 子程序結(jié)構(gòu) 過程定義偽操作過程定義偽操作 子程序的調(diào)用與返回子程序的調(diào)用與返回 保存與恢復(fù)寄存器保存與恢復(fù)寄存器 子程序的參數(shù)傳送子程序的參數(shù)傳送 子程序的嵌套與遞歸子程序的嵌套與遞歸匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)一、調(diào)用程序與子程序一、調(diào)用程序與子程序 子程序子程序: :在許多應(yīng)用程序中,常常需要多次使用某功能的指令在許多應(yīng)用程序中,常常需要多次使用某功能的指令序列。這時(shí),為了減少重復(fù)編寫程序,節(jié)省內(nèi)存空間,把這一功序列。這時(shí),為了減少重復(fù)編寫程序,節(jié)省內(nèi)存空間,把這一功能的指令序列組成一個(gè)相對獨(dú)立的程序段。在程序運(yùn)行時(shí),如果能的指令序列組成一個(gè)相對

2、獨(dú)立的程序段。在程序運(yùn)行時(shí),如果需要使用這個(gè)給定的功能,就轉(zhuǎn)移到這個(gè)獨(dú)立的程序段,待這個(gè)需要使用這個(gè)給定的功能,就轉(zhuǎn)移到這個(gè)獨(dú)立的程序段,待這個(gè)獨(dú)立的程序段指令序列執(zhí)行完后,又返回到原來位置繼續(xù)運(yùn)行程獨(dú)立的程序段指令序列執(zhí)行完后,又返回到原來位置繼續(xù)運(yùn)行程序。我們把這個(gè)相對獨(dú)立的程序段就叫子程序或過程。序。我們把這個(gè)相對獨(dú)立的程序段就叫子程序或過程。調(diào)用程序調(diào)用程序: :編制程序時(shí),按需要轉(zhuǎn)向子程序,稱為子程序調(diào)用,編制程序時(shí),按需要轉(zhuǎn)向子程序,稱為子程序調(diào)用,或稱為過程調(diào)用。調(diào)用子程序的程序稱為調(diào)用程序或主程序。主、或稱為過程調(diào)用。調(diào)用子程序的程序稱為調(diào)用程序或主程序。主、子程序是相對而言的

3、。但子程序一定是受調(diào)用程序或主程序調(diào)用子程序是相對而言的。但子程序一定是受調(diào)用程序或主程序調(diào)用的。子程序定義的位置可以放在主程序的前面或后面。的。子程序定義的位置可以放在主程序的前面或后面。匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)二二. 過程定義偽操作過程定義偽操作 過程名過程名 PROC PROC NEARNEAR ( ( FAR FAR ) ) 過程名過程名 ENDPENDP(1 1)NEARNEAR屬性:調(diào)用程序和子程序在同一代碼段中,屬性:調(diào)用程序和子程序在同一代碼段中, 可省略。(段內(nèi)調(diào)用)可省略。(段內(nèi)調(diào)用)(2 2)FARFAR屬性:調(diào)用程序和子程序不在同一代碼段中。屬性:調(diào)用程序和子程

4、序不在同一代碼段中。 (段間調(diào)用)(段間調(diào)用).匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)code1 segmentcode1 segmentmain proc main proc farfar callcall far ptr subp far ptr subp ret retmain endpmain endpcode1 endscode1 endscode2 segmentcode2 segmentsubp proc subp proc farfar retretsubp endpsubp endpcode2 endscode2 ends 段間調(diào)用和返回段間調(diào)用和返回code segmentcod

5、e segmentmain proc main proc farfar call call subp subp ret retmain endpmain endpsubp proc subp proc nearnear retretsubp endpsubp endpcode endscode ends 段內(nèi)調(diào)用和返回段內(nèi)調(diào)用和返回匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)segx segmentsegx segmentsubtsubt proc proc farfar retretsubtsubt endp endp callcall subtsubt segx endssegx endssegy s

6、egmentsegy segment callcall far ptr far ptr subtsubt segy endssegy ends同一個(gè)子程序同一個(gè)子程序可以被段內(nèi)調(diào)可以被段內(nèi)調(diào)用,也可以段用,也可以段間調(diào)用間調(diào)用匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì) (1)CALL 子程序調(diào)用指令:子程序調(diào)用指令:隱含使用堆棧保存返回地址隱含使用堆棧保存返回地址 指令格式:指令格式: CALL DST ;其中其中DST為過程的目標(biāo)地址(即過程名)。為過程的目標(biāo)地址(即過程名)。指令功能:指令功能: 把把CALL指令的下一條指令地址(稱為返回點(diǎn)或斷點(diǎn))指令的下一條指令地址(稱為返回點(diǎn)或斷點(diǎn)) 推推入堆棧

7、保存,然后轉(zhuǎn)到目標(biāo)地址(入堆棧保存,然后轉(zhuǎn)到目標(biāo)地址(DST)。)。 CALL指令可以在段內(nèi)、段間調(diào)用,尋址方式分為直接和指令可以在段內(nèi)、段間調(diào)用,尋址方式分為直接和間接兩種。間接兩種。三三. 子程序的調(diào)用與返回指令子程序的調(diào)用與返回指令匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì) 段內(nèi)直接近調(diào)用:段內(nèi)直接近調(diào)用:CALL DST執(zhí)行操作:執(zhí)行操作: (SP) (SP) - 2 ( (SP)+1,(SP) ) (IP) (IP) DST(實(shí)際操作是(實(shí)際操作是把從把從指令中得到的距目標(biāo)過程相對偏移量(最大為指令中得到的距目標(biāo)過程相對偏移量(最大為32K字節(jié))加到指令指針字節(jié))加到指令指針I(yè)P上(得到子程序

8、的上(得到子程序的入口地址),實(shí)現(xiàn)過程調(diào)用。入口地址),實(shí)現(xiàn)過程調(diào)用。)段內(nèi)間接近調(diào)用:段內(nèi)間接近調(diào)用:CALL DST執(zhí)行操作:執(zhí)行操作: PUSH IP (IP) (EA)DST給出子程序的入口地址給出子程序的入口地址(子程序?yàn)椋ㄗ映绦驗(yàn)閚ear屬性)屬性)比如:比如:CALL subpDST給出寄存器或存儲單元的內(nèi)給出寄存器或存儲單元的內(nèi)容(轉(zhuǎn)向地址)容(轉(zhuǎn)向地址)比如:比如: CALL word ptr bx (SP) (IP)匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)段間直接遠(yuǎn)調(diào)用:段間直接遠(yuǎn)調(diào)用:CALL FAR PTR DST執(zhí)行操作:執(zhí)行操作: PUSH CS PUSH IP (IP)

9、DST DST偏移地址偏移地址 (CS) DST DST段地址段地址段間間接遠(yuǎn)調(diào)用段間間接遠(yuǎn)調(diào)用:CALL FAR PTR DST 執(zhí)行操作:執(zhí)行操作: PUSH CS PUSH IP (IP) (EA) (CS) (EA+2)(IP)(CS)(SP) DST給出子程序的入口地址給出子程序的入口地址(子程序?yàn)椋ㄗ映绦驗(yàn)閒ar屬性)屬性)比如:比如:CALL far ptr subp匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)(2)RET 返回主程序指令:返回主程序指令: 屬于無屬于無條件轉(zhuǎn)移指令??梢栽诙蝺?nèi)或段間返條件轉(zhuǎn)移指令??梢栽诙蝺?nèi)或段間返回?;亍6蝺?nèi)近返回:段內(nèi)近返回:RET 執(zhí)行操作:執(zhí)行操作:

10、 POP IP段內(nèi)帶立即數(shù)近返回:段內(nèi)帶立即數(shù)近返回:RET EXP 執(zhí)行操作:執(zhí)行操作: POP IP (SP) (SP)+EXP段間遠(yuǎn)返回:段間遠(yuǎn)返回:RET(F) 執(zhí)行操作:執(zhí)行操作: POP IP POP CS 段間帶立即數(shù)遠(yuǎn)返回:段間帶立即數(shù)遠(yuǎn)返回:RET EXP表達(dá)式表達(dá)式 (SP) (IP) (SP) 。 (SP)(SP)+EXP匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)例:帶立即數(shù)返回例:帶立即數(shù)返回(SP)(SP) 堆棧段堆棧段code segmentcode segmentmain proc farmain proc farStart:Start: push ds push dsSu

11、b ax,axSub ax,axpush ax push ax push ax push ax push bx push bx push cx push cx call sub call sub ret retmain endpmain endpsub proc sub proc nearnear ret 6 ret 6sub endpsub endpcode endscode endsend startend start(IP)(IP)(cx)(cx)(bx)(bx)(ax)(ax)(SP)(SP)(SP)(SP)主程序模塊主程序模塊子程序模塊子程序模塊(SP)(SP)程序返回程序返回匯編語

12、言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)【例】已知三個(gè)八位無符號數(shù)【例】已知三個(gè)八位無符號數(shù)X X、Y Y、Z Z,分別存放于,分別存放于BUFBUF、BUF+1BUF+1和和BUF+2BUF+2存儲單元,計(jì)算存儲單元,計(jì)算2X+5Y+8Z2X+5Y+8Z,結(jié)果送,結(jié)果送RESRES和和RES+1RES+1單元。單元。DATA SEGMENTBUF DB 71H,0A4H,9BHRES DB 2 DUP(?)DATA ENDSSTACK SEGMENT DW 50 DUP(?)TOP LABEL WORDSTACK ENDSCODE SEGMENT ASSUME CS:CODE, DS:DATA, SS:S

13、TACKMAIN PROC FAR START:MAIN ENDPCODE ENDS END START匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)將主程序補(bǔ)充完整將主程序補(bǔ)充完整START: PUSHDS SUB AX,AX PUSH AX ;保存程序前綴PSP地址 MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV SP,OFFSET TOP MOV AX,0 ;AX清0 MOV WORD PTR RES,AX ;RES字單元清0 LEA BX,BUF ;置地址指針 MOV AL,2 CALL MULL ;過程調(diào)用計(jì)算RES+2X MOV AL,5 CAL

14、L MULL ;過程調(diào)用計(jì)算RES+5Y MOV AL,8 CALL MULL ;過程調(diào)用計(jì)算RES+8Z RET ;程序返回匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)子程序編寫子程序編寫MULL PROC NEAR ;乘法子程序 MUL BYTE PTR BX ;做乘法結(jié)果在AX ADD WORD PTR RES,AX ;做加法 MOV AX,0 ;AX清0 INC BX ;地址加1 RET ;返回主程序 MULL ENDP匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)四四. 現(xiàn)場現(xiàn)場保護(hù)與恢復(fù)保護(hù)與恢復(fù)subtsubt proc near proc near push ax push ax push bx pus

15、h bx push cx push cx push dx push dx pop dx pop dx pop cx pop cx pop bx pop bx pop ax pop ax ret retsubtsubt endp endp要保護(hù)的寄存器:應(yīng)該是在子程序要保護(hù)的寄存器:應(yīng)該是在子程序中將被使用,返回調(diào)用程序后仍然中將被使用,返回調(diào)用程序后仍然需要使用其原有內(nèi)容的那些寄存器。需要使用其原有內(nèi)容的那些寄存器。即保護(hù)調(diào)用程序和子程序兩者在使即保護(hù)調(diào)用程序和子程序兩者在使用上發(fā)生沖突的那些寄存器。用上發(fā)生沖突的那些寄存器。但在但在編程時(shí),一時(shí)很難弄清哪些是有沖編程時(shí),一時(shí)很難弄清哪些是有沖

16、突的寄存器,一種較為簡單的方法突的寄存器,一種較為簡單的方法是把所有的寄存器均加以保護(hù)。是把所有的寄存器均加以保護(hù)。一般在子程序中進(jìn)行寄存器保護(hù)較一般在子程序中進(jìn)行寄存器保護(hù)較好。好。即在子程序的開始部分,先進(jìn)即在子程序的開始部分,先進(jìn)行相關(guān)寄存器(主要是在子程序中行相關(guān)寄存器(主要是在子程序中使用的各寄存器)的保護(hù)。然后再使用的各寄存器)的保護(hù)。然后再進(jìn)行子程序的處理操作。在執(zhí)行完進(jìn)行子程序的處理操作。在執(zhí)行完子程序后,返回前,先恢復(fù)各寄存子程序后,返回前,先恢復(fù)各寄存器內(nèi)容后,再返回調(diào)用程序。器內(nèi)容后,再返回調(diào)用程序。匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)(1) 通過寄存器傳送參數(shù)通過寄存器傳送

17、參數(shù)(2) 通過存儲器傳送參數(shù)通過存儲器傳送參數(shù)(3) 通過地址表傳送參數(shù)地址通過地址表傳送參數(shù)地址(4) 通過堆棧傳送參數(shù)或參數(shù)地址通過堆棧傳送參數(shù)或參數(shù)地址五五. 子程序的參數(shù)傳送子程序的參數(shù)傳送實(shí)現(xiàn)的方法是把子程序所需要的入口參實(shí)現(xiàn)的方法是把子程序所需要的入口參數(shù),由調(diào)用程序予先放入指定的寄存器數(shù),由調(diào)用程序予先放入指定的寄存器中。在進(jìn)入子程序后,子程序就可直接中。在進(jìn)入子程序后,子程序就可直接對這些寄存器內(nèi)容進(jìn)行操作了。同樣子對這些寄存器內(nèi)容進(jìn)行操作了。同樣子程序的運(yùn)行結(jié)果,也可置入寄存器中,程序的運(yùn)行結(jié)果,也可置入寄存器中,把它們作為子程序的出口參數(shù)寄存器使把它們作為子程序的出口參數(shù)

18、寄存器使用。用。請大家注意:參數(shù)的傳遞方法并不是固定不變的,即它們是可以綜合請大家注意:參數(shù)的傳遞方法并不是固定不變的,即它們是可以綜合使用的。依實(shí)現(xiàn)的需要和情況的不同,可以靈活使用其中一種方式,使用的。依實(shí)現(xiàn)的需要和情況的不同,可以靈活使用其中一種方式,也可以同時(shí)使用幾種方式的混合。有的時(shí)候還可能并不需要參數(shù)傳遞。也可以同時(shí)使用幾種方式的混合。有的時(shí)候還可能并不需要參數(shù)傳遞。匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)例例1:十六進(jìn)制到十進(jìn)制的轉(zhuǎn)換(:十六進(jìn)制到十進(jìn)制的轉(zhuǎn)換(通過寄存器傳送參數(shù)通過寄存器傳送參數(shù))hexidec segment ; 1610 assume cs: hexidec main

19、 proc farstart: push ds sub ax, ax push ax call hexibin ; 162 call crlf call binidec ; 210 call crlf retmain endphexidec ends end startCrlf proc near mov dl, 0dh mov ah,2 int 21h mov dl, 0ah mov ah,2 int 21h retCrlf endp匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)hexibin proc nearhexibin proc near mov bx, 0mov bx, 0newchar: mo

20、v ah, 1 int 21h sub al, 30h jl exit cmp al, 10 jl add_to sub al, 27h cmp al, 0ah jl exit cmp al, 10h jge exitadd_to: mov cl, 4 shl bx, cl mov ah, 0 add bxbx, ax jmp newchar exit: rethexibin endphexibin endpbinidec proc nearbinidec proc near mov cx, 10000d call dec_divcall dec_div mov cx, 1000d call

21、dec_divcall dec_div mov cx, 100d call dec_divcall dec_div mov cx, 10d call dec_divcall dec_div mov cx, 1d call dec_divcall dec_div retbinidec endpbinidec endpdec_div proc neardec_div proc near mov ax, mov ax, bxbx mov dx, 0 mov dx, 0 div cx div cx mov mov bxbx, dx, dx mov dl, al mov dl, al add dl, 3

22、0h add dl, 30h mov ah, 2 mov ah, 2 int 21h int 21h ret retdec_div endpdec_div endp 1 a b 5 31 61 62 35匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)例例2:累加數(shù)組中的元素(:累加數(shù)組中的元素(通過存儲器傳送參數(shù)通過存儲器傳送參數(shù))data segment ary dw 1,2,3,4,5,6,7,8,9,10 count dw 10 sum dw ?data endscode segment assume cs:code,ds:datastart: mov ax, data mov ds, ax call

23、 proaddcall proadd mov ax,4c00h int 21hmain endpcode ends end startproadd proc nearproadd proc near push ax push cx push si lea si, aryary mov cx, countcount xor ax, axnext: add ax, si add si, 2 loop next mov sumsum,ax pop si pop cx pop ax retproadd endpproadd endp匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)如果數(shù)據(jù)段定義如下:如果數(shù)據(jù)段定義如下

24、:data segmentdata segment ary dwary dw 1,2,3,4,5,6,7,8,9,10 1,2,3,4,5,6,7,8,9,10 count dwcount dw 10 10 sum dwsum dw ? ? ary1 dwary1 dw 10,20,30,40,50,60,70,80,90,100 10,20,30,40,50,60,70,80,90,100 count1 dwcount1 dw 10 10 sum1 dwsum1 dw ? ?data endsdata ends 如果直接訪問內(nèi)存變量,那么累加如果直接訪問內(nèi)存變量,那么累加數(shù)組數(shù)組aryary

25、和和數(shù)組數(shù)組ary1ary1中的元素不能用同一個(gè)子程序中的元素不能用同一個(gè)子程序 proaddproadd。那那如何能實(shí)現(xiàn)調(diào)用同一個(gè)子程序如何能實(shí)現(xiàn)調(diào)用同一個(gè)子程序proadd來累加另一個(gè)來累加另一個(gè)數(shù)組元素?數(shù)組元素?匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)例例3:累加數(shù)組中的元素(:累加數(shù)組中的元素(通過地址表傳送參數(shù)地址通過地址表傳送參數(shù)地址)data segment ary dw 10,20,30,40,50,60,70,80,90,100 count dw 10 sum dw ? table dw 3 dup (?) ; 地址表data endscode segmentmain proc f

26、ar assume cs:code, ds:data push ds sub ax, ax push ax mov ax, data mov ds, ax mov table, offset ary ;把要傳送給子程序把要傳送給子程序 mov table+2, offset count;的參數(shù)都存放在地址的參數(shù)都存放在地址 mov table+4, offset sum ;表中,然后把地址表表中,然后把地址表 mov bx, offset table;的首地址通過寄存器的首地址通過寄存器 call proadd ;BX傳送到子程序中去。傳送到子程序中去。 retmain endp 匯編語言程序

27、設(shè)計(jì)匯編語言程序設(shè)計(jì)proadd proc nearproadd proc near push ax push cx push si push di mov si, bx mov di, bx+2 mov cx, di mov di, bx+4 xor ax, axnext: add ax, si add si, 2 loop next mov di,ax pop di pop si pop cx pop ax retproadd endpproadd endpcode ends end main 30d 40d 50d 60d 70d 80d 90d100d 10d ary 20d 10dc

28、ountsumtable00000000001400140016001600180018000000000014001400160016(bx)(bx)(si)(si)(di)(di)550d550d存儲單元的內(nèi)容存儲單元的內(nèi)容匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)例例4:累加數(shù)組中的元素(:累加數(shù)組中的元素(通過堆棧傳送參數(shù)地址通過堆棧傳送參數(shù)地址) 在主程序里把參數(shù)地址保存到堆棧中,在子程序里從堆棧中取出在主程序里把參數(shù)地址保存到堆棧中,在子程序里從堆棧中取出參數(shù)以達(dá)到傳送參數(shù)的目的。參數(shù)以達(dá)到傳送參數(shù)的目的。data segmentdata segment ary dw 10,20,30,40

29、,50,60,70,80,90,100 ary dw 10,20,30,40,50,60,70,80,90,100 count dw 10 count dw 10 sum dw ? sum dw ?data endsdata endsstack segment stack segment dw 100 dup (?) dw 100 dup (?) ;堆棧全是字操作,必須用;堆棧全是字操作,必須用DWDW tos label word tos label word ;棧頂指針也必須是字類型;棧頂指針也必須是字類型stack endsstack ends 匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)code

30、segmentmain proc far assume cs:code, ds:data, ss:stackstart: mov ax, stack mov ss, ax mov sp, offset tos ;堆棧段及;堆棧段及SPSP設(shè)置方法設(shè)置方法 mov ax, data mov ds, ax mov bx, offset ary push bx mov bx, offset count push bx mov bx, offset sum push bx ;把參數(shù)地址保存到堆棧把參數(shù)地址保存到堆棧 call proadd mov ax, 4c00h int 21hmain endpc

31、ode ends end start匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)proadd proc nearproadd proc near push bppush bp mov mov bpbp, sp, sp push ax push cx push si push di mov si,bpbp+8 mov di,bpbp+6 mov cx,di mov di,bpbp+4 xor ax, axnext: add ax, si add si, 2 loop next mov di,ax pop di pop si pop cx pop ax pop bp ret 6ret 6proadd endp

32、proadd endp(ip)sumcountarray (di) (si) (cx) (ax)(sp)(bpbp)(bp) (bpbp)+8 (bpbp)+6 (bpbp)+4tosCALL指令指令堆棧最滿的狀態(tài)堆棧最滿的狀態(tài)匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)子程序的嵌套:子程序的嵌套:一個(gè)子程序也可以作為調(diào)用程序去調(diào)用另一個(gè)子程序。一個(gè)子程序也可以作為調(diào)用程序去調(diào)用另一個(gè)子程序。 主程序主程序 子程序子程序A A 子程序子程序B B六六. 子程序的嵌套與遞歸調(diào)用子程序的嵌套與遞歸調(diào)用 call call proc_Aproc_Aproc_Aproc_A call call proc_Bpro

33、c_BCall Call proc_Aproc_Aretretproc_Bproc_B retret子程序的遞歸調(diào)用是指一個(gè)子子程序的遞歸調(diào)用是指一個(gè)子程序直接或間接地調(diào)用自己。程序直接或間接地調(diào)用自己。遞歸調(diào)用要注意必須有結(jié)束遞遞歸調(diào)用要注意必須有結(jié)束遞歸調(diào)用的判斷語句。歸調(diào)用的判斷語句。匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)編寫子程序計(jì)算(編寫子程序計(jì)算(bx)!=axFact proc near and bx,bx jzfact1 ;等于等于0跳轉(zhuǎn)跳轉(zhuǎn) pushbx dec bx call fact ;遞歸調(diào)用遞歸調(diào)用L: pop bx mulbx ;結(jié)果在結(jié)果在ax中中 retFact1:

34、mov ax,1 retFact endp編寫程序計(jì)算編寫程序計(jì)算4!+7! . . ;主程序開始部分主程序開始部分 mov bx, 4 ;入口參數(shù)入口參數(shù) call fact ;調(diào)用子程序調(diào)用子程序M: push ax ;保存保存4!的結(jié)果的結(jié)果 mov bx, 7 call fact ;(ax)=7! pop bx ;(bx)=4! add ax,bx . .遞歸子程序:遞歸子程序:n! n ( n - 1 ) ( n - 2 ) 1 3! 3 21= 6 0!=1 n!=n(n-1)!匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)子程序如果段間調(diào)用時(shí),必須定義為子程序如果段間調(diào)用時(shí),必須定義為FARF

35、AR類型類型。段間調(diào)用通常用于不同模塊之間的調(diào)用。段間調(diào)用通常用于不同模塊之間的調(diào)用。編寫不同模塊的段間調(diào)用程序,應(yīng)該注意以下幾個(gè)個(gè)問題:編寫不同模塊的段間調(diào)用程序,應(yīng)該注意以下幾個(gè)個(gè)問題: (1 1)主程序模塊和子程序模塊分別匯編,然后用連接)主程序模塊和子程序模塊分別匯編,然后用連接程序?qū)⑺鼈冞B接在一起。程序?qū)⑺鼈冞B接在一起。 (2 2)在主程序模塊中,主程序所調(diào)用的外部過程名必)在主程序模塊中,主程序所調(diào)用的外部過程名必須用須用EXTRNEXTRN偽指令說明。偽指令說明。 (3 3)在過程模塊中,提供給外段調(diào)用的過程名必須用)在過程模塊中,提供給外段調(diào)用的過程名必須用PUBLICPUBL

36、IC偽指令說明。偽指令說明。 (4 4)模塊間其它公用符號名及外部符號名的定義不可)模塊間其它公用符號名及外部符號名的定義不可缺少。缺少。七七. 多模塊程序設(shè)計(jì)(段間調(diào)用)多模塊程序設(shè)計(jì)(段間調(diào)用)匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)局部符號:局部符號:在本模塊中定義,在本模塊中引用的符號。在本模塊中定義,在本模塊中引用的符號。不同模塊中不同模塊中的局部符號允許重名。的局部符號允許重名。外部符號:外部符號:在某一模塊中定義,在另一模塊中引用的符號。在某一模塊中定義,在另一模塊中引用的符號。要連接要連接的模塊中的外部符號不允許重名。的模塊中的外部符號不允許重名。 PUBLIC PUBLIC 符號符號

37、 EXTRN EXTRN 符號符號: :類型類型 extrn proadd : farextrn proadd : far ;在本模塊中引用其他模塊;在本模塊中引用其他模塊 ;中定義的外部符號;中定義的外部符號proaddproaddcode1 segmentcode1 segmentstart:start: call far ptr proadd call far ptr proadd code1 endscode1 ends end start end start; proadd1.asmpublic proaddpublic proadd ;在本模塊中定義可供;在本模塊中定義可供 ;其他

38、模塊引用的符號;其他模塊引用的符號code2 segmentcode2 segmentproadd proc farproadd proc far ret retproadd endpproadd endpcode2 endscode2 ends end end ; proadd2.asm匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)將【例將【例6.16.1】 中的段內(nèi)調(diào)用改為段間調(diào)用中的段內(nèi)調(diào)用改為段間調(diào)用已知三個(gè)八位無符號數(shù)已知三個(gè)八位無符號數(shù)X X、Y Y、Z Z,分別存放于,分別存放于BUFBUF、BUF+1BUF+1和和BUF+2BUF+2存儲單元,存儲單元,計(jì)算計(jì)算2X+5Y+8Z2X+5Y+8

39、Z,結(jié)果送,結(jié)果送RESRES和和RES+1RES+1單元。單元。NAME EXAM6_2EXTRN MULL:FAR ;外部引用說明PUBLIC RES ;定義公用名DATA SEGMENTBUF DB 71H,0A4H,9BHRES DB 2 DUP(?)DATA ENDSSTACK SEGMENT DW 50 DUP(?)TOP LABEL WORDSTACK ENDSCODE1 SEGMENTASSUME CS:CODE1, DS:DATA, SS:STACKMAIN PROC FAR START:MAIN ENDPCODE1 ENDS END START NAME L6_2A EXT

40、RN RES:BYTE ;外部引用說明;外部引用說明 PUBLIC MULL ;定義公用名;定義公用名CODE2 SEGMENT ASSUME CS:CODE2MULL PROC FAR ;乘法子程序;乘法子程序 MUL BYTE PTR BX ;做乘法結(jié)果在;做乘法結(jié)果在AX ADD WORD PTR RES, AX ;做加法;做加法 MOV AX,0 ;AX清清0 INC BX ;地址加;地址加1 RET ;返回主程序;返回主程序 MULL ENDPCODE2 ENDS END匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)例例5:用:用兩個(gè)模塊兩個(gè)模塊累加數(shù)組累加數(shù)組元素。元素。; proadd1.as

41、mextrn proadd : farextrn proadd : fardata segment common ;允許同名段重疊;允許同名段重疊 ary dw 1,2,3,4,5,6,7,8,9,10 count dw 10 sum dw ?data endscode1 segment main proc far assume cs:code1, ds:datastart: mov ax, data mov ds, ax call far ptr proadd mov ah, 4ch int 21hmain endpcode1 ends end start匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì);

42、proadd2.asmpublic proaddpublic proadddata segment common ary dw 1,2,3,4,5,6,7,8,9,10 count dw 10 sum dw ?data ends code2 segment proadd proc far assume cs:code2,ds:data mov ax, data mov ds, ax push ax push cx push si lea si, ary mov cx, count xor ax, ax next: add ax, si add si, 2 loop next mov sum,a

43、x pop si pop cx pop ax retproadd endpcode2 ends end匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)補(bǔ)充: 模塊化程序設(shè)計(jì)思想 在設(shè)計(jì)大型程序時(shí),常常要將整個(gè)問題分解為若干個(gè)在設(shè)計(jì)大型程序時(shí),常常要將整個(gè)問題分解為若干個(gè)小問題,必要時(shí)還要將小問題再次分解為更小的若干問小問題,必要時(shí)還要將小問題再次分解為更小的若干問題,每個(gè)小問題編寫成獨(dú)立的源文件,最后將所有的源題,每個(gè)小問題編寫成獨(dú)立的源文件,最后將所有的源文件連接起來組合成一個(gè)大程序。也就是說,一個(gè)程序文件連接起來組合成一個(gè)大程序。也就是說,一個(gè)程序往往由多個(gè)源文件組成,那么構(gòu)成一個(gè)程序的各個(gè)相對往往由多個(gè)

44、源文件組成,那么構(gòu)成一個(gè)程序的各個(gè)相對獨(dú)立的源文件通常稱為模塊。獨(dú)立的源文件通常稱為模塊。 這樣把一個(gè)程序分成多個(gè)功能相對獨(dú)立的程序模塊這樣把一個(gè)程序分成多個(gè)功能相對獨(dú)立的程序模塊分別編制、調(diào)試后,再用連接程序把它們連接在一起生分別編制、調(diào)試后,再用連接程序把它們連接在一起生成一個(gè)完整的程序的設(shè)計(jì)方法稱為模塊化程序設(shè)計(jì)。成一個(gè)完整的程序的設(shè)計(jì)方法稱為模塊化程序設(shè)計(jì)。匯編語言程序設(shè)計(jì)匯編語言程序設(shè)計(jì)模塊化程序設(shè)計(jì)的優(yōu)點(diǎn)模塊化程序設(shè)計(jì)的優(yōu)點(diǎn) 開發(fā)速度快開發(fā)速度快 可維護(hù)性與可讀性強(qiáng)可維護(hù)性與可讀性強(qiáng) 可移埴性強(qiáng)可移埴性強(qiáng)模塊劃分的原則和方法模塊劃分的原則和方法模塊劃分是一個(gè)自上而下的過程。主模塊是

45、一個(gè)總控模塊,首先確模塊劃分是一個(gè)自上而下的過程。主模塊是一個(gè)總控模塊,首先確定主要的模塊,也就是說,要把總?cè)蝿?wù)劃分成幾個(gè)主要的子任務(wù)。定主要的模塊,也就是說,要把總?cè)蝿?wù)劃分成幾個(gè)主要的子任務(wù)。一般來說,可以分成輸入任務(wù)、輸出任務(wù)和一個(gè)或多個(gè)進(jìn)行處理或一般來說,可以分成輸入任務(wù)、輸出任務(wù)和一個(gè)或多個(gè)進(jìn)行處理或計(jì)算的子任務(wù)。在劃分子模塊的過程中應(yīng)該明確每個(gè)模塊的功能、計(jì)算的子任務(wù)。在劃分子模塊的過程中應(yīng)該明確每個(gè)模塊的功能、數(shù)據(jù)結(jié)構(gòu)及相互之間的關(guān)系。第二步,對這些主要的子模塊根據(jù)需數(shù)據(jù)結(jié)構(gòu)及相互之間的關(guān)系。第二步,對這些主要的子模塊根據(jù)需要再劃分成下一層的子模塊。第三步,重復(fù)上述過程,一直到程序

46、要再劃分成下一層的子模塊。第三步,重復(fù)上述過程,一直到程序分成易于理解和易于實(shí)現(xiàn)的小模塊為止。分成易于理解和易于實(shí)現(xiàn)的小模塊為止。段的定義 SEGMENTSEGMENT偽指令的完整的格式為:偽指令的完整的格式為: 段名段名 SEGMENT SEGMENT 定位類型定位類型 組合類組合類型型 類別類別 段名段名 ENDSENDS定位類型定位類型 定位類型用于指定該段的段起始地定位類型用于指定該段的段起始地址的特性,連接程序連接目標(biāo)文件時(shí),址的特性,連接程序連接目標(biāo)文件時(shí),根據(jù)定位類型來確定段的開始地址。根據(jù)定位類型來確定段的開始地址。一共有一共有5 5種選擇。種選擇。 1PAGE(頁) 段的起始

47、地址從頁邊界開始,也段的起始地址從頁邊界開始,也就是說必須為就是說必須為256256的倍數(shù),即該地址的的倍數(shù),即該地址的最后最后8 8位二進(jìn)制位應(yīng)為位二進(jìn)制位應(yīng)為0 0。 2PARA(節(jié)) 段的起始地址必須從段邊界開始,段的起始地址必須從段邊界開始,也就是說必須為也就是說必須為1616的倍數(shù),即該地址的倍數(shù),即該地址的最后的最后4 4位二進(jìn)制位應(yīng)為位二進(jìn)制位應(yīng)為0 0。 3DWORD(雙字) 段的起始地址必須從雙字邊界段的起始地址必須從雙字邊界開始,也就是說必須為開始,也就是說必須為4 4的倍數(shù),的倍數(shù),即該地址的最低兩位二進(jìn)制位應(yīng)為即該地址的最低兩位二進(jìn)制位應(yīng)為0 0。 4WORD(字) 段的起始地址必須從字邊界開段的起始地址必須從字邊界開始,也就是說必須為偶數(shù)地址,即始,也就是說必

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論