山東大學(xué)匯編語言程序設(shè)計(jì)課件第6章_第1頁
山東大學(xué)匯編語言程序設(shè)計(jì)課件第6章_第2頁
山東大學(xué)匯編語言程序設(shè)計(jì)課件第6章_第3頁
山東大學(xué)匯編語言程序設(shè)計(jì)課件第6章_第4頁
山東大學(xué)匯編語言程序設(shè)計(jì)課件第6章_第5頁
已閱讀5頁,還剩37頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第六章子程序結(jié)構(gòu)6.1子程序的設(shè)計(jì)方法6.2子程序的嵌套6.3子程序舉例主程序子程序:子程序:在一個(gè)實(shí)際程序中,有些操作要執(zhí)行多次, 把要重復(fù)執(zhí)行(subroutine)操作編為子程序。 也常把一些常用的操作標(biāo)準(zhǔn)化、通用化的子程序。主程序(Mainprogram)——往往要調(diào)用子程序 或處理中斷, 暫停主程序,執(zhí)行子程序或中斷服務(wù)程序。模塊化程序設(shè)計(jì)方法模塊化程序設(shè)計(jì)方法按照各部分程序所實(shí)現(xiàn)的不同功能把程序劃分成多個(gè)模塊,各個(gè)模塊在明確各自的功能和相互間的連接約定后,就可以分別編制和調(diào)試程序,最后再把他們連接起來,形成一個(gè)大程序。

子程序結(jié)構(gòu)是模塊化程序設(shè)計(jì)的基礎(chǔ)調(diào)用子程序時(shí)需保留內(nèi)容:①調(diào)用子程序:將CALL下條指令地址即IP值保留下來 (8086中段寄存器CS和指令指針I(yè)P),才能保證子程序執(zhí)行完后準(zhǔn)確返回主程序繼續(xù)執(zhí)行。②執(zhí)行子程序時(shí),通常用到內(nèi)部寄存器,執(zhí)行結(jié)果會影響標(biāo)志位,必須在調(diào)用子程序之前將現(xiàn)狀保護(hù)起來。③子程序嵌套或子程序遞歸(自調(diào)自)保留許多信息,而且保證正確返回(且后進(jìn)先出)。

后保留先取出原則(即LIFO-LASTInFirstout)。6.1子程序的設(shè)計(jì)方法

6.1.1過程(子程序)定義偽操作過程名PROC屬性……過程名ENDPNEAR(FAR)與標(biāo)號類似,是子程序入口的符號地址CALL和RET指令的屬性(1)都有NEAR和FAR兩種屬性(2)在80x86匯編程序中用PROC的類型屬性來確定過程屬性的確定原則:NEAR屬性:調(diào)用程序和子程序在同一代碼段中(段內(nèi)調(diào)用)FAR屬性:調(diào)用程序和子程序不在同一代碼段中(段間調(diào)用)codesegment

mainprocfar......

callsubr1......retmainendpsubr1procnear......retsubr1endpcodeendscodesegment

mainprocfar......callsubr1......retsubr1procnear......retsubr1endpmainendpcodeends例6.1調(diào)用程序和子程序在同一代碼段中把過程寫成嵌套的形式NEAR例6.2調(diào)用程序和子程序不在同一代碼段中

segxsegment

......

subtprocfar......retsubtendp......

callsubt......

segxendsends

segysegmentsegment......

callsubt......

segyendsendsFARFAR

子程序調(diào)用(中斷調(diào)用):隱含使用堆棧保存返回地址callnearptrsubp

(1)保存返回地址

(2)轉(zhuǎn)子程序(IP)←subp的偏移地址callfarptrsubp

(1)保存返回地址

(2)轉(zhuǎn)子程序

(CS)←subp的段地址

(IP)←subp的偏移地址

(IP)(SP)→

(IP)(SP)→

(CS)6.1.2子程序的調(diào)用和返回(IP)(SP)→

(CS)(PSW)intn(n:中斷類型號)

(1)保存現(xiàn)場和返回地址(2)轉(zhuǎn)中斷處理程序

(IP)←(n*4)(CS)←(n*4+2)子程序返回(中斷返回):(1)ret(2)iretint21H注意:1、PROC的屬性2、堆棧狀態(tài)

CALL調(diào)用指令(僅以16位為例)段內(nèi)直接近調(diào)用:CALLDST執(zhí)行操作:PUSH(IP)(IP)←(IP)+16位位移量段內(nèi)間接近調(diào)用:CALLDST執(zhí)行操作:PUSH(IP) (IP)←(EA)CALL與RET指令的復(fù)習(xí)段間直接遠(yuǎn)調(diào)用:CALLDST執(zhí)行操作:PUSH(CS) PUSH(IP)(IP)←DST偏移地址(CS)←DST段地址段間間接遠(yuǎn)調(diào)用:CALLDST執(zhí)行操作:PUSH(CS) PUSH(IP)(IP)←(EA)(CS)←(EA+2)CALL與RET指令的復(fù)習(xí)

RET返回指令段內(nèi)近返回:RET執(zhí)行操作:(IP)POP()段內(nèi)近帶立即數(shù)近返回:RETEXP執(zhí)行操作:(IP)POP() (SP)←(SP)+D16(由EXP計(jì)算得到)帶立即數(shù)用于調(diào)用程序調(diào)用子程序時(shí)的參數(shù)傳遞CALL與RET指令的復(fù)習(xí)段間遠(yuǎn)返回:RET執(zhí)行操作:(IP)←POP()(CS)←POP()段間帶立即數(shù)遠(yuǎn)返回:RETEXP執(zhí)行操作:(IP)←POP()(CS)←POP() (SP)←(SP)+D16(由EXP計(jì)算得到)CALL與RET指令的復(fù)習(xí)6.1.3保存與恢復(fù)寄存器1、為什么要有保存與恢復(fù)寄存器的操作?

調(diào)用程序和子程序所使用的堆棧會發(fā)生沖突,為了避免運(yùn)行發(fā)生錯(cuò)誤

2、如何保存和恢復(fù)寄存器?1、通常使用PUSH保存和POP恢復(fù)2、286+可以使用PUSHA/POPA,386+可以使用PUSHAD/POPAD3、增強(qiáng)功能中的USES字段3、要對哪些寄存器保存和恢復(fù)?(1)子程序子程序中用到的寄存器應(yīng)該保存(2)負(fù)責(zé)傳送參數(shù)的寄存器則不一定需要保存,特別是用來向主程序回送結(jié)果的寄存器subtprocfarpushaxpushbxpushcxpushdx......popdxpopcxpopbxpopaxretsubtendp保存恢復(fù)例:參數(shù)傳送的方式

(1)通過寄存器傳送參數(shù)(2)通過存儲器傳送參數(shù)

*子程序和調(diào)用程序在同一程序模塊中,則子程序可直接訪問模塊中的變量。

(3)通過地址表傳送參數(shù)地址(4)通過堆棧傳送參數(shù)或參數(shù)地址6.1.4子程序的參數(shù)傳送計(jì)算機(jī)處理信息時(shí),其對象都是二進(jìn)制數(shù)。外設(shè)(顯示器、打印機(jī)、鍵盤等)用ASCII碼與CPU進(jìn)行信息傳送。例如:(1)在鍵盤上按下某一字符鍵(如’9’),鍵盤接口 向鍵盤緩沖區(qū)送去的是該字符的ASCII碼(如 39H),而不是送數(shù)字09H。

(2)在文本方式下,要在顯示器上顯示某一字符(如’A’),須將該字符的ASCII碼(如41H)送顯示緩沖區(qū),不是送數(shù)字0AH?;A(chǔ)知識復(fù)習(xí)例6.3十進(jìn)制到十六進(jìn)制的轉(zhuǎn)換程序

(通過寄存器傳送變量)decihexsegment;1016assumecs:decihexmainprocfarpushdssubax,axpushaxrepeat:calldecibin;102

callcrlf

callbinihex;216

callcrlfjmprepeat

retmainendpdecibinprocnear;102movbx,0newchar:movah,1int21hsubal,30hjlexit;<0退出cmpal,9djgexit;>9退出cbwxchgax,bxmovcx,10dmulcxxchgax,bxaddbx,axjmpnewcharexit:retdecibinendp鍵盤輸入binihexprocnear;216movch,4rotate:movcl,4rolbx,clmoval,blandal,0fhaddal,30hcmpal,3ahjlprintitaddal,7hprintit:movdl,almovah,2int21hdecchjnzrotate

retbinihexendpcrlfprocnearmovdl,0dhmovah,2int21hmovdl,0ahmovah,2int21hretcrlfendpdecihexendsendmain例6.4累加數(shù)組中的元素(直接訪問變量)datasegmentarydw1,2,3,4,5,6,7,8,9,10countdw10sumdw?dataendscodesegmentmainprocfarassumecs:code,ds:datastart:pushdssubax,axpushaxmovax,datamovds,axcallnearptrproaddretmainendpproaddprocnearpushaxpushcxpushsi

leasi,arymovcx,countxorax,axnext:addax,[si]addsi,2loopnextmovsum,axpopsipopcxpopaxretproaddendpcodeendsendstartdatasegmentarydw1,2,3,4,5,6,7,8,9,10countdw10sumdw?ary1dw10,20,30,40,50,60,70,80,90,100count1dw10sum1dw?dataends如果數(shù)據(jù)段定義如下:*如果直接訪問內(nèi)存變量,那么累加數(shù)組ary和數(shù)組ary1中的元素不能用同一個(gè)子程序proadd例6.4累加數(shù)組中的元素(通過地址表傳送變量地址)datasegmentarydw10,20,30,40,50,60,70,80,90,100countdw10sumdw?

tabledw3dup(?);地址表dataendscodesegmentmainprocfarassumecs:code,ds:datastart:pushdssubax,axpushaxmovax,datamovds,ax

movtable,offsetarymovtable+2,offsetcountmovtable+4,offsetsummovbx,offsettablecallproaddretmainendpproaddprocnear

pushaxpushcxpushsipushdi

movsi,[bx]movdi,[bx+2]movcx,[di]movdi,[bx+4]

xorax,axnext:addax,[si]addsi,2loopnext

mov[di],ax

popdipopsipopcxpopax

retproaddendpcodeendsendstart

ary100000

200002

30

40

50

60

70

80

90

100

count100014

sum?0016

table

00000018(bx)00140016(si)(di)例6.4累加數(shù)組中的元素(通過堆棧傳送變量地址)

datasegmentarydw10,20,30,40,50,60,70,80,90,100countdw10sumdw?dataendsstacksegmentdw100dup(?)

toslabelwordstackendscode1segmentmainprocfarassumecs:code1,ds:data,ss:stackstart:

movax,stackmovss,axmovsp,offsettospushdssubax,axpushaxmovax,datamovds,ax

movbx,offsetarypushbxmovbx,offsetcountpushbxmovbx,offsetsumpushbxcallfarptrproaddretmainendpcode1endscode2segmentassumecs:code2proaddprocfar

pushbpmovbp,sp

pushaxpushcxpushsipushdi

movsi,[bp+0ah]movdi,[bp+8]movcx,[di]movdi,[bp+6]

(bp)+0a0000

(sp)(di)

(si)

(cx)

(ax)

(bp)(bp)

(ip)

(cs)

(bp)+60016

(bp)+80014

0

(ds)

xorax,axnext:addax,[si]addsi,2loopnext

mov[di],ax

popdi

popsipopcxpopax

popbp

ret6proaddendpcode2endsendstart低地址高地址結(jié)構(gòu)偽操作STRUC:定義一種可包含不同類型數(shù)據(jù)的結(jié)構(gòu)模式格式:結(jié)構(gòu)名STRUC字段名1DB?字段名2DW?字段名3DD?……

結(jié)構(gòu)名ENDS

例:學(xué)生個(gè)人信息STUDENT_DATASTRUC;4個(gè)字段,18個(gè)字節(jié)的結(jié)構(gòu)模式

NAMEDB5DUP(?)IDDW0AGEDB?DEPDB10DUP(?)STUDENT_DATAENDS結(jié)構(gòu)預(yù)置語句:把結(jié)構(gòu)中各字段的數(shù)據(jù)存入存儲器,并可重新輸入字符串和數(shù)值。格式:變量名結(jié)構(gòu)名<>變量名結(jié)構(gòu)名<預(yù)賦值說明>例:S991000STUDENT_DATA<>S991001STUDENT_DATA<,1001,22,>STUDENTSTUDENT_DATA100DUP(<>)訪問結(jié)構(gòu)數(shù)據(jù)變量:

MOVAL,S991000.NAME[SI]MOVAL,[BX].NAME[SI]MOVAL,STUDENT+4*18.NAME[SI]例6.4累加數(shù)組中的元素(通過堆棧傳送變量地址)stack_strcstrucsave_bpdw?save_cs_ipdw2dup(?)par3_addrdw?par2_addrdw?par1_addrdw?stack_strcendsproaddprocfar

pushbpmovbp,sp

pushaxpushcxpushsipushdi

movsi,[bp].par1_addrmovdi,[bp].par2_addrmovcx,[di]

movdi,[bp].par3_addrxorax,axnext:addax,[si]addsi,2loopnextmov[di],ax

popdipopsipopcxpopaxpopbpret6proaddendp

0000par1_addr

(sp)(di)

(si)

(cx)

(ax)

(bp)(bp)

(ip)

(cs)

0016par3_addr

0014par2_addr

0

(ds)模塊的概念模塊化程序設(shè)計(jì)模塊每個(gè)模塊可以單獨(dú)成一個(gè)文件多個(gè)模塊相連 a.各模塊仍有個(gè)各自的分段b.有時(shí)把幾個(gè)分段連成一個(gè)段外部符號與局部符號外部符號:在一個(gè)模塊中定義,在另一個(gè)模塊中引用的符號局部符號:在一個(gè)模塊中定義,又在本模塊中引用的符號與外部符號有關(guān)的兩個(gè)偽操作(PUBLIC,EXTRN)PUBLIC偽操作功能:定義該符號為外部符號格式:PUBLIC符號,[符號,…]EXTRN偽操作功能:在模塊中使用外部符號格式:EXTRN符號:類型,[符號:類型,…]PUBLIC和EXTRN的使用1、必須相匹配必須先用PUBLIC定義要使用的外部符號,然后才能用EXTRN來宣布在模塊中使用PUBLIC定義了的外部符號;否則將出錯(cuò)。2、外部符號不能重名

但不同模塊中的局部符號允許重名多個(gè)模塊之間的參數(shù)傳遞問題具體:1、使用公共數(shù)據(jù)段(COMMON屬性)2、使用外部符號注意變量或標(biāo)號的段地址,必要時(shí)要做動態(tài)修改3、使用段的PUBLIC屬性利用外部符號與SEGMENT的類型屬性實(shí)現(xiàn)參數(shù)傳遞6.1.5增強(qiáng)功能的過程定義偽操作格式:過程名PROC[屬性字段][USES寄存器列表][,參數(shù)字段] ……過程名ENDP子程序的嵌套主程序

子程序A

子程序B

proc_A

proc_B…...………...

callproc_Acallproc_B

…...…………ret

ret遞歸子程序:n!6.2嵌套與遞歸子程序1.嵌套:2.嵌套深度:3.遞歸:對應(yīng)與數(shù)學(xué)上的遞歸,很有用4.遞歸子程序:5.堆棧溢出原因:堆棧段在定義時(shí)大小已經(jīng)確定 堆棧上溢:堆棧已滿,還想存入數(shù)據(jù) 堆棧下溢:堆棧已空,還想取出數(shù)據(jù)幾個(gè)概念例計(jì)算n!framestrucsave_bpdw?save_cs_ipdw2dup(?)ndw?result_addrdw?frameendsdatasegmentn_vdw3resultdw?dataendsstacksegmentdw128dup(0)toslabelwordstackendscodesegmentmainprocfarassumecs:code,ds:data,ss:stackstart:

movax,stackmovss,axmovsp,offsettos

pushdssubax,axpushaxmovax,datamovds,ax

movbx,offsetresultpushbxmovbx,n_vpushbx

callfarptrfactretmainendpcodeendscode1segmentassumecs:code1factprocfar

pushbpmovbp,sp

pushbxpushaxmovbx,[bp].result_addrmovax,[bp].n

cmpax,0

jedone

pushbxdecax

pushax

callfarptrfactmovbx,[bp].result_addrmovax,[bx]

mul[bp].njmpshortreturndone:movax,1return:mov[bx],ax

popaxpopbxpopbpret4factendpcode1endsRESULT的地址

0CODE1的(CS)CODE1中的(IP)(BP)(BX)(AX)第4幀RESULT的地址

1CODE1的(CS)CODE1中的(IP)(BP)(BX)(AX)第3幀RESULT的地址

2CODE1的(CS)CODE1中的(IP)(BP

溫馨提示

  • 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

提交評論