版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、匯編語言程序設(shè)計,第6章 子程序結(jié)構(gòu),Assembly Language Programming,2,第六章 子程序結(jié)構(gòu),把功能相對獨立的程序段單獨編寫和調(diào)試,作為一個相對獨立的模塊供程序使用,就形成子程序。子程序可以實現(xiàn)源程序的模塊化,可簡化源程序結(jié)構(gòu),可以提高編程效率。定義和使用子程序、參數(shù)傳遞和返回值約定、寄存器使用約定、局部變量和堆棧控制等。參數(shù)傳遞是子程序設(shè)計的重點和難點,3,6.1 子程序的設(shè)計方法,一、 過程(
2、子程序)定義偽操作子程序名 PROC NEAR ( 或 FAR )…… ret子程序名 ENDP子程序名為符合語法的標(biāo)識符NEAR屬性(段內(nèi)近調(diào)用): 調(diào)用程序和子程序在同一代碼段中,只能被相同代碼段的其他程序調(diào)用;FAR屬性(段間遠(yuǎn)調(diào)用): 調(diào)用程序和子程序不在同一代碼段中,可以被相同或不同代碼段的程序調(diào)用.,4,子程序調(diào)用和返回指令,code segmentmain p
3、roc far …… call sub …… retmain endpsub proc near …… retsub endpcode ends,,段內(nèi)調(diào)用和返回,code1 segmentmain proc far …… call sub
4、 …… retmain endpcode1 endscode2 segmentsub proc far …… retsub endpcode2 ends,段間調(diào)用和返回,,,,5,CALL 調(diào)用指令段內(nèi)直接調(diào)用:CALL DST 執(zhí)行操作: (SP)←(SP)-2 ((SP)+1,(SP))←(IP)
5、 (IP)←(IP)+16位位移量段內(nèi)間接調(diào)用:CALL DST 執(zhí)行操作: (SP)←(SP)-2 ((SP)+1,(SP))←(IP) (IP)←(EA),6,段間直接調(diào)用:CALL DST執(zhí)行操作: (SP)←(SP)-2, ((SP)+1,(SP))←(CS)
6、 (SP)←(SP)-2, ((SP)+1,(SP))←(IP) (IP)←偏移地址 (CS)←段地址段間間接調(diào)用:CALL DST執(zhí)行操作: (SP)←(SP)-2, ((SP)+1,(SP))←(CS) (SP)←(SP)-2, ((SP)+1,(SP))←(IP)
7、 (IP)←(EA) (CS)←(EA+2),7,RET返回指令 段內(nèi)返回:RET 執(zhí)行操作: (IP)←((SP)+1,(SP)) (SP)←(SP)+2段內(nèi)帶立即數(shù)返回:RET EXP段間返回:RET 執(zhí)行操作: (IP)←((SP)+1,(SP))
8、 (SP)←(SP)+2 (CS)←((SP)+1,(SP)) (SP)←(SP)+2段間帶立即數(shù)返回:RET EXP,8,(AX),(BX),(CX),例:帶立即數(shù)返回code segmentmain proc far …… push ax pu
9、sh bx push cx call sub …… retmain endpsub proc near …… ret 6sub endpcode ends,(SP)?,,,( IP ),,,高地址,低地址,* *,9,對簡化段定義格式,在微型、小型和緊湊存儲模式下,過程的缺省屬性為near;在中型、大
10、型和巨型存儲模式下,過程的缺省屬性為far對完整段定義格式,過程的缺省屬性為near用戶可以在過程定義時用near或far改變?nèi)笔傩?二、使用子程序,CALL 子程序名 / 子程序入口地址 子程序名是一個(全局標(biāo)識符)常量地址。,子程序調(diào)用(中斷調(diào)用):隱含使用堆棧保存返回地址call near ptr subprog ;段內(nèi)調(diào)用 (1) 保存返回地址 (2) 轉(zhuǎn)子程序
11、 (EIP) ← subprog的偏移地址call far ptr subprog ;段間調(diào)用 (1) 保存返回地址 (2) 轉(zhuǎn)子程序 (CS) ← subprog 的段地址 (EIP) ← subprog 的偏移地址,10,11,int n (n : 中斷類型號) (1) 保存現(xiàn)場和返回地址
12、 (2) 轉(zhuǎn)中斷處理程序 (IP) ← (n*4) (CS) ← (n*4+2)子程序返回 (1) ret (2) ret imm (3) iret (中斷返回),12,code segment main proc far ...... call subr1 ...... ret
13、subr1 proc near ...... retsubr1 endpmain endpcode ends,例6.1 調(diào)用程序和子程序在同一代碼段中,code segment main proc far ...... call subr1 ...... retmain
14、endpsubr1 proc near ...... retsubr1 endpcode ends,(可嵌套定義),,13,seg1 segment subt proc far ...... ret subt endp ......
15、 call subt ......seg1 endsseg2 segment ...... call subt ......seg2 ends,,代碼段seg1,,代碼段seg2,例6.2 調(diào)用程序和子程序不在同一代碼段中,三、 增強功能的過程(子程序)定義子程序名
16、 PROC [屬性] [USES 寄存器列表] [,參數(shù)表]LOCAL 局部變量表……ret子程序名 ENDP,距離:NEAR/FAR (微、小、緊湊和平坦模式為NEAR,中、大和巨模式為FAR)語言類型:C、BASIC、PASCAL、FORTRAN、可見性:Private / Public可以使用宏名指定屬性,參數(shù)名[:類型]; 缺省類型為DWORD,,,14,15,入口參數(shù)(輸入?yún)?shù)):主程序提供給子
17、程序出口參數(shù)(輸出參數(shù)):子程序返回給主程序參數(shù)的形式:① 數(shù)據(jù)本身(傳值) ② 數(shù)據(jù)的地址(傳址),四、 參數(shù)傳遞約定,C語言用 AL / AX / DX:AX /EAX / EDX:EAX 返回整數(shù),用浮點堆棧棧頂返回實數(shù)。匯編語言一般建議使用C語言約定。,①通過寄存器傳送參數(shù)②通過存儲器傳送參數(shù) *子程序和調(diào)用程序在同一程序模塊中,則子程序可直接訪問模塊中的變量。 *子程序和調(diào)
18、用程序不在同一程序模塊中,則有兩種傳送方式:建立公共數(shù)據(jù)區(qū) 使用外部符號③通過地址表傳送參數(shù)地址④通過堆棧傳送參數(shù)或參數(shù)地址,傳遞的方法:,17,subnameproc ;具有缺省屬性的subname過程push esi;保護寄存器:順序壓入堆棧push edi;以 esi/edi/ebx 為例push ebx…;過程體
19、pop ebx;恢復(fù)寄存器:逆序彈出堆棧pop edipop esiret;過程返回subnameendp;過程結(jié)束,保護現(xiàn)場,恢復(fù)現(xiàn)場,五、利用堆棧(保護寄存器、臨時變量和臨時數(shù)據(jù)),,,七、高級語法,函數(shù)原型聲明子程序名 PROTO [[距離] [語言],] [參數(shù) : 類型] [, …]子程序調(diào)用偽操作符INVOKE 子程序名 [, 實參表]參數(shù)符合 PUSH 的操作數(shù)類型,可以
20、使用 ADDR 取得變量的地址(隱含地使用 LEA eax, Var)定義局部變量LOCAL 變量名[重復(fù)數(shù)量][:類型] [, …]定義和使用外部標(biāo)識PUBLIC 標(biāo)識符 [, …]EXTERN 標(biāo)識符:類型 [, …],18,19,例題 :實現(xiàn)光標(biāo)回車換行的子程序,dpcrlfproc;子程序開始push ax;保護寄存器AX和DXpush dxmov dl, 0dh
21、;顯示回車mov ah, 2int 21hmov dl, 0ah;顯示換行mov ah, 2int 21hpop dx;恢復(fù)寄存器DX和AXpop axret;子程序返回dpcrlfendp;過程結(jié)束,20,例題 :實現(xiàn)al內(nèi)容(兩個十六進制數(shù))的顯示的子程序,ALdisp proc ;子程序開始 push ax
22、 ;過程中使用了AX、CX和DX push cx push dx push ax ;暫存ax mov dl,al ;轉(zhuǎn)換al的高4位 mov cl,4 shr dl,cl or dl,30h ;al高4位變成3 cmp dl,39h jb
23、e aldisp1 add dl,7 ;是0Ah~0Fh,還要加上7aldisp1: mov ah,2 ;顯示 int 21h,21,例題 :實現(xiàn)al內(nèi)容(兩個十六進制數(shù))的顯示的子程序,pop dx ;恢復(fù)原ax值到dx and dl, 0fh ;轉(zhuǎn)換al的低4位
24、 or dl, 30h cmp dl, 39h jbe aldisp2 add dl,7aldisp2: mov ah,2 ;顯示 int 21h pop dx pop cx pop ax ret;過程返回AL
25、dispendp,22,例題 :實現(xiàn)al內(nèi)容(兩個十六進制數(shù))的顯示的子程序,;主程序mov bx,offset array;調(diào)用程序段開始mov cx,countdisplp:mov al,[bx]call Aldisp;調(diào)用顯示過程mov dl, ',’;顯示一個逗號,分隔數(shù)據(jù)mov ah, 2int 21hinc bxloop displp;調(diào)用程
26、序段結(jié)束.exit 0...;過程定義end,23,decihex segment ; 10?16 assume cs: decihexmain proc far push ds sub ax, ax push axrepeat: ca
27、ll decibin ; 10?2 call crlf call binihex ; 2?16 call crlf jmp repeat retmain endp,例6.3 十進制到十六進制的轉(zhuǎn)換程序 (通過寄存器傳送變量),24,dec
28、ibin proc near ; 10?2 mov bx, 0 ; bx為傳遞參數(shù)newchar: mov ah, 1 int 21h sub al, 30h jl exit ; 9退出 cbw
29、 xchg ax, bx mov cx, 10d mul cx xchg ax, bx add bx, ax jmp newcharexit: retdecibin endp,例6.3 十進制到十六進制的轉(zhuǎn)換程序,25,binihex proc near
30、 ; 2?16 mov ch, 4rotate: mov cl, 4 rol bx, cl mov al, bl and al, 0fh add al, 30h cmp al, 3ah
31、 jl printit add al, 7h ; ‘A’~’F’ printit: mov dl, al mov ah, 2 int 21h dec ch
32、 jnz rotate retbinihex endp,例6.3 十進制到十六進制的轉(zhuǎn)換程序,26,crlf proc near mov dl, 0dh mov ah, 2 int 21h mov dl, 0ah mov ah, 2
33、 int 21h retcrlf endpdecihex ends end main,例6.3 十進制到十六進制的轉(zhuǎn)換程序,27,data segment ary dw 1,2,3,4,5,6,7,8,9,10 count dw 10 sum dw ?data e
34、ndscode segmentmain proc far assume cs:code, ds:datastart: push ds sub ax, ax push ax mov ax, data mov ds, ax call near ptr proadd
35、 retmain endp,例6.4 累加數(shù)組中的元素(直接訪問變量),28,proadd proc near push ax push cx push si lea si, ary mov cx, count xor ax, ax,例6.4 累加數(shù)組中的元素(直接訪問變量),next: add ax
36、, [si] add si, 2 loop next mov sum, ax pop si pop cx pop ax retproadd endpcode ends end start,,,,,29,data segmentary dw 1,2,3,4,5,6,7,8,9,10count dw 10sum
37、 dw ?ary1 dw 10,20,30,40,50,60,70,80,90,100count1 dw 10sum1 dw ?data ends,如果數(shù)據(jù)段定義如下:,*如果直接訪問內(nèi)存變量,那么累加數(shù)組ary和數(shù)組ary1中的元素不能用同一個子程序proadd,例6.4 累加數(shù)組中的元素(直接訪問變量),30,table dw 3 dup (?)
38、 ; 定義地址表 code segmentmain proc far assume cs:code, ds:datastart: push ds sub ax, ax push ax mov ax, data mov ds, ax mov table, offset
39、ary mov table+2, offset count mov table+4, offset sum mov bx, offset table call proadd ret main endp,例6.4 累加數(shù)組中的元素,通過地址表傳送變量地址,,,proadd proc near
40、 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 loo
41、p next mov [di], ax pop di pop si pop cx pop ax retproadd endpcode ends end start,(si),(di),32,例6.4 累加數(shù)組中的元素(通過堆棧傳送變量地址),data segment ary dw 10,
42、20,30,40,50,60,70,80,90,100 count dw 10 sum dw ?data endsstack segment dw 100 dup (?) tos label wordstack ends,code1 segmentmain proc far
43、 assume cs:code1, ds:data, ss:stackstart: mov ax, stack mov ss, ax mov sp, offset tos push ds sub ax, ax push ax mov ax, data mov ds,
44、 ax,,mov bx, offset ary push bx mov bx, offset count push bx mov bx, offset sum push bx call far ptr proadd retmain endpcode1 ends,,code2 segment assume
45、 cs: code2proadd proc far push bp mov bp, sp push ax push cx push si push di mov si, [bp+0ah] mov di, [bp+8] mov cx, [di] mov di, [bp+6],x
46、or ax, axnext: add ax, [si] add si, 2 loop next mov [di], ax pop di pop si pop cx pop ax pop bp ret 6proadd endpcode2 ends
47、 end start,,,,堆棧示意,,35,例:求,ADDSUM PROC MOV AX,5 MOV DX,0 MOV CX,AXNEXTAX: PUSH CX CALL SUM ADD DX,AX POP CX LOOP NEXTAX MOV AH,4CH INT 21H
48、 RETADDSUM ENDP,SUM PROC MOV AX,0NEXT: ADD AX,CX LOOP NEXT RETSUM ENDPEND ADDSUM,36,例:判斷閏年的程序,data segment ;定義數(shù)據(jù)段 infon db 0dh, 0ah, 'Please input a year: $' Y
49、 db 0dh, 0ah, 'This is a leap year! $' N db 0dh, 0ah, 'This is not a leap year! $' w dw 0 buf db 8 db ? db 8 dup(?)data e
50、ndsstack_sg segment stack db 200 dup(0)stack_sg ends,37,例:判斷閏年的程序,code segment assume ds:data, ss:stack_sg, cs:codestart: mov ax,data mov ds,ax lea dx, in
51、fon ;在屏幕上顯示提示信息 mov ah,9 int 21h lea dx,buf ;從鍵盤輸入年份字符串 mov ah,10 int 21h,38,例:判斷閏年的程序,mov cl, [buf+1] ;取實際輸入的字符數(shù) lea di,buf+2
52、 ;DI指向輸入串的起始地址 call datacate call ifyears jc a1 lea dx,n mov ah,9 int 21h jmp exita1: lea
53、 dx, y mov ah, 9 int 21hexit: mov ah, 4ch int 21h,39,;十進制數(shù)轉(zhuǎn)換成二進制,datacate proc near mov ch,0 mov si,di mov
54、 bl,10 mov bh,0 mov ax,0 ;累加器清“0”l1: imul bx sub byte ptr [si],30h add al,byte p tr [si] ad
55、c ah,0 inc si loop l1 mov w,ax ret datacate endp,鍵盤輸入字符串‘123’↓ 則, (AX)=(((0×10)+1)×10+2)×10+3,40,;判斷閏年,ifye
56、ars proc near push bx push cx push dx mov ax,w mov cx,ax mov dx,0 mov bx,4 div bx
57、 cmp dx,0 jnz lab1 mov ax,cx mov bx,100 div bx cmp dx,0,jnz lab2 mov ax,cx mov bx,
58、400 div bx cmp dx,0 jz lab2 lab1: clc jmp lab3 lab2: stc lab3: pop dx pop cx pop bx
59、 ret ifyears endpcode ends end start,,41,將二進制數(shù)按位轉(zhuǎn)換成相應(yīng)的ASCII碼字符串,將一個給定的二進制數(shù)按位轉(zhuǎn)換成相應(yīng)的ASCII碼字符串,送到指定的存儲單元并顯示。如二進制數(shù)10010011轉(zhuǎn)換成字符串為‘10010011’。要求將轉(zhuǎn)換過程寫成子程序,且子程序應(yīng)具有較好的通用性,而必須能實現(xiàn)對8位和16位二進制數(shù)的轉(zhuǎn)換。,42,將二進制數(shù)按位轉(zhuǎn)換成相應(yīng)的ASCII碼
60、字符串,入口參數(shù):DX存放待轉(zhuǎn)換的二進制數(shù)CX存放待轉(zhuǎn)換數(shù)的位數(shù)(8位或16位)DI存放ASCII碼首地址出口參數(shù):轉(zhuǎn)換后的字符串存放在以DI作指針的字節(jié)存貯區(qū)中程序如下:DATASEGMENTNUM8DB93HNUM16DW0ABCDHASCBUFDB20DUP(0)DATAENDS,43,將二進制數(shù)按位轉(zhuǎn)換成相應(yīng)的ASCII碼字符串,CODESEGMENTASSUME DS:DATA,CS
61、:CODE, SS:STACKSTART:MOVAX,DATAMOVDS,AXMOVDX,0MOVDL,NUM8;轉(zhuǎn)換二進制數(shù)送DXMOVCX,8;置位數(shù)8LEADI,ASCBUF;字符串首址→DICALLBTASC;調(diào)用子程序BTASCMOV[DI],BYTE PTR 0DHMOV[DI+1],BYTE PTR 0AH,44,將二進制數(shù)按位轉(zhuǎn)換成相應(yīng)的ASCII碼字
62、符串,MOV[DI+2],BYTE PTR ‘$’LEADX,ASCBUFMOVAH,9INT21HMOVDX,NUM16MOVCX,16;置位數(shù)16LEADI,ASCBUFCALLBTASC MOV[DL],BYTE PTR 0DHMOV[DL+1],BYTE PTR 0AHMOV[DL+2],BYTE PTR ‘$’ ;顯示轉(zhuǎn)換后的字符串
63、LEADX, ASCBUF MOVAH,9 INT21H,,45,將二進制數(shù)按位轉(zhuǎn)換成相應(yīng)的ASCII碼字符串,BTASCPROCPUSHAX;保存AXMOVAL,0CMPCX,8;比較8位數(shù)JNEL1;直接轉(zhuǎn)換16位數(shù)MOVDH,DL;8位數(shù)轉(zhuǎn)換送DHL1:ROLDX,,1;DX最高位移入CFRCLAL,1;CF移入AL
64、最低位ADDAL,30HMOV[DI],AL INCDILOOPL1POPAXRETBTASCENDPCODEENDSENDSTART,46,,子程序的嵌套主程序 子程序A 子程序B proc_A
65、 proc_B…... …… …... call proc_A call proc_B …...…… …… ret
66、 ret,,,,,遞歸子程序:n!,6.2 嵌套與遞歸子程序,47,遞歸方法求n!(1≤n≤8),;定義數(shù)據(jù)段和堆棧段data segment n dw0 result dw0data endsstack1 segmentdw200 dup (0)toslabel wordstac
67、k1 ends,48,主程序,code segment assume cs:code,ds:data,ss:stack1main proc far mov ax, stack1 mov ss, ax mov sp, offset tos push ds xor ax, ax push ax
68、 mov ax, data mov ds, ax call near ptr decbin ;輸入一個正整數(shù) call near ptr crlf ;輸出一個回車換行,mov [n], bx ;mov ax,bx push bx call near ptr factorial
溫馨提示
- 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 程序結(jié)構(gòu).dwg
- 程序結(jié)構(gòu).dwg
- 程序結(jié)構(gòu).dwg
- 程序結(jié)構(gòu).dwg
- 程序結(jié)構(gòu).dwg
- 程序結(jié)構(gòu).dwg
- 程序結(jié)構(gòu).dwg
- 程序結(jié)構(gòu).dwg
- 程序結(jié)構(gòu)框圖.dwg
- 程序結(jié)構(gòu)框圖.dwg
- 程序結(jié)構(gòu)框圖.dwg
- 程序結(jié)構(gòu)框圖.dwg
- 程序結(jié)構(gòu)框圖.dwg
- 程序結(jié)構(gòu)框圖.docx
- 程序結(jié)構(gòu)框圖.dwg
- c#程序結(jié)構(gòu)
- 總程序結(jié)構(gòu)框圖.dwg
- 總程序結(jié)構(gòu)框圖.dwg
- 總程序結(jié)構(gòu)框圖.dwg
- 總程序結(jié)構(gòu)框圖.dwg
評論
0/150
提交評論