日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

實驗9

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

76543210
含義BLRGBIRGB

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

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 顯示字符串

??????編寫一個通用的子程序來讓調用者可以決定顯示的位置(行、列、內容和顏色)
??????子程序描述如下:
????????????名稱:show_str
????????????功能:在指定的位置、用特定的顏色,顯示一個用0結束的字符串
????????????參數:(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位的被除數和8位的除數在做除法的時候,用al存儲結果的商,ah存儲結果的余數。如果當除數為1時,那么商也是一個16位數據,這超過了al這個8位寄存器所能表示數據的范圍了。
??????子程序描述如下:
????????????名稱:divdw
????????????功能:進行不會溢出的除法運算,被除數為dword型,除數為word型,結果為dword型。
????????????參數:(ax)=dword型數據的低16位,(dx)=dword型數據的高16位,(cx)=除數
????????????返回:(dx)=結果的高16位,(ax)=結果的低16位,(cx)=余數
??????提示:參考公式如下:
????????????X:被除數,范圍:[0,FFFFFFFF]
????????????N:除數,范圍:[0,FFFF]
????????????H:X高16位,范圍:[0,FFFF]
????????????L:X低16位,范圍:[0,FFFF]
????????????int():描述性運算符,取商,比如,int(38/10)=3
????????????rem():描述性運算符,取余數,比如,rem(38/10)=8

????????????公式:X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N
????????????注意:乘以65536相當于左移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 保存被除數的低16位Lmov [si+2],dx 保存被除數的高16位Hmov ax,dxmov dx,0div cx 用高16位H除以除數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]處,余數存儲在[si]處。done: pop dxpop axpop cxmov cx,[si] 保存返回值到相應的寄存器中mov ax,[si+2]mov dx,[si+4]pop sipop dsretcode endsend start
問題3 數值(int)到字符串形式的轉換

??????問題:把數據用十進制的形式顯示到屏幕上,需進行兩步的操作:(1),將用二進制信息存儲的數據轉變為十進制形式的字符串(2),顯示十進制形式的字符串(只需調用問題1的show_str即可)
??????子程序描述如下:
????????????名稱:dtoc
????????????功能:將word型數據轉變為十進制數的字符串,字符串以0為結尾符。
????????????參數:(ax)=word型數據、ds:si指向字符串的首地址
????????????返回:無
??????編程,將數據12666以十進制形式在屏幕的8行3列,用綠色顯示出來。在顯示時調用本次實驗中的第一個子程序show_str。
??????思路:想要得到十進制數12666的每一位數值,需將12666除以10,它的余數6為個位上的數值,它的商1266作為新的被除數再除以10,余數6為原數據十位上的數值,它的商再次除以10,以此類推,進行5次除以10操作就可以得到每一位的值了。
??????在已知數據為12666的情況下,循環次數為5,但對于數據未知的情況下,就需要判定每次得到的商是否為0了,當除到商為0時,所有位上的值就被全部求出。在此采用jcxz指令來實現此功能。
??????除法功能在此采用32位除以16位的方式來實現,因為這樣不會導致溢出。因為如果采用16位除以8位的方式的話,那么它的商也是用8位來保存的,而12666/10=1266,這已經大于8位數據的最大值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 整數10作為16位的除數放在bx中mov si,9mov byte ptr [si],0 字符串末尾置0sub si,1s: mov dx,0div bxadd dl,'0' 容易看出dh中全為0,計算出數據的實際ASCII值mov [si],dl 字節單元數據的傳送,將余數保存到內存中mov cx,axjcxz donesub si,1jmp short sdone: pop dxpop axpop cxpop bxretcode endsend start
課程設計1

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

????????????但還需要編寫一個將dword型數據轉換為字符串的子程序。說明如下:
??????????????????名稱:ddtoc(為了和word型數據轉換子程序dtoc區分開來)
??????????????????功能:將dword型數據轉變為表示十進制數的字符串,字符串以0為結尾符
??????????????????參數:(ax)=dword型數據的低16位,(dx)=dword型數據的高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個雙字型數據來表示公司每年的總收入dw 3,7,9,13,28,38,130,220,476,778,100,1442,2258,2793,4037,5635,8226dw 11542,14430,15257,17800//用21個字型數據來表示公司每年的員工數量data endsbuf segmentdb 16 dup(0) 這塊內存是用來進行雙字型到字符串轉換的buf endscode segmentstart:mov ax,datamov ds,axmov bx,0 ds:bx表示數據段起始的偏移地址mov ax,0b800hmov es,ax mov di,160*2 es:di指向顯示緩沖區第二行第0列mov al,21mov dl,8mul dlmov si,ax 計算21*8,保存到si,這是雇員數在數據段的起始偏移地址mov cx,21 外層循環次數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 雇員數 nnext: pop sipop dsmov dx,[bx+86]mov ax,[bx+84]div word ptr [si] 計算人均收入push dspush simov ax,bufmov ds,axcall dtoc 字型數據轉換為字符串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 除數10保存在cx中push simov si,0 將ds:si開始后的6個字節作為divdw中的臨時緩存call divdw divdw采用本文中實現的子程序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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。