日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

汇编语言随笔(8)-实验9(显示字符串)、实验10(子程序:除法溢出,数值到字符串的转换)和课程设计1

發(fā)布時間:2025/6/17 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 汇编语言随笔(8)-实验9(显示字符串)、实验10(子程序:除法溢出,数值到字符串的转换)和课程设计1 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

實驗9

??????編程,在屏幕中間分別顯示綠色,綠底紅色,白底藍色的字符串‘welcome to masm!’。
??????80x25彩色字符模式下的顯示緩沖區(qū),每頁可以顯示25行,每行80個字符,其中每個字符占兩個字節(jié)的存儲空間,低位字節(jié)存儲字符的ASCII值,高位字節(jié)存儲字符的屬性。所以一行總共有160個字節(jié)。其中屬性字節(jié)的格式如下:

76543210
含義BLRGBIRGB

??????其中BL為閃爍,R為紅色,G為綠色,B為藍色,I為高亮,在高位的RGB表示背景顏色,低位的表示前景顏色。
??????以綠底紅色為例,它的顏色屬性為00100100B。顯示緩沖區(qū)的段地址為0b800h,默認在第0頁的屏幕中間的偏移地址為12x160+(40-16/2)x2。其中16為本程序中字符串的字節(jié)數(shù)。搞清楚了目的地址和顏色屬性之后,我們開始編寫程序:

assume cs:codedata segmentdb 'welcome to masm!'data endscode segmentstart:mov ax,0b800hmov es,axmov di,12*160+32*2 目的地址存儲在es:di中mov ax,datamov ds,axmov bx,0mov cx,10hs: mov al,[bx]mov es:[di],almov byte ptr es:[di+1],00100100Binc bxadd di,2loop smov ax,4c00hint 21hcode endsend start

實驗10

問題1 顯示字符串

??????編寫一個通用的子程序來讓調(diào)用者可以決定顯示的位置(行、列、內(nèi)容和顏色)
??????子程序描述如下:
????????????名稱:show_str
????????????功能:在指定的位置、用特定的顏色,顯示一個用0結(jié)束的字符串
????????????參數(shù):(dh)=行號(取值范圍為0-24),(dl)=列號(取值范圍為0-79),(cl)=顏色,ds:si指向字符串的首地址
????????????返回:無
??????在屏幕的8行3列,用綠色顯示data段中的字符串,完整的程序如下:

assume cs:codedata segmentdb 'Welcome to masm!',0data endscode segmentstart: mov dh,8mov dl,3mov cl,2mov ax,datamov ds,axmov si,0call show_strmov ax,4c00hint 21hshow_str: push cxpush dxpush axpush sipush dspush dipush esmov ax,0b800hmov es,axmov di,dh*160+dl*2 es:di為目的地址s: mov al,[si]cmp al,0je donemov es:[di],almov es:[di+1],cladd di,2inc sijmp short sdone: pop espop dipop dspop sipop axpop dxpop csretcode endsend start
問題2 解決除法溢出

??????問題:除法溢出指的是商過大,超出了寄存器的存儲范圍。比如:16位的被除數(shù)和8位的除數(shù)在做除法的時候,用al存儲結(jié)果的商,ah存儲結(jié)果的余數(shù)。如果當(dāng)除數(shù)為1時,那么商也是一個16位數(shù)據(jù),這超過了al這個8位寄存器所能表示數(shù)據(jù)的范圍了。
??????子程序描述如下:
????????????名稱:divdw
????????????功能:進行不會溢出的除法運算,被除數(shù)為dword型,除數(shù)為word型,結(jié)果為dword型。
????????????參數(shù):(ax)=dword型數(shù)據(jù)的低16位,(dx)=dword型數(shù)據(jù)的高16位,(cx)=除數(shù)
????????????返回:(dx)=結(jié)果的高16位,(ax)=結(jié)果的低16位,(cx)=余數(shù)
??????提示:參考公式如下:
????????????X:被除數(shù),范圍:[0,FFFFFFFF]
????????????N:除數(shù),范圍:[0,FFFF]
????????????H:X高16位,范圍:[0,FFFF]
????????????L:X低16位,范圍:[0,FFFF]
????????????int():描述性運算符,取商,比如,int(38/10)=3
????????????rem():描述性運算符,取余數(shù),比如,rem(38/10)=8

????????????公式:X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N
????????????注意:乘以65536相當(dāng)于左移16位。
??????計算1000000/10(F4240H/0AH)完整程序如下:

assume cs:codedata segmentdw 4 dup(0)data endscode segmentstart: mov ax,datamov ds,axmov si,0mov ax,4240hmov dx,0fhmov cx,0ahcall divdwmov ax,4c00hint 21hdivdw: push dspush sipush cxpush axpush dxmov [si],ax 保存被除數(shù)的低16位Lmov [si+2],dx 保存被除數(shù)的高16位Hmov ax,dxmov dx,0div cx 用高16位H除以除數(shù)Nmov [si+4],ax 保存商mov ax,[si]div cx rem(H/N)作為高16位,L作為低16位,除以Nmov [si+2],axmov [si],dx//將商的高16位存儲在[si+4]處,低16位存儲在[si+2]處,余數(shù)存儲在[si]處。done: pop dxpop axpop cxmov cx,[si] 保存返回值到相應(yīng)的寄存器中mov ax,[si+2]mov dx,[si+4]pop sipop dsretcode endsend start
問題3 數(shù)值(int)到字符串形式的轉(zhuǎn)換

??????問題:把數(shù)據(jù)用十進制的形式顯示到屏幕上,需進行兩步的操作:(1),將用二進制信息存儲的數(shù)據(jù)轉(zhuǎn)變?yōu)槭M制形式的字符串(2),顯示十進制形式的字符串(只需調(diào)用問題1的show_str即可)
??????子程序描述如下:
????????????名稱:dtoc
????????????功能:將word型數(shù)據(jù)轉(zhuǎn)變?yōu)槭M制數(shù)的字符串,字符串以0為結(jié)尾符。
????????????參數(shù):(ax)=word型數(shù)據(jù)、ds:si指向字符串的首地址
????????????返回:無
??????編程,將數(shù)據(jù)12666以十進制形式在屏幕的8行3列,用綠色顯示出來。在顯示時調(diào)用本次實驗中的第一個子程序show_str。
??????思路:想要得到十進制數(shù)12666的每一位數(shù)值,需將12666除以10,它的余數(shù)6為個位上的數(shù)值,它的商1266作為新的被除數(shù)再除以10,余數(shù)6為原數(shù)據(jù)十位上的數(shù)值,它的商再次除以10,以此類推,進行5次除以10操作就可以得到每一位的值了。
??????在已知數(shù)據(jù)為12666的情況下,循環(huán)次數(shù)為5,但對于數(shù)據(jù)未知的情況下,就需要判定每次得到的商是否為0了,當(dāng)除到商為0時,所有位上的值就被全部求出。在此采用jcxz指令來實現(xiàn)此功能。
??????除法功能在此采用32位除以16位的方式來實現(xiàn),因為這樣不會導(dǎo)致溢出。因為如果采用16位除以8位的方式的話,那么它的商也是用8位來保存的,而12666/10=1266,這已經(jīng)大于8位數(shù)據(jù)的最大值255了。

assume cs:codedata segmentdb 10 dup(0)data endscode segmentstart: mov ax,12666mov bx,datamov ds,bxmov si,0call dtocmov dh,8mov dl,3mov cl,2call show_str mov ax,4c00hint 21hdtoc: push bxpush cxpush axpush dxmov bx,10 整數(shù)10作為16位的除數(shù)放在bx中mov si,9mov byte ptr [si],0 字符串末尾置0sub si,1s: mov dx,0div bxadd dl,'0' 容易看出dh中全為0,計算出數(shù)據(jù)的實際ASCII值mov [si],dl 字節(jié)單元數(shù)據(jù)的傳送,將余數(shù)保存到內(nèi)存中mov cx,axjcxz donesub si,1jmp short sdone: pop dxpop axpop cxpop bxretcode endsend start
課程設(shè)計1

??????將實驗七中的公司21年的數(shù)據(jù)在屏幕上顯示出來,一共占據(jù)屏幕21行,每一行中顯示出每一年的數(shù)據(jù),依次為年份、收入、雇員數(shù)和平均收入。
??????思路:
????????????先計算出每一字段的行號和列號,可得,行號范圍為[2,22];每一行第一個字段起始地址為6,第二個字段起始地址為28,第三個字段起始地址為50,最后一個字段起始地址為72。這樣就可以將所有數(shù)據(jù)內(nèi)容顯示在屏幕中央。
????????????說明一點,前面已經(jīng)實現(xiàn)了的子程序在此將被直接調(diào)用。

????????????但還需要編寫一個將dword型數(shù)據(jù)轉(zhuǎn)換為字符串的子程序。說明如下:
??????????????????名稱:ddtoc(為了和word型數(shù)據(jù)轉(zhuǎn)換子程序dtoc區(qū)分開來)
??????????????????功能:將dword型數(shù)據(jù)轉(zhuǎn)變?yōu)楸硎臼M制數(shù)的字符串,字符串以0為結(jié)尾符
??????????????????參數(shù):(ax)=dword型數(shù)據(jù)的低16位,(dx)=dword型數(shù)據(jù)的高16位,ds:si指向字符串的首地址
??????????????????返回:無
??????????????????仍需要注意除法溢出的問題。
??????完整程序如下:

assume cs:codedata segamentdb '1975','1976','1977','1978','1979','1980','1981','1982','1983'db '1984','1985','1986','1987','1988','1989','1990','1991','1992'db '1993','1994','1995'//用21個字符串來表示年份dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514dd 245980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000//用21個雙字型數(shù)據(jù)來表示公司每年的總收入dw 3,7,9,13,28,38,130,220,476,778,100,1442,2258,2793,4037,5635,8226dw 11542,14430,15257,17800//用21個字型數(shù)據(jù)來表示公司每年的員工數(shù)量data endsbuf segmentdb 16 dup(0) 這塊內(nèi)存是用來進行雙字型到字符串轉(zhuǎn)換的buf endscode segmentstart:mov ax,datamov ds,axmov bx,0 ds:bx表示數(shù)據(jù)段起始的偏移地址mov ax,0b800hmov es,ax mov di,160*2 es:di指向顯示緩沖區(qū)第二行第0列mov al,21mov dl,8mul dlmov si,ax 計算21*8,保存到si,這是雇員數(shù)在數(shù)據(jù)段的起始偏移地址mov cx,21 外層循環(huán)次數(shù)21次body: mov ax,[bx]mov es:[di+6],axmov ax,[bx+2]mov es:[di+8],ax 年份push sipush dsmov ax,[bx+84]mov dx,[bx+86]call ddtocmov bp,0subb: mov al,[si]cmp al,0je nextmov es:[di+bp+28],alinc bpinc sijmp short subb 總收入next: pop dspop simov ax,[si]push dspush simov ax,bufmov ds,axcall dtocmov bp,0subbo: mov al,[si]cmp al,0je nnextmov es:[di+bp+50],alinc bpinc sijmp short subbo 雇員數(shù) nnext: pop sipop dsmov dx,[bx+86]mov ax,[bx+84]div word ptr [si] 計算人均收入push dspush simov ax,bufmov ds,axcall dtoc 字型數(shù)據(jù)轉(zhuǎn)換為字符串mov bp,0 subbody:mov al,[si]cmp al,0je nnnextmov es:[di+bp+72],alinc bpinc sijmp short subbody nnnext: pop sipop dsadd di,160add si,2add bx,4loop bodymov ax,4c00hint 21hddtoc: push cxpush axpush dxmov ax,bufmov ds,axmov si,15mov byte ptr [si],0dec sis: mov cx,10 除數(shù)10保存在cx中push simov si,0 將ds:si開始后的6個字節(jié)作為divdw中的臨時緩存call divdw divdw采用本文中實現(xiàn)的子程序pop siadd cl,'0'mov [si],cldec sicmp dx,0jne scmp ax,0je donejmp short sdone: inc si 注意,最后退出時si并不是剛好指向字符串首地址pop dxpop axpop cxretcode endsend start

總結(jié)

以上是生活随笔為你收集整理的汇编语言随笔(8)-实验9(显示字符串)、实验10(子程序:除法溢出,数值到字符串的转换)和课程设计1的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。