版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年飯店裝修協(xié)議核心內(nèi)容一覽
- 2024年柴油產(chǎn)品銷售協(xié)議文本
- 2024辦公室員工固定期限協(xié)議
- 2024年防腐木建筑協(xié)議樣本
- 2024常年蔬菜種植業(yè)務(wù)協(xié)議樣書
- 629702024短期貸款協(xié)議模板
- 2024年項(xiàng)目經(jīng)理個(gè)人勞動協(xié)議樣本
- 2024年門禁系統(tǒng)安裝及維護(hù)服務(wù)協(xié)議
- 健康女性課件教學(xué)課件
- 北師大版八年級生物下冊全冊教案
- 鎂合金行業(yè)發(fā)展分析及投資前景預(yù)測報(bào)告
- 室內(nèi)維修方案
- 小學(xué)信息技術(shù)課堂與學(xué)科教學(xué)逆向融合管見 論文
- 軍士生生涯規(guī)劃
- 北師大版數(shù)學(xué)三年級上冊全冊分層作業(yè)設(shè)計(jì)含答案
- 認(rèn)知障礙人員培訓(xùn)課件
- 中國艾滋病現(xiàn)狀
- 國際業(yè)務(wù)基礎(chǔ)知識培訓(xùn)
- 急診科中的老年病急癥救治
- 亞馬遜賬戶安全培訓(xùn)內(nèi)容
- 生活區(qū)消防安全培訓(xùn)課件
評論
0/150
提交評論