. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  课设1,不知道哪有错  [待解决] 回复[ 4次 ]   点击[ 451次 ]  
walkmanilove
[帖 主]   [ 发表时间:2007-11-19 15:04 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2007-10-22 22:29
assume cs:codesg,ss:stack 
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 

data ends 
table segment
        db 16 dup (0)
table ends
stack segment 
        db 16 dup (0)
stack ends 
codesg segment 
main:   
        mov ax,table
        mov ds,ax
        mov ax,data
        mov es,ax
        mov ax,stack
        mov ss,ax
        mov sp,16
        mov bx,0;bx用于保存输入字符的偏移地址
        mov si,0
        mov di,0
        mov cx,21
s0:
        mov ax,es:[bx].0h
        mov [si],ax
        mov ax,es:[bx].2h
        mov [si].2h,ax
        mov word ptr [si].4h,0
        mov dh,1
        mov dl,2
        mov cl,2
        call show_str
;以上实现在显示器上显示年份
        mov ax,es:[bx].54h
        mov dx,es:[bx].56h
        call dtoc
        add dl,10
        mov cl,2
        call show_str
;以上实现在显示器上显示收入
        mov ax,es:[si].0a8h
        mov dx,0
        call dtoc
        add dl,10
        mov cl,2
        call show_str
;以上实现在显示器上显示雇员数
        mov ax,es:[bx].54h
        mov dx,es:[bx].56h
        div word ptr es:[si].0a8h
        mov dx,0
        call dtoc
        add dl,10
        mov cl,2
        call show_str
;以上实现在显示器上显示平均收入
        add si,2
        add bx,4
        inc dh
        loop s0

        mov ax,4c00h
        int 21h

;子程序show_str,入口参数:dh(显示行数),dl(显示列数),cl(字符属性)还回参数:无
show_str:
        push bx
        push dx
        push cx
        push es
        push si

        mov ax,0b800h
        mov es,ax
        mov bx,0
        mov al,0a0h
        dec dh
        mul dh
        add dl,dl
        mov dh,0
        add ax,dx
        mov bx,ax;确定初始显存偏移地址
        mov ah,cl;写入字符属性
        mov si,0
s:
        mov ch,0
        mov cl,[si]
        jcxz ok
        mov al,cl
        mov es:[bx],ax
        inc si
        add bx,2
        jmp short s
ok:
        pop si
        pop es
        pop cx
        pop dx
        pop bx
        ret

;子程序dtoc,入口参数:ax(dword数据低16位),dx(dword数据高16位),ds:si指向字符串首

地址,还回参数:无
dtoc:
        push cx
        push si
        mov si,0
ok2:        
        mov cx,10
        call divdw
        add cl,30h
        push cx
        inc ax
        mov cx,ax
        or cx,dx;确定商是否为0 
        jcxz ok2
        mov cx,ax
s1:        pop cx
        mov [si],cl
        inc si
        loop s1
        mov ax,0
        mov [si],ax
        pop si
        pop cx
        ret

;子程序divdw,入口参数:ax(被除数低16位),dx(被除数高16位),cx(除数)还回参数:dx(结果高

;16位),ax(结果的低16位),cx(余数)
divdw:
        push bx
        push cx
        push dx
              push si 
               
        mov bx,ax;低16位保存,一会做L/N
        mov ax,dx
        mov dx,0
        div cx;H/N
        mov si,ax;保存商到si,一会用作商的高位
        mov ax,bx
        div cx;L/N
        mov cx,dx;余数保存到cx
        mov dx,si;商高位保存到dx
       
              pop si
        pop dx 
        pop cx
              pop bx
        ret
        


codesg ends
end main
        

;以上是我写的,但就是结果不对,调试也不知道问题出在哪(调着就弹出来了)。
啊。。。。。疯了都。。。
cat442
[第1楼]   [ 回复时间:2007-11-19 16:17 ]   [引用]   [回复]   [ top ] 
荣誉值:16
信誉值:6
注册日期:2007-06-26 16:56
冷静 再冷静 

坚持 再坚持 

程序就是靠编程者的细心和耐心调出来的 

可以讲点方法策略  要一步一步走 一部分一部的调试,先把子程序一一调通,保证实现了预期的功能再向下进行。
walkmanilove
[第2楼]   [ 回复时间:2007-11-19 19:54 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2007-10-22 22:29
子程序经过修改调试通过:
下面是我后的代码,但不知道主程序问题出在哪
assume cs:codesg,ss:stack 
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 

data ends 
table segment
        db 16 dup (0)
table ends
stack segment 
        db 256 dup (0)
stack ends 
codesg segment 
main:   
        mov ax,table
        mov ds,ax
        mov ax,data
        mov es,ax
        mov ax,stack
        mov ss,ax
        mov sp,100h
        mov bx,0;bx用于保存输入字符的偏移地址
        mov si,0
        mov di,0
        mov cx,21
        mov dh,3
s0:        
        mov ax,es:[bx].0h
        mov [si],ax
        mov ax,es:[bx].2h
        mov [si].2h,ax
        mov byte ptr [si].4h,0
        mov dl,2
        mov cl,2
        call show_str
;以上实现在显示器上显示年份
        mov ax,es:[bx].54h
        mov dx,es:[bx].56h
        call dtoc
        add dl,10
        mov cl,2
        call show_str
;以上实现在显示器上显示收入
        mov ax,es:[si].0a8h
        mov dx,0
        call dtoc
        add dl,10
        mov cl,2
        call show_str
;以上实现在显示器上显示雇员数
        mov ax,es:[bx].54h
        mov dx,es:[bx].56h
        div word ptr es:[si].0a8h
        mov dx,0
        call dtoc
        add dl,10
        mov cl,2
        call show_str
;以上实现在显示器上显示平均收入
        add bx,4
        inc dh
        loop s0

        mov ax,4c00h
        int 21h

;子程序show_str,入口参数:dh(显示行数),dl(显示列数),cl(字符属性)还回参数:无
show_str:
        push bx
        push dx
        push cx
        push es
        push si

        mov ax,0b800h
        mov es,ax
        mov bx,0
        mov al,0a0h
        dec dh
        mul dh
        add dl,dl
        mov dh,0
        add ax,dx
        mov bx,ax;确定初始显存偏移地址
        mov ah,cl;写入字符属性
        mov si,0
s:
        mov ch,0
        mov cl,[si]
        jcxz ok
        mov al,cl
        mov es:[bx],ax
        inc si
        add bx,2
        jmp short s
ok:
        pop si
        pop es
        pop cx
        pop dx
        pop bx
        ret

;子程序dtoc,入口参数:ax(dword数据低16位),dx(dword数据高16位),ds:si指向字符串首

地址,还回参数:无
dtoc:
        push bx
        push cx
        push si
        mov si,0
        mov bx,0

        
s2:        or ax,dx;确定商是否为0 
        mov cx,ax
        jcxz ok2
        mov cx,10
        call divdw
        add cl,30h
        push cx
        inc bx
        jmp short s2
        

ok2:        mov cx,bx
s1:        pop ax
        mov [si],al
        inc si
        loop s1
        mov al,0
        mov [si],al
        pop si
        pop cx
        pop bx
        ret
;子程序divdw,入口参数:ax(被除数低16位),dx(被除数高16位),cx(除数)还回参数:dx(结果高

;16位),ax(结果的低16位),cx(余数)
divdw:
        push bx
        push dx
              push si 
               
        mov bx,ax;低16位保存,一会做L/N
        mov ax,dx
        mov dx,0
        div cx;H/N
        mov si,ax;保存商到si,一会用作商的高位
        mov ax,bx
        div cx;L/N
        mov cx,dx;余数保存到cx
        mov dx,si;商高位保存到dx
       
              pop si
        pop dx 
              pop bx
        ret
codesg ends
end main
cat442
[第3楼]   [ 回复时间:2007-11-20 09:53 ]   [引用]   [回复]   [ top ] 
荣誉值:16
信誉值:6
注册日期:2007-06-26 16:56
我提两个,这对赢两类问题
比如
1 你的divdw dx作为参数,又同时返回结果高16位,但是你对dx进行了压栈和出栈,那么这个值丢失了
2 你主程序设置先 cx为21 之后传参又改变了cx 之前并未保存 cx初始设置失效了 循环次数不对了

建议楼主把程序从头到尾查一遍,把类似逻辑错误都找出来,如果还有问题再结合debug调试。
goal00001111
[第4楼]   [ 回复时间:2007-12-17 18:55 ]   [引用]   [回复]   [ top ] 
荣誉值:3
信誉值:9
注册日期:2007-10-19 10:16
实现在显示器上显示平均收入时,你没有考虑除法溢出问题,有可能会带来麻烦。
dtoc子程序,没有考虑被除数为0的情况。
结构化不明显,主函数做了太多的事情。
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved