程序设计一,字符写入问题,求大神告知下
问题: 程序设计一,为何在指定长度写入的数据还会导致文字错乱? 代码如下: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:
mov word ptr ds:,ax
mov ax,word ptr ss:.2
mov word ptr ds:.2,ax ;年份装入ds:si中
add si,6
push dx
mov ax, word ptr ss:.54h
push ax
mov ax, word ptr ss:.56h
push ax
mov ax,0ah
push ax
call dtoc ;收入转入ds:si
add si,6
mov ax,word ptr ss:.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:.54h
push ax
mov ax, word ptr ss: .56h
push ax
mov ax,word ptr ss:.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,
e: push cx
mov cl,ds:
jcxz b
c: inc si
pop cx
loop e
mov al,0
mov ds:,al
pop cx
ret 2
b: mov al,20h
mov ds:,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, ;(ax)
mov dx, ;(dx)
dtocs: mov cx, ;型数据,如果除数为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:,al ;写入中
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, ;高16位数据
mov dx,0
mov cx,
div cx
mov si,ax
mov ax,
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,
mov ds,ax
mov ax,0b800h;屏幕显示地址
mov es,ax
mov ax, ;行
add ax,4
mov bx,160 ;第一行4*160
mul bx
mov bx,ax
mov si,
mov di,0
show_s1:mov cl,ds: ;ds:指向文本byte单元
mov ch,0
jcxz show_s0;如果=0直接返回
mov ch, ;颜色
mov es:,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
endstart 自己解决了,终于知道问题出现在哪里了.dtoc 中
;功能名: 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, ;(ax)
mov dx, ;(dx)
dtocs: mov cx, ;型数据,如果除数为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 ;这里进行push 导致 mov 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:,al ;写入中
inc si
loop dtoct
pop cx
pop di
pop dx
ret 6
;源码终
{:10_257:}{:10_257:} 泡泡吧 发表于 2017-1-10 05:46
自己解决了,终于知道问题出现在哪里了.dtoc 中
;功能名: dtoc
精简后代码如下:
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:
mov word ptr ds:,ax
mov ax,word ptr ss:.2
mov word ptr ds:.2,ax ;年份装入ds:si中
add si,6
push dx ;入栈显示行
mov ax, word ptr ss:.54h
push ax
mov ax, word ptr ss:.56h
push ax
call dtoc ;收入转入ds:si
add si,8
mov ax,word ptr ss:.0a8h
push ax
mov ax,0
push ax
call dtoc ;人员转入ds:si中
add si,4
push cx ;入栈cx,保存循环次数
mov ax, word ptr ss:.54h
push ax
mov ax, word ptr ss: .56h
push ax
mov cx,word ptr ss:.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, ;将长度赋值给cx
e: push cx;保存长度
mov cl,ds:;获取ds:si字符
jcxz b ;是否为零,如果为零调到b,进行转为空格
c: inc si ;不为零,ds:si 指向下一个字符
pop cx ;取出cx,
loop e
mov al,0
mov ds:,al;字符串以0结尾
pop cx
ret 2
b: mov al,20h
mov ds:,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, ;(ax)
mov dx, ;(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:,al ;写入中
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, ;高16位数据
mov dx,0
div cx
mov si,ax;保存高位商
mov ax, ;低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, ;行
add ax,4
mov bx,160 ;第一行4*160
mul bx
mov bx,ax
mov si, ;列
mov di,0
show_s1:mov cl,ds: ;ds:指向文本byte单元
mov ch,0
jcxz show_s0;如果=0直接返回
mov ch, ;颜色
mov es:,cx ;显示
mov al,0
mov ds:,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
endstart
页:
[1]