这个题目的要求是将图片1的数据打印到显存中如图片2,可是我debug到子程序show_4str中的代码- mov es:[di],ax-时[color=#FF0000][/color],t后发现他的数据并没有改成正确的数值31(字符1)左思右想这句代码应该没有问题,我的显存地址B800:00A2也没有计算错误,不太明白,请各位坛友指教,现在将debug图附上。
希望有坛友赐教
- Assembly code
assume cs:codedata 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 endsstack segment db 32 dup(0)stack endscode segmentstart: 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,21s1: push cx mov bp,4 mov cl,2 call show_4str inc dh pop cx loop s1 ;========收入写入显存段========= mov cx,21 mov di,84s2: 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,168s3: 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,84s4: 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,bpa: 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,0b: mov cx,10 call divdw push cx add di,1 ;si记录入栈次数 mov cx,ax jcxz ok1 jmp short bok1: mov cx,dx jcxz ok2 ;dx和ax的值都为0,表示除完,除法过程结束 jmp short bok2: mov cx,sic1: 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 de: 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 retcode endsend start