




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、實(shí)驗(yàn)八 編寫子程序(4學(xué)時(shí)) 在本次實(shí)驗(yàn)中,我們將編寫3個(gè)子程序,通過它們來認(rèn)識(shí)幾個(gè)常見的問題和掌握解決這些問題的方法。同前面的所有實(shí)驗(yàn)一樣,這個(gè)實(shí)驗(yàn)室必須獨(dú)立完成的,在后面的課程中,將要用到這個(gè)實(shí)驗(yàn)中編寫的3個(gè)子程序。1、 顯示字符串 顯示字符串是下現(xiàn)實(shí)工作中經(jīng)常要用到的功能,應(yīng)該編寫一個(gè)通用的字程序來實(shí)現(xiàn)這個(gè)功能。我們應(yīng)該提供靈活的調(diào)用接口,使調(diào)用者可以決定顯示的位置(行、列)、內(nèi)容和顏色。 該子程序描述如下:名稱:show_str功能:在指定位置用指定顏色顯示一個(gè)用0結(jié)束的字符串。參數(shù):(dh)=行號(hào)(取值范圍024),(dl)=列號(hào)(取值范圍079),(cl)=顏色,ds:si指向字符
2、串的首地址。返回:無應(yīng)用舉例:在屏幕的8行3列,用綠色顯示data段中的字符串。assume cs: codedata segment db welcome to masm!, 0data endscode segment start: mov dh, 8 mov dl, 3 mov cl, 2 mov ax, data mov ds, ax mov si, 0 call show_str mov ax, 4c00h int 21hshow_str: : : :code endsend start提示:(1) 子程序的入口參數(shù)是屏幕上的行號(hào)和列號(hào),注意在子程序內(nèi)部要將它們轉(zhuǎn)化為顯存中的地址,首
3、先要分析一下屏幕上的行列位置和顯存地址的對(duì)應(yīng)關(guān)系;(2) 注意保存子程序中用到的相關(guān)寄存器;(3) 這個(gè)子程序的內(nèi)部處理和顯存的結(jié)構(gòu)密切相關(guān),但是向外提供了與顯存結(jié)構(gòu)無關(guān)的接口。通過調(diào)用這個(gè)子程序,進(jìn)行字符串的顯示時(shí)可以不必了解顯存的結(jié)果,為編程提供了方便。在實(shí)驗(yàn)中,注意體會(huì)這種設(shè)計(jì)思想。data segment db "welcome to masm!"data endsstack segment db "welcome to masm!"stack endscode segment start: mov dh, 8 mov dl, 3 mov cl,
4、 2 mov ax, data mov ds, ax mov si, 0 mov ax,0b800h mov es,ax mov ax, stack mov ss, ax mov sp,10h call show_str mov ax, 4c00h int 21hshow_str: push dx push cx mov al,160 dec dh mul dh mov bx,ax add dx,si add dl,dl add bl,dl mov cl,si mov ch,0 jcxz ok mov es:bx,cl pop cx mov es:bx+1,cl inc si pop dx j
5、mp short show_strok: pop cx pop dx retcode endsend start2、 解決除法溢出的問題 前面講過,div指令可以做除法。當(dāng)進(jìn)行8位除法的時(shí)候,用al存儲(chǔ)商,ah存儲(chǔ)余數(shù);進(jìn)行16位除法時(shí),用ax存儲(chǔ)商,dx存儲(chǔ)余數(shù)。可是,現(xiàn)在有一個(gè)問題,如果結(jié)果的商大于al或ax所能存儲(chǔ)的最大值,那么將如何?比如,下面的程序段:mov bh, 1mov ax, 1000div bh進(jìn)行的是8位除法,商為1000,而1000在al中放不下。又比如,下面的程序段:mov ax, 1000hmov dx, 1mov bx, 1div bx進(jìn)行的是16位除法,商為11
6、000h,而11000h在ax中放不下。我們在用div指令做除法的時(shí)候,和可能發(fā)生上面的情況:結(jié)果的商過大,超出了寄存器所能存儲(chǔ)的范圍。當(dāng)cpu執(zhí)行div等除法指令時(shí),如果發(fā)生這樣的情況,將引發(fā)cpu的一個(gè)內(nèi)部錯(cuò)誤,這個(gè)錯(cuò)誤被稱為:除法溢出。我們可以通過特殊的程序來處理這個(gè)錯(cuò)誤,但在這里我們不討論這個(gè)錯(cuò)誤的處理,這是后面課程中要涉及的內(nèi)容。下面我們僅僅來看一下除法發(fā)生時(shí)的一些現(xiàn)象,如同8.1所示。圖8.1 除法溢出時(shí)發(fā)生的現(xiàn)象 圖中展示了在windows 2000中使用debug執(zhí)行相關(guān)程序段的結(jié)果,div指令引發(fā)了cpu的除法溢出,系統(tǒng)對(duì)其進(jìn)行了相關(guān)的處理。至此,我們已經(jīng)清楚了問題所在;用d
7、iv指令做除法的時(shí)候可能產(chǎn)生除法溢出。由于有這樣的問題,在進(jìn)行除法運(yùn)算時(shí)要注意除數(shù)和被除數(shù)的值,比如1000000/10就不能用div指令來計(jì)算。那么怎么辦呢?我們用下面的子程序divdw解決。該子程序的描述如下:名稱:divdw功能:進(jìn)行不會(huì)產(chǎn)生溢出的除法運(yùn)算,被除數(shù)為dword型,除數(shù)為word型,結(jié)果為dword型。參數(shù): (ax)=dword型數(shù)據(jù)的低16位;(dx)=dword型數(shù)據(jù)的高16位;(cx)=除數(shù)返回:(ax)=商的低16位;(dx)=商的高16位;(cx)=余數(shù)應(yīng)用舉例:計(jì)算1000000/10(f424h/0ah)mov ax, 4240hmov dx, 000fhm
8、ov cx, 0ahcall divdw結(jié)果:(ax)=86a0h,(dx)=0001h, (cx)=0.提示:給出一個(gè)公式:x: 被除數(shù),范圍:0,ffffffffn: 除數(shù),范圍: 0,ffffh: x高16位,范圍: 0,ffffl: x低16位,范圍: 0,ffffint(): 描述性運(yùn)算符,取商,比如int(38/10)=3rem(): 描述性運(yùn)算符,取余數(shù),比如rem(38/10)=8公式:x/n=int(h/n)*65536+rem(h/n)*65536+l/n這個(gè)公式將可能產(chǎn)生溢出的除法運(yùn)算:x/n,轉(zhuǎn)變?yōu)槎鄠€(gè)不會(huì)產(chǎn)生溢出的除法運(yùn)算。公式中,等號(hào)右邊的所有除法運(yùn)算都可以用div
9、指令來做,肯定不會(huì)導(dǎo)致除法溢出。(關(guān)于這個(gè)公式的推導(dǎo),有興趣的同學(xué)可參見王爽所著匯編語言的附注5.代碼:assume cs: codedata segment db "welcome to masm!",0data endsstack segment db "welcome to masm!"stack endscode segmentstart: mov ax, 4240hmov dx, 000fhmov cx, 0ahcall divdwmov ax, 4c00hint 21hdivdw:push axmov ax,dxmov dx,0div cxm
10、ov bx,axpop axdiv cxmov cx,dxmov dx,bxretcode endsend start3、 數(shù)值顯示 編程實(shí)現(xiàn)將data段中的數(shù)據(jù)以十進(jìn)制的形式顯示出來。data segment dw 123, 12666, 1, 8, 3, 38data ends這些數(shù)據(jù)在內(nèi)存中都是二進(jìn)制信息,標(biāo)記了數(shù)值的大小。要把它們顯示到屏幕上,成為我們能夠讀懂的信息,需要進(jìn)行信息的轉(zhuǎn)化。比如,數(shù)值12666,在機(jī)器中存儲(chǔ)為二進(jìn)制信息:0011000101111010b(317ah),計(jì)算機(jī)可以理解它。而要在顯示器上讀到可以理解的數(shù)值12666,我們看到的應(yīng)該是一串字符:“12666”。
11、由于顯卡遵循的是ascii編碼,為了讓我們能在顯示器上看到這串字符,它在機(jī)器中應(yīng)以ascii碼的形式存儲(chǔ)為:31h, 32h, 36h, 36h, 36h(字符“0”“9”對(duì)應(yīng)的ascii碼為30h39h).通過上面的分析可以看到,在概念世界中,有一個(gè)抽象的數(shù)據(jù)12666,它表示了一個(gè)數(shù)值的大小。在現(xiàn)實(shí)世界中它可以有多種表示形式,可以在電子機(jī)器中以高低電平(二進(jìn)制)的形式存儲(chǔ),也可以在紙上、黑板上、屏幕上以人類的語言“12666”來書寫?,F(xiàn)在,我們面臨的問題的就是,要將同一抽象的數(shù)據(jù)從一種表示形式轉(zhuǎn)化為另一種表示形式。可見,要將數(shù)據(jù)用十進(jìn)制形式顯示到屏幕上,要進(jìn)行兩步工作:(1) 將用二進(jìn)制信
12、息存儲(chǔ)的數(shù)據(jù)轉(zhuǎn)變?yōu)槭M(jìn)制形式的字符串;(2) 顯示十進(jìn)制形式的字符串。第二步我們在本次實(shí)驗(yàn)的第一個(gè)子程序中已經(jīng)實(shí)現(xiàn),在這里只要調(diào)用一下show_str即可。我們來討論第一步,因?yàn)閷⒍M(jìn)制信息轉(zhuǎn)變?yōu)槭M(jìn)制形式的字符串也是經(jīng)常要用到的功能,我們應(yīng)該為它編寫一個(gè)通用的子程序。該子程序的描述如下:名稱: dtoc功能: 將word型數(shù)據(jù)轉(zhuǎn)變?yōu)楸硎臼M(jìn)制數(shù)的字符串,字符串以0為結(jié)尾符。參數(shù): (ax)=word型數(shù)據(jù),ds:si指向字符串的首地址。返回: 無應(yīng)用舉例: 編程實(shí)現(xiàn)將數(shù)據(jù)12666以十進(jìn)制形式在屏幕的8行3列用綠色顯示出來。在顯示時(shí)我們調(diào)用本次實(shí)驗(yàn)中的第一個(gè)子程序show_str。assum
13、e cs: codedata segment db 10 dup (0)data endscode segment start: mov ax, 12666 mov bx, data mov ds, bx mov si, 0 call dtoc mov dh, 8 mov dl, 3 mov cl, 2 call show_str : : :code endsend start提示: 下面我們對(duì)這個(gè)問題進(jìn)行一下簡單的分析。(1) 要得到字符串“12666”,就是要得到一列表示該字符串的ascii碼:31h, 32h, 36h, 36h, 36h。 十進(jìn)制數(shù)碼字符對(duì)應(yīng)的ascii碼=十進(jìn)制數(shù)碼值
14、+30h。 要得到表示十進(jìn)制數(shù)的字符串,先求十進(jìn)制數(shù)每位的值。 例:對(duì)于12666,先求得每位的值:1,2,6,6,6。再將這些數(shù)分別加上30h,便得到了表示12666的ascii碼串: 31h, 32h, 36h, 36h, 36h。(2) 那么,怎樣得到每位的值呢?采用除基取余法: 余數(shù) 10 | 1 2 6 6 6 6 10 | 1 2 6 6 6 10 | 1 2 6 6 10 | 1 2 2 10 | 1 1 0可見,用基數(shù)10除12666,共除5次,記下每次的余數(shù),就得到了每位的值。(3) 綜合上面的分析,可得到處理過程如下: 用12666除以10,循環(huán)5次,記下每次的余數(shù);將每次
15、的余數(shù)分別加上30h,便得到了表示十進(jìn)制數(shù)的ascii碼串。如下: 余數(shù) +30h ascii碼串 字符串 10 | 1 2 6 6 6 6 36h 6 10 | 1 2 6 6 6 36h 6 10 | 1 2 6 6 36h 6 10 | 1 2 2 32h 2 10 | 1 1 31h 1 0(4) 對(duì)(3)的質(zhì)疑。 在已知數(shù)據(jù)是12666的情況下,知道進(jìn)行5次循環(huán)??稍趯?shí)際問題中,數(shù)據(jù)的值是多少程序員并不知道,也就是說,程序員不能事先確定循環(huán)次數(shù)。 那么,如何確定數(shù)據(jù)各位的值已經(jīng)全部求出來了呢?我們可以看出,只要是除到商為0,各位的值就已經(jīng)全部求出??梢允褂胘cxz指令來實(shí)現(xiàn)相關(guān)的功能
16、。代碼:assume cs: codedata segment db 10 dup (0)data endscode segment start: mov ax, 12666 mov bx, data mov ds, bx mov bx,0b800h mov es,bx mov si, 0 call dtoc mov dh, 8 mov dl, 3 mov cl, 2 call show_str mov ax, 4c00h int 21hdtoc: mov bx,10 mov dx,0 div bx mov cx,ax mov si,dx add byte ptr si,30h inc si jcxz
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 異常信息考核管理辦法
- 外聘機(jī)構(gòu)服務(wù)管理辦法
- 薪酬等級(jí)評(píng)審管理辦法
- 肝病護(hù)理課件教學(xué)
- 福建二升三數(shù)學(xué)試卷
- 福建2024成人高考數(shù)學(xué)試卷
- 二年級(jí)拔尖數(shù)學(xué)試卷
- 足球培訓(xùn)課件模板
- 廣東6年級(jí)升學(xué)數(shù)學(xué)試卷
- 高中藝術(shù)生數(shù)學(xué)試卷
- 2025年氫溴酸行業(yè)市場需求分析報(bào)告及未來五至十年行業(yè)預(yù)測報(bào)告
- 光伏電站運(yùn)維安全操作規(guī)程
- 2025春季學(xué)期國開電大專科《管理學(xué)基礎(chǔ)》期末紙質(zhì)考試總題庫
- 物流倉儲(chǔ)設(shè)備選型與配置規(guī)范
- T-BSRS 124-2024 伴生放射性礦開發(fā)利用場地土壤放射性污染調(diào)查和修復(fù)監(jiān)測技術(shù)規(guī)范
- (2025)全國交管12123學(xué)法減分考試題庫附答案
- 虛擬現(xiàn)實(shí)行業(yè)標(biāo)準(zhǔn)-深度研究
- T-ZHCA 025-2023 化妝品抗氧化人體測試方法
- 安保主管上半年工作總結(jié)
- 中山市招商服務(wù)中心2025年上半年招考人員易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 2022年9月國家開放大學(xué)??啤陡叩葦?shù)學(xué)基礎(chǔ)》期末紙質(zhì)考試試題及答案
評(píng)論
0/150
提交評(píng)論