. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  课程设计一:大家来看看啊,不知道怎么了,一到第二十行就会溢出  [已解决] 回复[ 4次 ]   点击[ 614次 ]  
lijangwei
[帖 主]   [ 发表时间:2007-12-03 20:32 ]   [引用]   [回复]   [ top ] 
荣誉值:7
信誉值:9
注册日期:2007-11-01 20:06
assume cs:code,ds:data

data segment
   db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985','1986'
   db '1987','1988','1989','1990','1991','1992','1994','1995','1996'

   dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514,345980
   dd  590827,803530,1183000,1843000,2759000,2752000,4649000,5967000

   dw  3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2693,4037,5635,8226
   dw  11542,14430,15257,17800

   db 8 dup (0)
   val dw ?
data ends


stack segment
   db 64 dup (0)
stack ends

table segment
 db 21 dup ("year neww     ww     ??    ")
table ends


code segment
start:
    mov ax,data 
    mov ds,ax
    ;初始化一数据段
    mov ax,table 
    mov es,ax
    ;初始化一附加段
    mov ax,stack 
    mov ss,ax
    mov sp,40h

    call xieru

    mov dh,3
    mov dl,2   
    call xianshi

    mov ax,4c00h
    int 21h

;写入段,直接将数据转化为字符后,写入到附加段中
;中用到字过程DIVDW,把数字转化为字符,

xieru:
    mov si,0;源指向数据段中的数据
    mov bx,0;指向目的中的数据
  
    mov bp,0

    mov cx,21;设置循环的次数

 next:
    mov di,0;指向源中数据
    mov ax,ds:[si]
    mov dx,ds:[si+2]
    mov es:[bx+di],ax
    add di,2
    mov es:[bx+di],dx;把年份写入到附加段中
    
    add di,2
    mov es:[bx+di],byte ptr 20h
    inc di

    mov ax,ds:[si+54h]
    mov dx,ds:[si+56h]
    mov val,8
    call divdw;把收入放在DX:AX中,调用子过程DIVDW,把收入转化为字符串,反转后,装入到附加段中


    div word ptr ds:[bp+0a8h]
    push ax;由于调用子过程DIVDW时,保护了现场,所以这可用DX:AX除以人数,从而求出人均收入;并把收入入栈

    mov ax,ds:[bp+0a8h]
    mov dx,0
    mov val,6
    call divdw;把人数放入AX,后DX置0,调用子过程DIVDW,转化为字符
    

  
    pop ax;把收入放在AX中,后把收入转化为字符
    mov dx,0
    mov val,6
    call divdw


    add bx,20h;由于字符较多,加一点大的,

    add si,4
    add bp,2

    loop next

    ret

divdw:
    push ax
    push cx
    push dx
    push si;把程序中用到的寄存器入栈

    push bx

    mov si,0
    mov bx,0ah
  s:
    push ax
    mov cx,dx
    jcxz  s1   ; 判断一下高位是否为0,若为0,则不用再作,直接作低位除法                
    mov ax,dx
    mov dx,0

    div bx
    mov cx,ax;AX中存放的是高位的商,DX中存放的余数

  s1:
    pop ax
    div bx;用DX:AX除以bX

    mov ds:[0d2h+si],dl;把转化后的字符放在,一个数组中
    
    inc si
    mov dx,cx;把高位的商还放入DX中

    ;mov cx,ax
    ;jcxz ok;把低位的商放在CX中,判断其是否为0,若低位商为0 ,则表示结束,否则继续
    cmp ax,0
    jz ok
     
    jmp  s

  ok:       ;反转字符,后直接写入附加段中
    pop bx

    mov cx,  val;输入存入的位数
     
  s2:
    cmp si,0;判断SI是否为0,若为0,说明字符已把转完,下边补齐空格;否则继续把转字符
    jz s3
     mov al,ds:[0d2h+si-1]
     mov es:[bx+di],al
     inc di
     dec si
     dec cx
     jmp s2

  s3:
    mov es:[bx+di],byte ptr 20h
    inc di
    loop s2                           ;反转字符串,不足位补空格

    pop si
    pop dx
    pop cx
    pop ax

    ret


;显示段将附加段中数据直接写入显存,以便显示

xianshi:

  push ax
  push bx
  push si
  push di
  push bp 
  push ds 

  mov ax,0b800h
  mov ds,ax
  ;初始化一数据段

  mov al,160
  mul dh
  mov bx,ax
  mov al,2
  mul dl
  add bx,ax

  ;在BX中存入开始行的行地址
  mov si,0

  
  mov cx,21
b:
  mov di,0
  mov bp,0

  push cx
  mov cx,23
a: mov ah,8
  mov al,es:[bp+si]
  cmp al,20h
  jnz nn
  mov ah,0
  jmp nnn
nn:
  add al,30h
nnn:
  mov ds:[bx+di],ax
  add di,2
  inc si
  loop a
  add bx,0a0h
  add bp,20h
  pop cx
  loop b
  
  pop ds
  pop bp
  pop di
  pop si
  pop bx
  pop ax

  ret

code ends
end start

也不知怎么了,我看了好几天了,一到95年那一行,到结束时那一句LOOP NEXT下面的语句就会变
bloom
[第1楼]   [ 回复时间:2007-12-03 22:25 ]   [引用]   [回复]   [ top ] 
荣誉值:129
信誉值:0
注册日期:2007-07-12 18:33
回复:[贴 主]
------------------
在这里先鼓励一下楼主,然后希望楼主继续坚持不懈的继续调试程序中的错误。

课程设计一中最容易遇到的是除法溢出错误,但我运行了楼主的程序并不是这个错误,那么楼主应该继续在debug跟踪出错的地方,分析导致错误的代码,但在之前需要保证程序的逻辑是正确的,而且每个子程序也是正确的,这样才能更明确的断定出错的地方,也就是调试程序时,先想主程序的整个逻辑、思路是否正确,然后在看每个子程序是否正确,逐个确定后就知道是那里出问题了。 希望楼主早日完成~! :)
lijangwei
[第2楼]   [ 回复时间:2007-12-04 16:37 ]   [引用]   [回复]   [ top ] 
荣誉值:7
信誉值:9
注册日期:2007-11-01 20:06
明明第二十行最后一句是:LOOP NEXT
但是执行之后,却不是原先的指令,怎么回事啊?我用DEBUG跟踪了一下,发现也没有溢出来着啊?
lijangwei
[第3楼]   [ 回复时间:2008-02-28 15:53 ]   [引用]   [回复]   [ top ] 
荣誉值:7
信誉值:9
注册日期:2007-11-01 20:06
是溢出了,定义TABLE段的数据小于写入的数据,以致于把程序中的指令给覆盖掉了!
lijangwei
[第4楼]   [ 回复时间:2008-02-28 15:54 ]   [引用]   [回复]   [ top ] 
荣誉值:7
信誉值:9
注册日期:2007-11-01 20:06
此贴由 贴主 于 [ 2008-02-28 15:54 ] 结贴。 结贴原因:问题已解决
得分情况: 1楼(bloom):2分  
此问题已结贴!
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved