首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 嵌入开发 >

一个程序的bug搞了一天,苦思无果,希望坛友旁观者清

2013-09-11 
一个程序的bug弄了一天,苦思无果,希望坛友旁观者清这个题目的要求是将图片1的数据打印到显存中如图片2,可

一个程序的bug弄了一天,苦思无果,希望坛友旁观者清
这个题目的要求是将图片1的数据打印到显存中如图片2,可是我debug到子程序show_4str中的代码- mov es:[di],ax-时,t后发现他的数据并没有改成正确的数值31(字符1)左思右想这句代码应该没有问题,我的显存地址B800:00A2也没有计算错误,不太明白,请各位坛友指教,现在将debug图附上。
希望有坛友赐教
[img=http://my.csdn.net/my/album/show/124849][/img]


assume cs:code
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 11542,14430,15257,17800

db 168 dup(0)
data ends
stack segment
db 32 dup(0)
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,32
mov ax,0B800h
mov es,ax
mov di,0
mov si,0

;=========年份写入显存段========

mov dh,1
mov dl,1
mov cx,21
s1:
push cx
mov bp,4
mov cl,2
call show_4str
inc dh
pop cx
loop s1

;========收入写入显存段=========
mov cx,21
mov di,84
s2:mov ax,ds:[di]
add di,2
mov dx,ds:[di]
add di,2
mov si,294;ds:[si]指向字符串的首地址
call dtoc
push cx
mov dh,1
mov dl,16
mov cl,2
call show_str
pop cx
loop s2

;========雇员写入显存段=========
mov cx,21
mov di,168
s3:mov ax,ds:[di]
add di,2
mov dx,0
mov si,294
call dtoc
push cx
mov dh,1
mov dl,32
mov cl,2
call show_str
pop cx
loop s3

;=======人均收入写入显存段=======
mov cx,21
mov di,84
s4:mov ax,ds:[di]
add di,2
mov dx,ds:[di]
mov bp,168
div word ptr ds:[bp];其实这里更好的思路就是用除法程序divdw,因为人均收入也可能占用4个字节,但是我假设它只占用2个字节,事实上,只要这个课程设计能够做好,这个就没多大事情了
add bp,2
mov dx,0
mov si,294;ds:[si]指向字符串的首地址
call dtoc
mov dh,1
mov dl,48
push cx
mov cl,2
call show_str
pop cx
loop s4

mov ax,4c00h
int 21h


;======4个字符写入显存的特殊子程序show_4str======
;参数:ds:si指向字符串的首地址,dh=行号(范围0-24),dl=列号(范围0-79)
;cl=颜色,bp=字符串长度
show_4str:

push ax
push di
push si
push bp
push cx
mov al,160
mul dh
mov di,ax
mov al,2
mul dl
add di,ax;di显存偏移地址,es显存段基址
mov bl,cl;bl暂存颜色值
mov cx,bp
a:mov al,ds:[si]
inc si
mov ah,bl
mov es:[di],ax    ;es:[di]显存段
add di,2;除参数和cs:ip外,其他寄存器参数都要入栈,不知道这种想法是否正确?
loop a
pop cx
pop bp
pop si
pop di 
pop ax
ret

;======数值显示dtoc=======
;参数:ax=低16位dx=高16位
    ;ds:si指向字符串的首地址
;返回:无
dtoc:
push si
push di
push cx
mov di,0
b:mov cx,10
call divdw
push cx
add di,1;si记录入栈次数
mov cx,ax
jcxz ok1
jmp short b


ok1: 
mov cx,dx
jcxz ok2;dx和ax的值都为0,表示除完,除法过程结束
jmp short b
ok2:mov cx,si
c1:pop ax
add al,30h;al从数值变为字符
mov ds:[si],al
inc si
;mov ax,2
;mov ds:[si],al;给字符添加属性颜色绿色
;inc si;感觉这几行不需要额,不过还是写出来了
loop c1
mov byte ptr ds:[si],0
pop cx
pop di
pop si
ret

;=========显示字符串show_str=========
;参数:(dh)=行号(取值范围0-24),(dl)=列号(取值范围0-79)
;(cl)=颜色,ds:si指向字符串的首地址
;返回:无
;应用举例:在屏幕的8行3列,用绿色显示data段中的字符串
show_str:
push bp
push bx
push ax
push di
push si
mov al,dh
mov bl,160
mul bl
mov di,ax
mov al,dl
mov bl,2
mul bl;偏移地址=dh*160+dl*2
add di,ax;di存显存缓冲区的偏移地址,es存段基址
mov bl,cl ;bl暂存cl的颜色值,好像只有bx可用了,要不cl的值就要入栈了
d:
mov al,ds:[si]
mov ah,bl
mov es:[di],ax
mov cl,ds:[si]
mov ch,0
add si,2
add di,2
jcxz e
jmp short d
e:
pop si
pop di
pop ax
pop bx
pop bp
ret

;======除法程序divdw======
;参数:(ax)=dword型数据的低16位 (dx)=dword型数据的高16位    
;(cx)=除数
;返回:(dx)=结果的高16位 (ax)=结果的低16位
;(cx)=余数
divdw:
push si
push di
mov di,ax
mov ax,dx;先求int(H/N)
mov dx,0
div cx
mov si,ax;si存着高16位的值
mov ax,di;再求[rem(H/N)*65536+L]/N,此时ax存着高16位,dx存着低16位
div cx ;ax存着低16位 dx余数
mov cx,dx
mov dx,si
pop di
pop si
ret
code ends
end start



[解决办法]
呵呵,都什么年代了,还写8086的汇编
[解决办法]
LZ玩反编译的啊、全汇编、
[解决办法]
引用:
LZ玩反编译的啊、全汇编、


呵呵,你没看那些寄存器全部是8086的,连一个32位的寄存器都没有,现在要找一个8086的exe文件,恐怕都没那么容易了 :)
[解决办法]
这个 表示不懂
[解决办法]
引用:
这个题目的要求是将图片1的数据打印到显存中如图片2,可是我debug到子程序show_4str中的代码- mov es:[di],ax-时,t后发现他的数据并没有改成正确的数值31(字符1)左思右想这句代码应该没有问题,我的显存地址B800:00A2也没有计算错误,不太明白,请各位坛友指教,现在将debug图附上。
希望有坛友赐教

Assemb……

不懂 可以到汇编论坛问问
我的异常网推荐解决方案:程序员的一天,http://www.myexception.cn/other/1391144.html

热点排行