




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、5.1子程序子程序 5.2參數(shù)的傳遞參數(shù)的傳遞 5.3嵌套和遞歸子程序嵌套和遞歸子程序 5.4多模塊程序設(shè)計(jì)多模塊程序設(shè)計(jì) 5.5匯編語言與匯編語言與C語言混合編程語言混合編程5.6DOS和和BIOS調(diào)用調(diào)用IPCSn指令存放在內(nèi)存中指令存放在內(nèi)存中,處理器從內(nèi)存取指令分析執(zhí)行處理器從內(nèi)存取指令分析執(zhí)行n指令一般是從前到后順序執(zhí)行的指令一般是從前到后順序執(zhí)行的nCPU執(zhí)行當(dāng)前指令時(shí),執(zhí)行當(dāng)前指令時(shí),IP被更改為下條指令的地址,被更改為下條指令的地址,CS和和IP不能用不能用MOV等傳送指令直接修改等傳送指令直接修改n跳轉(zhuǎn)類指令可以通過修改跳轉(zhuǎn)類指令可以通過修改IP和和CS實(shí)現(xiàn)程序的不同流程實(shí)現(xiàn)
2、程序的不同流程n本章的本章的子程序調(diào)用和返回指令也是通過修改子程序調(diào)用和返回指令也是通過修改IP和和CS實(shí)現(xiàn)的實(shí)現(xiàn)的。回顧:專用寄存器回顧:專用寄存器下一條指令的段地址下一條指令的段地址下一條指令的偏移地址下一條指令的偏移地址 把程序需要完成的任務(wù)分解為若干個(gè)把程序需要完成的任務(wù)分解為若干個(gè)“子任子任務(wù)務(wù)”,每個(gè),每個(gè)“子任務(wù)子任務(wù)”由一段相對(duì)獨(dú)立的程序完成,由一段相對(duì)獨(dú)立的程序完成,稱為稱為“子程序子程序”。 子程序也稱為子程序也稱為“過程過程”(ProcedureProcedure),在高級(jí)),在高級(jí)語言里還稱作語言里還稱作“函數(shù)函數(shù)”(FunctionFunction)。)。子程序(子程
3、序(Subroutine )概念)概念一個(gè)簡單子程序一個(gè)簡單子程序;顯示回車換行的子程序顯示回車換行的子程序dispcrlf proc nearmov ah,02h; 2號(hào)子功能號(hào)子功能 mov dl, 0dh; 回車的回車的ascii碼碼int 21h; 顯示顯示mov ah,02h; 2號(hào)子功能號(hào)子功能 mov dl, 0ah; 換行的換行的ascii碼碼int 21h; 顯示顯示ret ;返回主程序返回主程序dispcrlf endpcode segmentassume cs:codestart: call dispcrlf ;調(diào)用子程序調(diào)用子程序mov ah, 4c00h int 21
4、h ; 返回返回DOScode ends end start1.1.程序結(jié)構(gòu)清晰,提高了程序的可閱讀性和可維護(hù)性。程序結(jié)構(gòu)清晰,提高了程序的可閱讀性和可維護(hù)性。2.2.每個(gè)子程序可以獨(dú)立地進(jìn)行調(diào)試,由于程序規(guī)模較小,降每個(gè)子程序可以獨(dú)立地進(jìn)行調(diào)試,由于程序規(guī)模較小,降低了調(diào)試難度。低了調(diào)試難度。3.3.每個(gè)子程序就是一個(gè)具有特定功能的獨(dú)立的程序,提高程每個(gè)子程序就是一個(gè)具有特定功能的獨(dú)立的程序,提高程序的序的“可重用性可重用性”,提高了軟件開發(fā)效率。,提高了軟件開發(fā)效率。 子程序結(jié)構(gòu)程序的優(yōu)點(diǎn)子程序結(jié)構(gòu)程序的優(yōu)點(diǎn) 主程序: CALLPROC1 MOVAX, BX 子程序 PROC1 RET把下
5、一條指令地址壓入堆棧保存按照堆棧保存的地址返回子程序的調(diào)用和返回示意子程序的調(diào)用和返回示意近程子程序近程子程序:只能在同一個(gè)代碼段內(nèi)調(diào)用的子程序。只能在同一個(gè)代碼段內(nèi)調(diào)用的子程序。n由于主程序和子程序處于同一個(gè)代碼段,調(diào)用和返回時(shí)只需要改變由于主程序和子程序處于同一個(gè)代碼段,調(diào)用和返回時(shí)只需要改變IPIP寄存寄存器的值,器的值,CSCS寄存器的值保持不變。寄存器的值保持不變。n近程子程序的入口地址用近程子程序的入口地址用1616位段內(nèi)偏移地址表示。位段內(nèi)偏移地址表示。遠(yuǎn)程子程序遠(yuǎn)程子程序:能夠被不同代碼段的程序調(diào)用。能夠被不同代碼段的程序調(diào)用。n調(diào)用時(shí),需要調(diào)用時(shí),需要同時(shí)改變同時(shí)改變CSCS
6、和和IPIP寄存器寄存器的值,返回時(shí),需要從堆棧里彈出的值,返回時(shí),需要從堆棧里彈出3232位的返回地址送入位的返回地址送入IPIP,CSCS寄存器寄存器。n遠(yuǎn)程子程序的入口地址用遠(yuǎn)程子程序的入口地址用1616位段基址和位段基址和1616位段內(nèi)偏移地址位段內(nèi)偏移地址表示。表示。子程序的類型子程序的類型5.1.1 5.1.1 CALLCALL和和RETRET指令指令 5.1.2 5.1.2 子程序的定義子程序的定義 5.1.3 5.1.3 子程序文件子程序文件 5.1.4 5.1.4 子程序應(yīng)用子程序應(yīng)用 CALL(Call,調(diào)用)指令,調(diào)用)指令 段內(nèi)直接調(diào)用段內(nèi)直接調(diào)用格式:格式:CALL子
7、程序名子程序名 操作:操作:SP SP-2, SS:SP IP(保存(保存16位返回地址)位返回地址) IP 子程序入口的偏移地址子程序入口的偏移地址段內(nèi)間接調(diào)用段內(nèi)間接調(diào)用 格式:格式:CALLREG16/MEM16 操作:操作:SP SP-2, SS:SP IP(保護(hù)(保護(hù)16位返回地址)位返回地址) IP REG16/MEM16 段內(nèi)調(diào)用段內(nèi)調(diào)用段間直接調(diào)用段間直接調(diào)用 格式:格式:CALL FAR PTR子程序名子程序名操作:操作: SP SP-2, SS:SP CSSP SP-2, SS:SP IP (以上是保存(以上是保存32位返回地址,偏移地址保存在較小地址處)位返回地址,偏移地
8、址保存在較小地址處) IP 子程序入口的偏移地址,子程序入口的偏移地址,CS 子程序入口的段基址子程序入口的段基址段間間接調(diào)用段間間接調(diào)用格式:格式:CALL MEM32操作:操作:SP SP-2,SS:SP CS SP SP-2,SS:SP IP IP MEM32,CSMEM32+2 段間調(diào)用段間調(diào)用(1) CALLPROC1(2) LEACX,PROC1CALL CX(3) ADDR_PROC1 DW PROC1 ;子程序偏移地址;子程序偏移地址CALLADDR_PROC1;調(diào)用近程子程序;調(diào)用近程子程序PROC1(4)LEABX, ADDR_PROC1CALLWORD PTR BX;調(diào)用
9、近程子程序;調(diào)用近程子程序PROC1調(diào)用子程序的四種方法調(diào)用子程序的四種方法n 無參數(shù)段內(nèi)返回?zé)o參數(shù)段內(nèi)返回格式:格式:RET操作:操作:IP SS: SP,SP SP+2n 有參數(shù)段內(nèi)返回有參數(shù)段內(nèi)返回格式:格式:RET D16 ;其中;其中D16代表代表16位數(shù)據(jù)位數(shù)據(jù)操作:操作:IP SS:SP,SP SP+2 SP SP+D16 n無參數(shù)段間返回?zé)o參數(shù)段間返回 格式:格式:RET操作:操作:IP SS:SP, SP SP+2CS SS:SP, SP SP+2 n有參數(shù)段間返回有參數(shù)段間返回 格式:格式:RET D16 ;其中;其中D16代表代表16位數(shù)據(jù)位數(shù)據(jù)操作:操作:IP SS:S
10、P, SP SP+2CS SS:SP, SP SP+2 SP SP+D16 RETRET指令指令5.1.2 5.1.2 子程序的定義子程序的定義 子程序名子程序名PROC NEAR/FAR;子程序體子程序體RET子程序名子程序名ENDP n子程序名應(yīng)該是合法的標(biāo)識(shí)符。子程序名應(yīng)該是合法的標(biāo)識(shí)符。n用用NEARNEAR說明的是說明的是“近程子程序近程子程序”,只能在同一代碼段內(nèi)調(diào)用。,只能在同一代碼段內(nèi)調(diào)用。n用用FARFAR說明的是說明的是“遠(yuǎn)程子程序遠(yuǎn)程子程序”,能在其它代碼段調(diào)用。,能在其它代碼段調(diào)用。n子程序的遠(yuǎn)近屬性選項(xiàng)可以省略(省略時(shí)為近程子程序)子程序的遠(yuǎn)近屬性選項(xiàng)可以省略(省略時(shí)
11、為近程子程序)n子程序的定義要寫在代碼段內(nèi)子程序的定義要寫在代碼段內(nèi)例例5.1 子程序子程序FRACTOR用來計(jì)算一個(gè)數(shù)的階乘。主程序利用它用來計(jì)算一個(gè)數(shù)的階乘。主程序利用它 計(jì)算計(jì)算15的階乘,存入的階乘,存入FRA數(shù)組。數(shù)組。 DATASEGMENT FRA DW 5 DUP (?)DATAENDSCODESEGMENTASSUME CS: CODE, DS: DATASTART: MOV AX, DATAMOVDS, AXMOVBX, 1; BX中存放待求階乘的數(shù)中存放待求階乘的數(shù)MOV SI, 0MOVCX, 5; 求階乘次數(shù)(循環(huán)次數(shù))求階乘次數(shù)(循環(huán)次數(shù))LOOP0: CALL F
12、RACTOR; 調(diào)用調(diào)用FRACTOR求階乘求階乘MOVFRASI, AX; 保存結(jié)果(階乘)保存結(jié)果(階乘)ADDSI, 2INCBX; 產(chǎn)生下一個(gè)待求階乘的數(shù)產(chǎn)生下一個(gè)待求階乘的數(shù)LOOPLOOP0; 循環(huán)控制循環(huán)控制MOV AX, 4C00HINT21HCODEENDSENDSTART思考題:這個(gè)程序正確么?思考題:這個(gè)程序正確么?;輸入?yún)?shù):輸入?yún)?shù):BX:對(duì)哪個(gè)數(shù)求階乘:對(duì)哪個(gè)數(shù)求階乘;輸出參數(shù):輸出參數(shù):AX:結(jié)果:結(jié)果FRACTOR PROC NEARMOV CX, BX; 待求階乘的數(shù)轉(zhuǎn)待求階乘的數(shù)轉(zhuǎn)入入CX寄存器寄存器MOVAX, 1; “累乘器累乘器”置初值置初值1FRAL
13、OOP:MULCX; 累乘累乘LOOPFRALOOP; 循環(huán)控制循環(huán)控制RETFRACTORENDPFRACTOR PROC NEARPUSHCX; CX壓入堆棧保護(hù)壓入堆棧保護(hù) MOV CX, BX; 待求階乘的數(shù)轉(zhuǎn)待求階乘的數(shù)轉(zhuǎn)入入CX寄存器寄存器MOVAX, 1; “累乘器累乘器”置初值置初值1FRALOOP:MULCX; 累乘累乘LOOPFRALOOP; 循環(huán)控制循環(huán)控制POPCX ; 從堆棧里彈出從堆棧里彈出CX的原值的原值 RETFRACTORENDP子程序名子程序名PROC NEAR/FARPUSH; 保護(hù)現(xiàn)場(寄存器保護(hù)現(xiàn)場(寄存器/存儲(chǔ)器)存儲(chǔ)器)PUSH; 個(gè)數(shù)根據(jù)具體情況
14、決定個(gè)數(shù)根據(jù)具體情況決定;子程序主體;子程序主體POP ;恢復(fù)現(xiàn)場,注意出棧次序;恢復(fù)現(xiàn)場,注意出棧次序POP ; 先進(jìn)棧的寄存器后出棧先進(jìn)棧的寄存器后出棧RET;返回;返回子程序名子程序名ENDP 在子程序入口處把相關(guān)寄存器的值入棧保護(hù),程序返回前再在子程序入口處把相關(guān)寄存器的值入棧保護(hù),程序返回前再恢復(fù)它們的值,這個(gè)操作稱為恢復(fù)它們的值,這個(gè)操作稱為“保護(hù)現(xiàn)場保護(hù)現(xiàn)場”和和“恢復(fù)現(xiàn)場恢復(fù)現(xiàn)場”。子程序的一般格式子程序的一般格式5.1.3 5.1.3 子程序文檔子程序文檔設(shè)計(jì)一個(gè)子程序之前,首先應(yīng)該明確:設(shè)計(jì)一個(gè)子程序之前,首先應(yīng)該明確:子程序的名字子程序的名字;子程序的功能子程序的功能;入
15、口參數(shù)入口參數(shù):為了運(yùn)行這個(gè)子程序,主程序?yàn)樗鼫?zhǔn)備了哪幾個(gè)為了運(yùn)行這個(gè)子程序,主程序?yàn)樗鼫?zhǔn)備了哪幾個(gè)“已知條件已知條件”?這些參數(shù)存放在什么地方?這些參數(shù)存放在什么地方?出口參數(shù)出口參數(shù):這個(gè)子程序的運(yùn)行結(jié)果有哪些?存放在什么地方?這個(gè)子程序的運(yùn)行結(jié)果有哪些?存放在什么地方?影響寄存器影響寄存器:執(zhí)行這個(gè)子程序會(huì)改變哪幾個(gè)寄存器的值?執(zhí)行這個(gè)子程序會(huì)改變哪幾個(gè)寄存器的值?其它需要說明的事項(xiàng)其它需要說明的事項(xiàng)。 上述內(nèi)容連同子程序源代碼等合稱為上述內(nèi)容連同子程序源代碼等合稱為“子程序文檔子程序文檔”。 常常把上述內(nèi)容以常常把上述內(nèi)容以“程序注釋程序注釋”的方式書寫在一個(gè)子程序的首部。的方式書寫在
16、一個(gè)子程序的首部。給使用者提供調(diào)用信息。給使用者提供調(diào)用信息。; 名稱:名稱: Square; 功能:求功能:求16Bit無符號(hào)數(shù)的平方根無符號(hào)數(shù)的平方根; 入口參數(shù):入口參數(shù):16Bit無符號(hào)數(shù)在無符號(hào)數(shù)在AX中中; 出口參數(shù):出口參數(shù):8Bit平方根數(shù)在平方根數(shù)在AL中中; 影響寄存器:影響寄存器:AX ( AL ) ;方法:方法: 利用公式:利用公式:N2=1+3+ + (2N-1) 求平方根求平方根SQUARE PROC NEARPUSHCX;保護(hù)現(xiàn)場保護(hù)現(xiàn)場PUSHBXMOVBX, AX;要求平方根的數(shù)送要求平方根的數(shù)送BXMOVAL, 0; AL中存放平方根,初值中存放平方根,初值
17、0 MOVCX, 1; CX置入第一個(gè)奇數(shù)置入第一個(gè)奇數(shù)1; 利用公式:利用公式:N2=1+3+ + (2N-1) 求平方根求平方根NEXT:SUBBX, CXJBDONEADDCX, 2; 形成下一個(gè)奇數(shù)形成下一個(gè)奇數(shù)INCAL;AL存放已減去奇數(shù)的個(gè)數(shù)存放已減去奇數(shù)的個(gè)數(shù)JMPNEXTDONE:POPBX;恢復(fù)現(xiàn)場恢復(fù)現(xiàn)場POPCXRET;返回返回SQUARE ENDP“SQUARE”的子程序,求一個(gè)數(shù)的平方根的子程序,求一個(gè)數(shù)的平方根5.1.4 5.1.4 子程序應(yīng)用子程序應(yīng)用每調(diào)用一次子程序,主程序需要做三件事:每調(diào)用一次子程序,主程序需要做三件事:(1)為子程序準(zhǔn)備入口參數(shù))為子程序
18、準(zhǔn)備入口參數(shù)(2)調(diào)用子程序)調(diào)用子程序(3)處理子程序的返回參數(shù))處理子程序的返回參數(shù)DATA SEGMENTX DW 59, 3500, 139, 199, 77 ;欲求平方根的數(shù)組;欲求平方根的數(shù)組ROOTDB5 DUP(?);存放平方根內(nèi)存區(qū);存放平方根內(nèi)存區(qū)DATA ENDS CODESEGMENTASSUME CS: CODE, DS: DATASTART: MOVAX, DATAMOVDS, AXLEABX, X;初始化指針;初始化指針LEASI, ROOTMOVCX, 5;設(shè)置計(jì)數(shù)器初值;設(shè)置計(jì)數(shù)器初值ONE:MOVAX, BX;設(shè)置入口參數(shù);設(shè)置入口參數(shù)CALLSQUARE;
19、調(diào)用子程序;調(diào)用子程序MOVSI, AL ;保存返回參數(shù)(平方根);保存返回參數(shù)(平方根)ADDBX, 2;修改指針;修改指針I(yè)NCSI;修改指針;修改指針LOOPONE;循環(huán)控制;循環(huán)控制MOVAX, 4C00H;返回;返回DOSINT21H 例例 求求5 5個(gè)無符號(hào)數(shù)的平方根。個(gè)無符號(hào)數(shù)的平方根。子程序子程序; 名稱:名稱: Square; 功能:求功能:求16Bit無符號(hào)數(shù)的平方根無符號(hào)數(shù)的平方根; 入口參數(shù):入口參數(shù):16Bit無符號(hào)數(shù)在無符號(hào)數(shù)在AX中中; 出口參數(shù):出口參數(shù):8Bit平方根數(shù)在平方根數(shù)在AL中中; 影響寄存器:影響寄存器:AX ( AL ) ;方法:方法: 利用公式
20、:利用公式:N2=1+3+ + (2N-1) 求平方根求平方根SQUARE PROC NEARPUSHCX;保護(hù)現(xiàn)場保護(hù)現(xiàn)場PUSHBXMOVBX, AX;要求平方根的數(shù)送要求平方根的數(shù)送BXMOVAL, 0; AL中存放平方根,初值中存放平方根,初值0 MOVCX, 1; CX置入第一個(gè)奇數(shù)置入第一個(gè)奇數(shù)1NEXT:SUBBX, CXJBDONEADDCX, 2; 形成下一個(gè)奇數(shù)形成下一個(gè)奇數(shù)INCAL;AL存放已減去奇數(shù)的個(gè)數(shù)存放已減去奇數(shù)的個(gè)數(shù)JMPNEXTDONE:POPBX;恢復(fù)現(xiàn)場恢復(fù)現(xiàn)場POPCXRET;返回返回SQUARE ENDPCODE ENDSEND START傳遞的參數(shù)
21、有兩種類型傳遞的參數(shù)有兩種類型:(1 1)值傳遞值傳遞:把參數(shù)的值放在約定的寄存器或存儲(chǔ)單元傳遞給把參數(shù)的值放在約定的寄存器或存儲(chǔ)單元傳遞給子程序,或者,由子程序返回給主程序。子程序,或者,由子程序返回給主程序。 如果一個(gè)入口參數(shù)是用值傳遞的,子程序使用這個(gè)值,但是如果一個(gè)入口參數(shù)是用值傳遞的,子程序使用這個(gè)值,但是不改變它自身的值。不改變它自身的值。(2 2)地址傳遞地址傳遞:把參數(shù)事先存放在某個(gè)存儲(chǔ)單元,把這個(gè)存儲(chǔ)把參數(shù)事先存放在某個(gè)存儲(chǔ)單元,把這個(gè)存儲(chǔ)單元的地址作為參數(shù)傳遞給子程序。單元的地址作為參數(shù)傳遞給子程序。 如果一個(gè)參數(shù)使用它的地址來傳遞,子程序可以改變這個(gè)參如果一個(gè)參數(shù)使用它的
22、地址來傳遞,子程序可以改變這個(gè)參數(shù)的值。例如,把存放結(jié)果的存儲(chǔ)單元的地址作為數(shù)的值。例如,把存放結(jié)果的存儲(chǔ)單元的地址作為“入口參數(shù)入口參數(shù)”傳遞給子程序,子程序可以把運(yùn)算結(jié)果直接存入這個(gè)單元。傳遞給子程序,子程序可以把運(yùn)算結(jié)果直接存入這個(gè)單元。n利用寄存器傳遞參數(shù)利用寄存器傳遞參數(shù) n利用主、子程序利用主、子程序“共享共享”的數(shù)據(jù)段傳遞參數(shù)的數(shù)據(jù)段傳遞參數(shù) n利用堆棧傳遞參數(shù)利用堆棧傳遞參數(shù)三種常用的參數(shù)傳遞方法:三種常用的參數(shù)傳遞方法: 用寄存器傳遞參數(shù)用寄存器傳遞參數(shù) 例例5.35.3求菲波那契數(shù)列的前求菲波那契數(shù)列的前n n項(xiàng)。項(xiàng)。分析:分析: 菲波那契數(shù)列的前兩項(xiàng)為菲波那契數(shù)列的前兩項(xiàng)
23、為1 1,1 1,以后的每一項(xiàng)都是其前兩,以后的每一項(xiàng)都是其前兩項(xiàng)之和。項(xiàng)之和。 X 0=1 , X 1=1, X i=X i-1+X i-2 ( i=2 ) 。方法方法1:利用寄存器傳遞參數(shù)的值。:利用寄存器傳遞參數(shù)的值。方法方法2:利用寄存器傳遞參數(shù)的地址。:利用寄存器傳遞參數(shù)的地址。.MODEL SMALL.DATAFIBLST DW 1, 1, 18 DUP (?)NDW20.CODESTART:MOV AX, DATAMOV DS, AXLEASI, FIBLSTMOV CX, NSUBCX, 2ONE:MOVAX, SIMOVBX, SI+2CALL FIBMOV SI+4, AX
24、ADD SI, 2LOOP ONEMOV AX, 4C00HINT 21H方法方法1:利用寄存器傳遞參數(shù)的值。:利用寄存器傳遞參數(shù)的值。;子程序FIB;功能:求菲波那契數(shù)列數(shù)列的一項(xiàng);入口參數(shù):AXX i-1,BXX i-2;出口參數(shù):AX X i X i-1+ X i-2FIBPROCADDAX, BXRET FIBENDPEND START.MODEL SMALL.DATAFIBLST DW 1, 1, 18 DUP (?)NDW20.CODESTART:MOV AX, DATAMOV DS, AXLEASI, FIBLSTMOV CX, NSUBCX, 2ONE:CALL FIBADD
25、SI, 2LOOP ONEMOV AX, 4C00HINT 21H方法方法2:利用寄存器傳遞參數(shù)的地址。:利用寄存器傳遞參數(shù)的地址。; 子程序FIB; 功能:求菲波那契數(shù)列數(shù)列的一項(xiàng);入口參數(shù):SIX i-2的段內(nèi)偏移地址;出口參數(shù):無(結(jié)果已由子程序存入數(shù)組內(nèi)) FIBPROCPUSHAXMOVAX, SI;取XI-2ADDAX, SI+2;加XI-1MOVSI+4, AX;存入XIPOPAXRET FIBENDPEND START26. MODEL SMALL. DATAFIBLST DW 1, 1, 18 DUP(?)NDW20XI1DW?;存放存放XI-1XI2DW?;存放存放XI-2
26、XIDW?;存放存放XI. CODESTART:MOV AX, DATAMOV DS, AXLEA SI, FIBLST; 設(shè)置地址指針設(shè)置地址指針MOV CX, NSUBCX, 2; 設(shè)置計(jì)數(shù)器初值設(shè)置計(jì)數(shù)器初值ONE:MOVAX, SI+2MOVXI1, AX; X i-1置入置入XI1MOVAX, SIMOVXI2, AX; X i-2置入置入XI2CALL FIB; 調(diào)用子程序調(diào)用子程序MOVAX, XI; 取出計(jì)算結(jié)果取出計(jì)算結(jié)果X iMOV SI+4, AX; 置入置入FIBLST數(shù)組數(shù)組ADD SI, 2; 修改地址指針修改地址指針LOOP ONE; 循環(huán)控制循環(huán)控制MOV AX
27、, 4C00HINT 21H2變量(共享數(shù)據(jù)段)傳遞參數(shù)變量(共享數(shù)據(jù)段)傳遞參數(shù) ;子程序子程序FIB;功能:計(jì)算菲波那契數(shù)列數(shù)列的一項(xiàng);功能:計(jì)算菲波那契數(shù)列數(shù)列的一項(xiàng);入口參數(shù):;入口參數(shù):XI1XI-1,XI2X I-2;出口參數(shù):;出口參數(shù):XIXI-1+X I-2FIBPROCPUSHAX;保護(hù)現(xiàn)場保護(hù)現(xiàn)場MOVAX, XI1 ;AXXI-1ADDAX, XI2;AXXI-1+XI-2MOVXI, AX;XI AXPOPAX;恢復(fù)現(xiàn)場恢復(fù)現(xiàn)場RET FIBENDPEND START . MODEL SMALL. DATA FIBLST DW 1, 1, 18 DUP(?) N DW
28、20.CODESTART: MOV AX, DATA MOV DS, AX LEA SI, FIBLST MOV CX, N SUB CX, 2ONE: PUSHAX ;為保存結(jié)果,在堆棧為保存結(jié)果,在堆?!邦A(yù)留預(yù)留”單元單元 PUSH WORD PTR SI;XI-2入棧入棧 PUSH WORD PTR SI+2 ;XI-1入棧入棧 CALL FIB ;調(diào)用子程序,執(zhí)行后堆棧狀態(tài)調(diào)用子程序,執(zhí)行后堆棧狀態(tài)1 POPAX;從堆棧彈出結(jié)果,執(zhí)行后堆棧狀態(tài)從堆棧彈出結(jié)果,執(zhí)行后堆棧狀態(tài)4 MOV SI+4, AX ;把結(jié)果存入把結(jié)果存入FIBLST數(shù)組數(shù)組 ADD SI, 2 LOOP ONE M
29、OV AX, 4C00H INT 21H 3. 堆棧傳遞參數(shù)堆棧傳遞參數(shù);子程序子程序FIB;功能:計(jì)算菲波那契數(shù)列數(shù)列的一項(xiàng);功能:計(jì)算菲波那契數(shù)列數(shù)列的一項(xiàng);入口參數(shù):;入口參數(shù): XI-1,X I-2在堆棧中在堆棧中;出口參數(shù):;出口參數(shù): X I在棧頂在棧頂FIBPROCPUSH BPMOV BP, SP;堆棧狀態(tài)堆棧狀態(tài)2 PUSH AXMOV AX, BP+4; 從堆棧取出從堆棧取出X I-1ADD AX, BP+6;AXX I-1+X I-2MOV BP+8, AX ; 結(jié)果存入堆棧結(jié)果存入堆棧 POP AXPOP BP; 恢復(fù)恢復(fù)BPRET 4; 返回,返回,SP+4, 執(zhí)行后
30、堆棧狀態(tài)執(zhí)行后堆棧狀態(tài)3FIBENDPEND START思考:思考:1。修改參數(shù)壓棧的順序,程序如何修改?。修改參數(shù)壓棧的順序,程序如何修改?2。改用堆棧傳入?yún)?shù),寄存器返回參數(shù),程序如何修改?。改用堆棧傳入?yún)?shù),寄存器返回參數(shù),程序如何修改?5.3.1 子程序嵌套 5.3.2 遞歸子程序 5.3.1 子程序嵌套 被調(diào)用的子程序在返回前又調(diào)用了其他子程序,稱被調(diào)用的子程序在返回前又調(diào)用了其他子程序,稱為為子程序嵌套子程序嵌套。 (也稱過程嵌套(也稱過程嵌套 Nest Procedure Call ) ;主程序主程序 . CALLSUBA ; .;子程序;子程序SUBA . CALLSUBB;
31、. RET; 子程序子程序SUBB . RET5.3.2 遞歸子程序 遞歸過程遞歸過程(Recursive Procedure):):一個(gè)直接或間接調(diào)用一個(gè)直接或間接調(diào)用自身的過程。自身的過程。如果一個(gè)問題可以分解為幾個(gè)子問題,而這些子問如果一個(gè)問題可以分解為幾個(gè)子問題,而這些子問題又和原問題有相同的算法時(shí),遞歸過程是非常方便的表題又和原問題有相同的算法時(shí),遞歸過程是非常方便的表達(dá)方式。達(dá)方式。遞歸過程可以使用遞歸過程可以使用堆棧傳遞參數(shù)堆棧傳遞參數(shù),也可以用,也可以用寄存器寄存器傳遞參數(shù)傳遞參數(shù)或存儲(chǔ)單元傳遞參數(shù)?;虼鎯?chǔ)單元傳遞參數(shù)。 計(jì)算計(jì)算1 1N N自然數(shù)之和可以定義為:自然數(shù)之和可以
32、定義為:SUM(N)= SUM(N)= N=1N=1時(shí),時(shí),SUMSUM函數(shù)直接返回函數(shù)直接返回1 1。N1N1時(shí),計(jì)算時(shí),計(jì)算SUMSUM(N N)分成兩步:)分成兩步:(1)(1)計(jì)算計(jì)算SUMSUM(N-1N-1):設(shè)置入口參數(shù)為):設(shè)置入口參數(shù)為N-1N-1, 調(diào)用調(diào)用SUMSUM函數(shù)(調(diào)用自身)函數(shù)(調(diào)用自身) (2)(2)進(jìn)行加法運(yùn)算:進(jìn)行加法運(yùn)算:N+SUMN+SUM(N-1N-1) 也可以定義為:SUM( N ) = 1+2+3+ +N. MODELSMALL. STACK100;定義;定義100字節(jié)用作堆棧字節(jié)用作堆棧. CODETOTALDW?START:MOVCX, 3;
33、為子程序準(zhǔn)備參數(shù);為子程序準(zhǔn)備參數(shù)CALLSUM;調(diào)用子程序;調(diào)用子程序SUMMOVCS: TOTAL, AX;保存結(jié)果;保存結(jié)果MOVAX, 4C00HINT21H;返回;返回;遞歸過程;遞歸過程SUM;入口參數(shù);入口參數(shù): CXN,出口參數(shù),出口參數(shù): AX=1N的和的和SUMPROCPUSHCX;保存入口參數(shù)(;保存入口參數(shù)(N)CMPCX, 1;判;判CX(N)是否為)是否為1JEBACK;CX(N)為)為1,轉(zhuǎn),轉(zhuǎn)BACKDECCX;CX-1,為下一次調(diào)用準(zhǔn)備參數(shù),為下一次調(diào)用準(zhǔn)備參數(shù)CALLSUM;遞歸調(diào)用,計(jì)算;遞歸調(diào)用,計(jì)算1N-1的和的和INCCX;恢復(fù);恢復(fù)CX為為NADD
34、AX, CX;加到;加到AX中中JMPEXITBACK: MOVAX, 1;N=1時(shí),通過時(shí),通過AX返回返回1EXIT:POPCX;恢復(fù)入口參數(shù);恢復(fù)入口參數(shù)RETSUMENDPENDSTART 這個(gè)程序使用寄存器進(jìn)行參數(shù)的傳遞。這個(gè)程序使用寄存器進(jìn)行參數(shù)的傳遞。 主程序中的主程序中的“CALL SUM”指令執(zhí)行了一次。指令執(zhí)行了一次。 子程序子程序SUM中的指令中的指令“CALLSUM”執(zhí)行了執(zhí)行了2次。次。 CALL指令先后共執(zhí)行了指令先后共執(zhí)行了3次,先后次,先后3次進(jìn)入同一個(gè)子程序次進(jìn)入同一個(gè)子程序 SUM。遞歸調(diào)用和返回示意圖遞歸調(diào)用和返回示意圖 編寫遞歸程序時(shí),必須保證要有一個(gè)終
35、止條件,而且,編寫遞歸程序時(shí),必須保證要有一個(gè)終止條件,而且,經(jīng)過有限次執(zhí)行這個(gè)子程序,這個(gè)終止條件能夠?qū)崿F(xiàn)。否則,經(jīng)過有限次執(zhí)行這個(gè)子程序,這個(gè)終止條件能夠?qū)崿F(xiàn)。否則,程序?qū)a(chǎn)生程序?qū)a(chǎn)生“死循環(huán)死循環(huán)”或者其它的錯(cuò)誤狀態(tài)?;蛘咂渌腻e(cuò)誤狀態(tài)。 主程序-MOV CX, 3CALL SUMMOV CS:TOTAL, AX-DEC CXCALL SUMINC CXADD AX, CX-RET子程序SUM(1)-DEC CXCALL SUMINC CXADD AX, CX-RET子程序SUM(2)子程序SUM(3)-MOV AX, 1-RETAX=6CX=3AX=?CX=3AX=?CX=2AX=?
36、CX=1AX=1CX=1AX=3CX=2. MODELSMALL. STACK100;定義;定義100字節(jié)用作堆棧字節(jié)用作堆棧. CODETOTAL DW?START:PUSHAX; 為返回結(jié)果預(yù)留單元,為返回結(jié)果預(yù)留單元,; AX中內(nèi)容無意義中內(nèi)容無意義MOVCX, 3;為子程序準(zhǔn)備參數(shù);為子程序準(zhǔn)備參數(shù)PUSHCX;入口參數(shù)壓入堆棧;入口參數(shù)壓入堆棧CALLSUM;調(diào)用子程序;調(diào)用子程序SUMPOPCS: TOTAL;保存結(jié)果保存結(jié)果MOVAX, 4C00HINT21H;返回;返回高級(jí)語言中的遞歸程序普遍使用堆棧傳遞參數(shù)。高級(jí)語言中的遞歸程序普遍使用堆棧傳遞參數(shù)。上面的例子改寫如下:上面的
37、例子改寫如下:;遞歸過程遞歸過程SUM;入口參數(shù):;入口參數(shù):SP+2N,出口參數(shù):,出口參數(shù):1N的和在堆棧棧頂?shù)暮驮诙褩m?;影響寄存器:;影響寄存器:BP, AX,CXSUMPROCPUSHBPMOVBP, SP;根據(jù);根據(jù)BP訪問堆棧中的參數(shù)訪問堆棧中的參數(shù) PUSH AX PUSH CXMOVCX, BP+4;取出入口參數(shù);取出入口參數(shù)N,存入,存入CXCMPCX, 1;N=1 ?JEBACK;N=1,轉(zhuǎn),轉(zhuǎn)BACKDECCX;CX-1,為下一次調(diào)用準(zhǔn)備參數(shù),為下一次調(diào)用準(zhǔn)備參數(shù)PUSHAX ;為保留下一次調(diào)用結(jié)果預(yù)留單元,;為保留下一次調(diào)用結(jié)果預(yù)留單元,AX中內(nèi)容無意義中內(nèi)容無意義
38、PUSHCX;入口參數(shù)(;入口參數(shù)(N-1)壓入堆棧)壓入堆棧CALLSUM;遞歸調(diào)用,計(jì)算;遞歸調(diào)用,計(jì)算1N-1的和的和POPAX ;從堆棧彈出子程序運(yùn)算結(jié)果;從堆棧彈出子程序運(yùn)算結(jié)果(1N-1的和的和)ADDAX, BP+4;把;把N加到加到AX中,得到中,得到1N的和的和MOVBP+6, AX;1N的和存入堆棧預(yù)留單元的和存入堆棧預(yù)留單元JMPEXIT BACK: MOVWORD PTRBP+6, 1;N=1時(shí),返回時(shí),返回1 EXIT: POP CX POP AX POPBPRET2 SUMENDP ENDSTART例:將字符串反序輸出例:將字符串反序輸出 mov bx, offse
39、t strmov bx, offset str push bxpush bx call reverscall revers pop bxpop bx mov dl, bx mov dl, bx mov ah, 2 mov ah, 2 int 21h int 21h revers proc near revers proc near push bp push bp mov bp, sp mov bp, sp mov bx, bp+4 mov bx, bp+4 mov al, bx mov al, bx cmp al, $ cmp al, $ je return je return inc bx
40、inc bx push bxpush bx call reverscall revers pop bxpop bx mov dl, bx mov dl, bx mov ah, 2 mov ah, 2 int 21h int 21h return: return: pop bppop bpret ret ;不能寫成:;不能寫成: ret 2 (ret 2 (?) ) revers endp revers endpn上機(jī)上機(jī)4:按照學(xué)號(hào)的順序輸入:按照學(xué)號(hào)的順序輸入20個(gè)學(xué)生的成個(gè)學(xué)生的成績(績(0100)存入一維數(shù)組)存入一維數(shù)組SCORE,然后,然后統(tǒng)計(jì)每一個(gè)學(xué)生的名次并在屏幕輸出。統(tǒng)計(jì)每一個(gè)
41、學(xué)生的名次并在屏幕輸出。要求:要求:1、顯示形式為、顯示形式為“ 學(xué)號(hào)學(xué)號(hào) :名次:名次 ”; 2、輸入每個(gè)成績、統(tǒng)計(jì)每個(gè)成績的名、輸入每個(gè)成績、統(tǒng)計(jì)每個(gè)成績的名次、顯示結(jié)果數(shù)據(jù)(學(xué)號(hào)或名次)分別定義次、顯示結(jié)果數(shù)據(jù)(學(xué)號(hào)或名次)分別定義為子程序;為子程序; 3、傳參方式:寄存器或堆棧。、傳參方式:寄存器或堆棧。5.4.15.4.1 段的完整定義段的完整定義 5.4.2 5.4.2 簡化段定義簡化段定義 5.4.3 5.4.3 創(chuàng)建多模塊程序創(chuàng)建多模塊程序1.一個(gè)應(yīng)用程序的開發(fā)由一個(gè)小組,而不是一個(gè)人完成的。 每個(gè)程序員編制的源程序自然地構(gòu)成一個(gè)(或者是多個(gè))源程序文件。每個(gè)程序員編制的源程序
42、自然地構(gòu)成一個(gè)(或者是多個(gè))源程序文件。 每個(gè)源程序文件內(nèi)包括了一個(gè)或多個(gè)每個(gè)源程序文件內(nèi)包括了一個(gè)或多個(gè)“子程序子程序”。這些源程序文件常常被稱為。這些源程序文件常常被稱為模塊模塊(Module)。)。 有時(shí)候也把位于同一個(gè)源程序有時(shí)候也把位于同一個(gè)源程序文件內(nèi)的各個(gè)文件內(nèi)的各個(gè)“子程序子程序”,或者一個(gè),或者一個(gè)“數(shù)據(jù)段數(shù)據(jù)段”定定義等稱為模塊。義等稱為模塊。 一個(gè)可供實(shí)際使用的應(yīng)用程序,它的源程序基本上都是由若干個(gè)程序文件組成的。2.源程序文件規(guī)模過大,會(huì)造成管理,維護(hù)上的困難。源程序文件規(guī)模過大,會(huì)造成管理,維護(hù)上的困難。 即便是一個(gè)人開發(fā)的應(yīng)用程序,也應(yīng)把一個(gè)大的程序分解成多個(gè)源代碼
43、文件。即便是一個(gè)人開發(fā)的應(yīng)用程序,也應(yīng)把一個(gè)大的程序分解成多個(gè)源代碼文件。 這樣,每個(gè)文件長度適中,容易閱讀和維護(hù),如果修改了某個(gè)模塊,只需對(duì)該模塊重這樣,每個(gè)文件長度適中,容易閱讀和維護(hù),如果修改了某個(gè)模塊,只需對(duì)該模塊重新匯編,然后再和其他模塊鏈接,無須把每個(gè)模塊重新匯編一次。新匯編,然后再和其他模塊鏈接,無須把每個(gè)模塊重新匯編一次。 3.許多許多“子程序子程序”可以重復(fù)使用,獨(dú)立為一個(gè)源程序文件便于可以重復(fù)使用,獨(dú)立為一個(gè)源程序文件便于“子程序庫子程序庫”的管理。的管理。 5.4.15.4.1 段的完整定義段的完整定義段名段名SEGMENT 對(duì)齊方式對(duì)齊方式 組合方式組合方式 使用類型使
44、用類型類類語句語句段名段名ENDS完整的段定義格式如下: 方括號(hào)括起來的內(nèi)容稱為方括號(hào)括起來的內(nèi)容稱為“可選項(xiàng)可選項(xiàng)”,可以由使用者根據(jù),可以由使用者根據(jù)需要決定。需要決定。 1. 對(duì)齊方式對(duì)齊方式一個(gè)新的段開始時(shí),對(duì)齊方式通知連接程序怎樣確定這個(gè)段一個(gè)新的段開始時(shí),對(duì)齊方式通知連接程序怎樣確定這個(gè)段的起始地址。對(duì)齊方式可以有下面幾種選擇:的起始地址。對(duì)齊方式可以有下面幾種選擇:nBYTE 使本段從前面段結(jié)束之后的下一個(gè)字節(jié)地址開始。使本段從前面段結(jié)束之后的下一個(gè)字節(jié)地址開始。nWORD使本段從前面段結(jié)束之后的下一個(gè)字地址開始。使本段從前面段結(jié)束之后的下一個(gè)字地址開始。nDWORD使本段從前面
45、段結(jié)束之后的下一個(gè)雙字地址開始。使本段從前面段結(jié)束之后的下一個(gè)雙字地址開始。nPARA使本段從前面段結(jié)束之后的下一個(gè)節(jié)的地址(使本段從前面段結(jié)束之后的下一個(gè)節(jié)的地址(16的的整數(shù)倍)開始存放,是默認(rèn)的對(duì)齊方式。如果沒有出現(xiàn)對(duì)齊方式整數(shù)倍)開始存放,是默認(rèn)的對(duì)齊方式。如果沒有出現(xiàn)對(duì)齊方式說明,自動(dòng)按照說明,自動(dòng)按照“PARA”來對(duì)齊。來對(duì)齊。nPAGE使本段從前面段結(jié)束之后的下一個(gè)頁地址(使本段從前面段結(jié)束之后的下一個(gè)頁地址(256的整的整數(shù)倍)開始。數(shù)倍)開始。對(duì)齊方式對(duì)齊方式段基址段基址起始偏移地址起始偏移地址段間空隙(字節(jié))段間空隙(字節(jié))BYTE3020H0005H0WORD3020H0
46、006H1DWORD3020H0008H3PARA3021H0000H11PAGE3030H0000H251 假設(shè)前面一個(gè)段的結(jié)束地址為假設(shè)前面一個(gè)段的結(jié)束地址為30204H,用不同對(duì)齊方式的結(jié)果如下表所示。用不同對(duì)齊方式的結(jié)果如下表所示。2. 組合方式組合方式通知連接程序以何種方式處理組合方式通知連接程序以何種方式處理不同程序文件中不同程序文件中名稱相名稱相同的段。組合方式可以有下面幾種選擇:同的段。組合方式可以有下面幾種選擇:lPRIVATEPRIVATE這個(gè)段不與其他同名段合并,每個(gè)段都有自己的段基這個(gè)段不與其他同名段合并,每個(gè)段都有自己的段基地址,是默認(rèn)的組合方式。地址,是默認(rèn)的組合方
47、式。lPUBLICPUBLIC將該段和其他名稱相同,組合方式同為將該段和其他名稱相同,組合方式同為“PUBLIC”PUBLIC”的的段前后連接在一起,合并成一個(gè)段,產(chǎn)生一個(gè)新的段基地址,所有段前后連接在一起,合并成一個(gè)段,產(chǎn)生一個(gè)新的段基地址,所有標(biāo)號(hào)的偏移地址都進(jìn)行調(diào)整。標(biāo)號(hào)的偏移地址都進(jìn)行調(diào)整。lSTACKSTACK將所有的將所有的STACKSTACK段連接為一個(gè)新的段連接為一個(gè)新的STACKSTACK段,類似于段,類似于PUBLICPUBLIC。lCOMMON COMMON 所有同名的段使用相同的起始地址,這樣,這些段所有同名的段使用相同的起始地址,這樣,這些段“共享共享”這一片共同的存
48、儲(chǔ)區(qū)間。這一片共同的存儲(chǔ)區(qū)間。lAT AT 表達(dá)式表達(dá)式段的起始地址由表達(dá)式的值來指定,用于設(shè)定一些特段的起始地址由表達(dá)式的值來指定,用于設(shè)定一些特殊的段。殊的段。使用(USE)類型 使用類型僅僅使用于使用使用類型僅僅使用于使用8038680386以上指令系統(tǒng)的匯編程序(例如,以上指令系統(tǒng)的匯編程序(例如,在程序首部使用在程序首部使用.386.386說明符)說明符) 使用使用1616位尋址方式時(shí),段內(nèi)偏移地址位尋址方式時(shí),段內(nèi)偏移地址1616位,每個(gè)段最大位,每個(gè)段最大64KB64KB。運(yùn)。運(yùn)行在實(shí)模式下的程序使用行在實(shí)模式下的程序使用1616位段。位段。 使用使用3232位尋址方式時(shí),段內(nèi)偏
49、移地址為位尋址方式時(shí),段內(nèi)偏移地址為3232位,一個(gè)段最大可達(dá)位,一個(gè)段最大可達(dá)4GB4GB。運(yùn)行在保護(hù)模式下的程序使用運(yùn)行在保護(hù)模式下的程序使用3232位段。位段。 使用使用8038680386以上以上CPUCPU并且工作在實(shí)模式下的程序不能遺漏并且工作在實(shí)模式下的程序不能遺漏“USE16”USE16”說明。說明。例如:例如: mul ax, 5 imul ax, bx, -14.類名稱一個(gè)段除了有一個(gè)段名之外,還可以有一個(gè)類名稱。一個(gè)段除了有一個(gè)段名之外,還可以有一個(gè)類名稱。類名稱是以引號(hào)引起來的任意字符串。類名稱是以引號(hào)引起來的任意字符串。類名稱相同的段被放在一片相鄰的存儲(chǔ)區(qū)間,但不會(huì)類
50、名稱相同的段被放在一片相鄰的存儲(chǔ)區(qū)間,但不會(huì)合并成同一個(gè)段。合并成同一個(gè)段。 52CSEG SEGMENT CODE ASSUME CS: CSEG, DS: DATA1 ASSUME SS: MYSTACKMAINPROCMOVAX, DATA1 MOVDS, AXMOVAX, SEG VAL2 MOVES, AX MOVAX, VAL1 LEASI, VAL2 MOVBX, ES:SI CMP AX, BXJB L1 CALLFAR PTR SUB1 L1:MOV AX, 4C00H INT21HMAINENDPCSEGENDS 例例5.5 本例中有兩個(gè)代碼段、兩個(gè)數(shù)據(jù)段和一個(gè)堆棧段,本例
51、中有兩個(gè)代碼段、兩個(gè)數(shù)據(jù)段和一個(gè)堆棧段,SUBCODESEGMENTCODEASSUME CS:SUBCODE,DS:DATA2,SS: MYSTACKSUB1PROCFAR;過程體RETSUB1ENDPSUBCODEENDS; = DATA1SEGMENTDATA ; 類名稱為DATAVAL1 DW1001HDATA1ENDS; = DATA2SEGMENTDATA ; 類名稱為DATAVAL2 DW1002HDATA2ENDS; =MYSTACK SEGMENT PARA STACK STACKDB100H DUP(?)MYSTACK ENDS; = END MAIN經(jīng)過鏈接,從對(duì)應(yīng)的經(jīng)過
52、鏈接,從對(duì)應(yīng)的MAP文件中可以看到程序有兩個(gè)代碼段、文件中可以看到程序有兩個(gè)代碼段、兩個(gè)數(shù)據(jù)段和一個(gè)堆棧段:兩個(gè)數(shù)據(jù)段和一個(gè)堆棧段: Start Stop Length Name Class 00000H 00022H 00023H CSEG CODE 00030H 00030H 00001H SUBCODE CODE 00040H 00041H00002H DATA1 DATA 00050H 00051H 00002H DATA2 DATA 00060H 0015FH 00100H MYSTACK STACK由于使用默認(rèn)的由于使用默認(rèn)的“PARA”對(duì)齊方式,段間有間隙。對(duì)齊方式,段間有間隙。
53、同類型名的段相鄰存放。同類型名的段相鄰存放。 如果將如果將SUBCODE的段名改為的段名改為CSEG,將,將DATA2段名改為段名改為DATA1,則鏈接器創(chuàng)建的則鏈接器創(chuàng)建的MAP文件是這樣的:文件是這樣的: Start Stop Length Name Class 00000H 00023H00024HCSEG CODE 00030H 00033H00004H DATA1 DATA 00040H 0013FH 00100H MYSTACK STACK 由此可見,在同一個(gè)程序文件中,相同段名的代碼段合并成一個(gè)段,由此可見,在同一個(gè)程序文件中,相同段名的代碼段合并成一個(gè)段,兩個(gè)同名的數(shù)據(jù)段也合并
54、成一個(gè)段。兩個(gè)同名的數(shù)據(jù)段也合并成一個(gè)段。5.4.25.4.2 簡化段定義簡化段定義 1 內(nèi)存模式定義偽指令使用簡化段定義時(shí),需要首先定義所使用的內(nèi)存模式等參數(shù)。使用簡化段定義時(shí),需要首先定義所使用的內(nèi)存模式等參數(shù)。格式如下:格式如下:.MODEL .MODEL 內(nèi)存模式內(nèi)存模式 ,語言類型,語言類型 ,操作系統(tǒng)類型,操作系統(tǒng)類型 , ,堆棧選項(xiàng)堆棧選項(xiàng) 2 近數(shù)據(jù)段定義偽指令.DATA .DATA?.CONSTl.DATA .DATA 創(chuàng)建一個(gè)數(shù)據(jù)段,段名是創(chuàng)建一個(gè)數(shù)據(jù)段,段名是_DATA_DATA,主要定義有初值的變量。,主要定義有初值的變量。l.DATA? .DATA? 用來定義沒有初值
55、的變量,段名為用來定義沒有初值的變量,段名為_BSS_BSS。定義在。定義在.DATA?.DATA?段段的無初值變量不占用可執(zhí)行文件的空間。的無初值變量不占用可執(zhí)行文件的空間。l.CONST .CONST 定義只讀數(shù)據(jù)段,段名是定義只讀數(shù)據(jù)段,段名是_CONST_CONST。 一個(gè)源文件中可以包含多個(gè)由一個(gè)源文件中可以包含多個(gè)由.DATA.DATA、.DATA?.DATA?和和.CONST.CONST定義的數(shù)定義的數(shù)據(jù)段,據(jù)段,TASMTASM自動(dòng)將其合并為一個(gè)物理段,使它們具有相同的段基址。自動(dòng)將其合并為一個(gè)物理段,使它們具有相同的段基址。 3 遠(yuǎn)數(shù)據(jù)段定義偽指令 .FARDATA 段名和.
56、FARDATA? 段名分別用來定義已有初值的數(shù)據(jù)段和沒有初值的數(shù)據(jù)段。如果段分別用來定義已有初值的數(shù)據(jù)段和沒有初值的數(shù)據(jù)段。如果段名缺省,默認(rèn)段名分別為名缺省,默認(rèn)段名分別為FAR_DATA和和FAR_BSS。通過指定段名,。通過指定段名,可在源文件中定義多個(gè)獨(dú)立的數(shù)據(jù)段。遠(yuǎn)數(shù)據(jù)段不會(huì)被合并??稍谠次募卸x多個(gè)獨(dú)立的數(shù)據(jù)段。遠(yuǎn)數(shù)據(jù)段不會(huì)被合并。 4 代碼段定義偽指令.CODE 段名 如果內(nèi)存模式為如果內(nèi)存模式為SMALL,.CODE偽指令不需要給出偽指令不需要給出“段名段名”,編譯器生成一個(gè)名為編譯器生成一個(gè)名為_TEXT的代碼段,對(duì)于多個(gè)代碼段的內(nèi)存模式,的代碼段,對(duì)于多個(gè)代碼段的內(nèi)存模式
57、,則應(yīng)該指明段名。則應(yīng)該指明段名。 5 堆棧段定義偽指令.STACK堆棧大小定義一個(gè)堆棧段,缺省大小為定義一個(gè)堆棧段,缺省大小為1024字節(jié),段名為字節(jié),段名為STACK。6 TASM預(yù)定義符號(hào) CODE和DATACODE表示由表示由.CODE定義的代碼段的段名,在指令中表示段基址。定義的代碼段的段名,在指令中表示段基址。DATA表示由表示由.DATA、.DATA?和和.CONST定義的數(shù)據(jù)段的段名,在定義的數(shù)據(jù)段的段名,在指令中表示段基址。指令中表示段基址。注意:使用簡化段定義時(shí),沒有段結(jié)束偽指令。一個(gè)新的段開始,就注意:使用簡化段定義時(shí),沒有段結(jié)束偽指令。一個(gè)新的段開始,就意味著上一個(gè)段到
58、此結(jié)束。意味著上一個(gè)段到此結(jié)束。 59.MODEL MEDIUM ; 內(nèi)存模式為中型內(nèi)存模式為中型.STACK 100H.DATA MSG1 DB FIRST MESSAGE”, 0DH, 0AH, $.DATA?;定義第二個(gè)數(shù)據(jù)段,未初始化定義第二個(gè)數(shù)據(jù)段,未初始化XDB10 DUP (?).CODEMAIN PROCMOVAX, DATAMOVDS, AXLEA DX, MSG1CALLFAR PTR DISP; 遠(yuǎn)調(diào)用遠(yuǎn)調(diào)用MOV AX, 4C00HINT 21HMAIN ENDP例例5.6 本例中有兩個(gè)代碼段。本例中有兩個(gè)代碼段。.CODE OTHER ;再定義一個(gè)代碼段再定義一個(gè)代碼
59、段DISP PROC FAR MOVAH, 9 INT21H RETDISP ENDPEND MAIN ; 入口地址入口地址MAIN 經(jīng)過鏈接,從對(duì)應(yīng)的經(jīng)過鏈接,從對(duì)應(yīng)的MAP文件中可以看到程序有兩個(gè)代碼文件中可以看到程序有兩個(gè)代碼段、兩個(gè)數(shù)據(jù)段和一個(gè)堆棧段:段、兩個(gè)數(shù)據(jù)段和一個(gè)堆棧段:Start Stop Length Name Class00000H 00011H 00012H EX506_TEXT CODE00012H 00016H 00005H OTHER CODE00020H 0002FH 00010H _DATA DATA00030H 0012FH 00100H STACK STA
60、CK00130H 00130H 00001H _BSS BSS 用用TD觀察這個(gè)程序,發(fā)現(xiàn)觀察這個(gè)程序,發(fā)現(xiàn)_DATA 和和_BSS段使用相同的段使用相同的段基址,被合并為一個(gè)物理段。段基址,被合并為一個(gè)物理段。5.4.3創(chuàng)建多模塊程序創(chuàng)建多模塊程序 模塊模塊 :由不同的程序員編寫,以不同的文件名存放在磁盤中,由不同的程序員編寫,以不同的文件名存放在磁盤中,這樣的源程序文件稱為這樣的源程序文件稱為“模塊模塊” 模塊內(nèi)部由若干個(gè)段的定義組成,其中僅有一個(gè)模塊包含模塊內(nèi)部由若干個(gè)段的定義組成,其中僅有一個(gè)模塊包含有主程序,其它的模塊包含了一些子程序和數(shù)據(jù)段、堆棧有主程序,其它的模塊包含了一些子程序
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 各種在家活動(dòng)方案
- 合作類區(qū)域活動(dòng)方案
- 合生元vip活動(dòng)方案
- 同事英語游戲活動(dòng)方案
- 同學(xué)交往禮儀活動(dòng)方案
- 同行游戲活動(dòng)策劃方案
- 名宿活動(dòng)促銷活動(dòng)方案
- 腫瘤標(biāo)記物鐵蛋白的臨床意義
- 名師講黨課活動(dòng)方案
- 反恐認(rèn)證安全教育
- 2025年內(nèi)鏡洗消考試試題及答案
- 第4課 互聯(lián)網(wǎng)創(chuàng)新發(fā)展 教學(xué)設(shè)計(jì) 2024-2025學(xué)年浙教版(2023)初中信息技術(shù)七年級(jí)上冊
- 2024年湖北工匠杯(信息通信信息化系統(tǒng)管理員賽項(xiàng))考試題庫-上(單選題)
- 中職病理學(xué)發(fā)熱
- 質(zhì)量策劃書-吳江水系二期項(xiàng)目
- 《兒童食物過敏》課件
- 第四單元第1課+身臨其境+課件-+【知識(shí)精研】人教版(2024)初中美術(shù)七年級(jí)上冊
- 煤礦應(yīng)急醫(yī)療救護(hù)常識(shí)課件
- 基于毫米波的工業(yè) 5G 創(chuàng)新應(yīng)用白皮書
- DB37T 2640-2022 監(jiān)獄安全防范系統(tǒng)建設(shè)技術(shù)規(guī)范
- 學(xué)校各功能室管理人員工作職責(zé)
評(píng)論
0/150
提交評(píng)論