|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
问题: 程序设计一,为何在指定长度写入的数据还会导致文字错乱? 代码如下:
- assume cs:codesg ,ss:data,ds:table
- data segment
- db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
- db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
- db '1993','1994','1995'
- ;数组格式存放
- dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
- dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
- ;数组格式存放
- dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
- dw 11452,14430,15257,17800
- ;数组格式存放
- data ends
- table segment
- db 42 dup (0)
- table ends
- codesg segment
- start: mov bx,0
- mov di,0
- mov dx,0
- mov cx,15h
- mov ax,table
- mov ds,ax
- mov ax,data
- mov ss,ax
- s: mov si,0
- mov ax,word ptr ss:[bx]
- mov word ptr ds:[si],ax
-
- mov ax,word ptr ss:[bx].2
- mov word ptr ds:[si].2,ax ;年份装入ds:si中
- add si,6
-
- push dx
- mov ax, word ptr ss:[bx].54h
- push ax
- mov ax, word ptr ss:[bx].56h
- push ax
- mov ax,0ah
- push ax
- call dtoc ;收入转入ds:si
- add si,6
-
- mov ax,word ptr ss:[di].0a8h
- push ax
- mov ax,0
- push ax
- mov ax, 0ah
- push ax
- call dtoc ;人员转入ds:si中
- add si,6
-
-
- push cx
- mov ax, word ptr ss:[bx].54h
- push ax
- mov ax, word ptr ss: [bx].56h
- push ax
- mov ax,word ptr ss:[di].0a8h
- push ax
- call divdw ;平均收入转入ds:si中
- pop cx
- push ax
- push dx
- mov ax,0ah
- push ax
- call dtoc
- add si,6
-
-
- mov si,0
- mov ax,24h
- push ax
- call dtoc1 ;将ds:si中的字符串0转为空格
-
- pop dx
- mov ax,ds
- push ax
- mov ax,02
- push ax
- push dx
- mov ax,0
- push ax
- call show1; 将数值显示在屏幕上
-
-
- inc dx
- add di,2
- add bx,4
-
- loop s
-
-
- mov ax,4c00h
- int 21h
-
- ;功能名: dtoc1
- ;说明: 将指定长度ds:si中的字符串0转为空格
- ;参数: ax=长度,ds:si指向字符串首地址
- ;结果: (ds:si)指向字符串的首地址,字符串以0结尾
- ;源码始
- dtoc1: mov bp,sp
- push cx
- mov cx,[bp+2]
- e: push cx
- mov cl,ds:[si]
- jcxz b
- c: inc si
- pop cx
- loop e
- mov al,0
- mov ds:[si],al
- pop cx
- ret 2
-
- b: mov al,20h
- mov ds:[si],al
- jmp short c
- ;源码终
- ;功能名: dtoc
- ;说明: 将word型数据转变为表示十进制数的字串符,字符串以0结尾,最大转换15byte字符
- ;参数: ax=dword型数据低16位
- ;参数: dx=dword型数据高16位
- ;参数: bx=word型数据,如果除数为0表示求(dx)(ax)/0ah十进制数的字串符,非0表示进行divdw转变为十进制数的字串符
- ;结果: (ds:si)指向字符串的首地址
- ;源码始
- dtoc: push dx
- push di
- push cx
- mov bp,sp
- mov di,0
- mov ax,[bp+0ch] ;(ax)
- mov dx,[bp+0ah] ;(dx)
- dtocs: mov cx,[bp+8] ;型数据,如果除数为0表示求(dx)(ax)/0ah十进制数的字串符,非0表示进行divdw转变为十进制数的字串符
- jcxz dtocz
- push ax ;非0表示进行divdw转变为十进制数的字串符
- push dx
- push cx
- dtocc: call divdw
- jmp short dtoce
- dtocz: push ax
- push dx
- mov cx,0ah
- push cx
- jmp short dtocc
- dtoce: add cl,30h
- mov ch,0
- push cx
- inc di
- mov cx,dx
- jcxz dtocr ;如果 余数为0
- dtocr: mov cx,ax
- jcxz dout
- jmp short dtocs ;如果商不为零继续除
-
- dout: mov cx,di
- dtoct: pop ax
- mov byte ptr ds:[si],al ;写入[ds:si]中
- inc si
- loop dtoct
- pop cx
- pop di
- pop dx
- ret 6
- ;源码终
- ;功能名: divdw
- ;说明: 进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型
- ;参数: push ax=dword型数据低16位
- ;参数: push dx=dword型数据高16位
- ;返回: dx=结果的高16位,ax=结果的低16位 cx=余数
- ;源码始
- divdw:
- push si
- mov bp,sp
- mov ax,[bp+6] ;高16位数据
- mov dx,0
- mov cx,[bp+4]
- div cx
- mov si,ax
- mov ax,[bp+8]
- div cx
- mov cx,dx
- mov dx,si
- pop si
-
- ret 6
- ;源码终
- ;功能名: show1
- ;说明: 向屏幕显示文本,以零结尾文本
- ;参数: push ax 文本,以零结尾
- ;参数: push ax 文本颜色,
- ;参数: push ax 行,从零开始 范围(0-24)
- ;参数: push ax 列,从零开始 范围(0-80),偶数递增
- ;结果: 向指定行显示指定文本
- ;源码始:
- show1: push di
- push bx
- push cx
- push si
- push dx
- mov bp,sp
- mov ax,[bp+12h]
- mov ds,ax
- mov ax,0b800h ;屏幕显示地址
- mov es,ax
- mov ax,[bp+0eh] ;行
-
- add ax,4
- mov bx,160 ;第一行4*160
- mul bx
- mov bx,ax
- mov si,[bp+0ch]
- mov di,0
- show_s1:mov cl,ds:[di] ;ds:[di]指向文本byte单元
- mov ch,0
- jcxz show_s0;如果=0直接返回
- mov ch,[bp+10h] ;颜色
- mov es:[bx][si],cx ;显示
- add si,2
- inc di
-
-
- loop show_s1
- show_s0:pop dx
- pop si
- pop cx
- pop bx
- pop di
- ret 8
- ;源码终
- codesg ends
- end start
复制代码
精简后代码如下:
- assume cs:codesg ,ss:data,ds:table
- data segment
- db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
- db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
- db '1993','1994','1995'
- ;年份字符串数组
- dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
- dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
- ;年总收入数组
- dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
- dw 11452,14430,15257,17800
- ;年人总数数组
- data ends
- table segment
- db 42 dup (0)
- table ends
- codesg segment
- start: mov bx,0
- mov di,0
- mov dx,0
- mov cx,15h
- mov ax,table
- mov ds,ax
- mov ax,data
- mov ss,ax
- s: mov si,0
- mov ax,word ptr ss:[bx]
- mov word ptr ds:[si],ax
-
- mov ax,word ptr ss:[bx].2
- mov word ptr ds:[si].2,ax ;年份装入ds:si中
- add si,6
-
- push dx ;入栈显示行
- mov ax, word ptr ss:[bx].54h
- push ax
- mov ax, word ptr ss:[bx].56h
- push ax
- call dtoc ;收入转入ds:si
- add si,8
-
- mov ax,word ptr ss:[di].0a8h
- push ax
- mov ax,0
- push ax
- call dtoc ;人员转入ds:si中
- add si,4
-
-
- push cx ;入栈cx,保存循环次数
- mov ax, word ptr ss:[bx].54h
- push ax
- mov ax, word ptr ss: [bx].56h
- push ax
- mov cx,word ptr ss:[di].0a8h
- call divdw ;平均收入转入ds:si中
- pop cx ;出栈cx,取出循环次数
- push ax
- push dx
- call dtoc
-
- mov si,0
- mov ax,24h
- push ax
- call dtoc1 ;将ds:si中的字符串0转为空格
-
- pop dx
- mov ax,02 ;颜色
- push ax ;颜色
- push dx ;行
- mov ax,0
- push ax
- call show1; 将数值显示在屏幕上
-
-
- inc dx
- add di,2
- add bx,4
-
- loop s
-
-
- mov ax,4c00h
- int 21h
-
- ;功能名: dtoc1
- ;说明: 将指定长度ds:si中的字符串0转为空格
- ;参数: ax=长度,ds:si指向字符串首地址
- ;结果: (ds:si)指向字符串的首地址,字符串以0结尾
- ;源码始
- dtoc1: mov bp,sp
- push cx
- mov cx,[bp+2] ;将长度赋值给cx
- e: push cx ;保存长度
- mov cl,ds:[si] ;获取ds:si字符
- jcxz b ;是否为零,如果为零调到b,进行转为空格
- c: inc si ;不为零,ds:si 指向下一个字符
- pop cx ;取出cx,
- loop e
- mov al,0
- mov ds:[si],al;字符串以0结尾
- pop cx
- ret 2
- b: mov al,20h
- mov ds:[si],al
- jmp short c
- ;源码终
- ;功能名: dtoc
- ;说明: 将word型数据转变为表示十进制数的字串符,字符串以0结尾,最大转换15byte字符
- ;参数: ax=dword型数据低16位
- ;参数: dx=dword型数据高16位
- ;结果: (ds:si)指向字符串的首地址
- ;源码始
- dtoc: push dx
- push di
- push cx
- mov bp,sp
- mov di,0
- mov ax,[bp+0ah] ;(ax)
- mov dx,[bp+08h] ;(dx)
- dtocz: push ax
- push dx
- mov cx,0ah
- call divdw ;进行除法
- add cl,30h ;余数转为字符串
- mov ch,0 ;高位=0
- push cx ;入栈字符串
- inc di ;记录字符个数
- mov cx,dx
- jcxz dtocr ;如果 余数为0
- dtocr: mov cx,ax ;如果商为零,跳到dtoct ,跳出循环,
- jcxz dout
- mov cx,bx; 将被除数赋值给cx
- jmp short dtocz ;如果商不为零继续除
- dout: mov cx,di
- dtoct: pop ax
- mov byte ptr ds:[si],al ;写入[ds:si]中
- inc si
- loop dtoct
- pop cx
- pop di
- pop dx
- ret 4
- ;源码终
- ;功能名: divdw
- ;说明: 进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型
- ;参数: push ax=dword型数据低16位
- ;参数: push dx=dword型数据高16位
- ;参数: cx=word型数据被除数
- ;返回: dx=结果的高16位,ax=结果的低16位 cx=余数
- ;源码始
- divdw:
- push si
- mov bp,sp
- mov ax,[bp+4] ;高16位数据
- mov dx,0
- div cx
- mov si,ax ;保存高位商
- mov ax,[bp+6] ;低16位数据
- div cx
- mov cx,dx
- mov dx,si ;赋值给dx,高位商
- pop si
- ret 4
- ;源码终
- ;功能名: show1
- ;说明: 向屏幕显示文本,以零结尾文本
- ;参数: push ax 文本,以零结尾
- ;参数: push ax 文本颜色,
- ;参数: push ax 行,从零开始 范围(0-24)
- ;参数: push ax 列,从零开始 范围(0-80),偶数递增
- ;结果: 向指定行显示指定文本
- ;源码始:
- show1: push di
- push bx
- push cx
- push si
- push dx
- mov bp,sp
- mov ax,0b800h ;屏幕显示地址
- mov es,ax
- mov ax,[bp+0eh] ;行
- add ax,4
- mov bx,160 ;第一行4*160
- mul bx
- mov bx,ax
- mov si,[bp+0ch] ;列
- mov di,0
- show_s1:mov cl,ds:[di] ;ds:[di]指向文本byte单元
- mov ch,0
- jcxz show_s0;如果=0直接返回
- mov ch,[bp+10h] ;颜色
- mov es:[bx][si],cx ;显示
- mov al,0
- mov ds:[di],al;显示后清除数据以免错乱
- add si,2
- inc di
-
- loop show_s1
- show_s0:pop dx
- pop si
- pop cx
- pop bx
- pop di
- ret 6
- ;源码终
- codesg ends
- end start
复制代码
|
|