haiouda 发表于 2015-5-3 18:36:17

课程设计 1 我回来了

本帖最后由 haiouda 于 2015-5-4 09:36 编辑

assume cs:code,ds:data,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'   ;0-83

dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,19514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000 ;84-167

dw 3,7,9,13,28,38,130,220,476,778,1001,1142,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800;168-210

db 14 dup(0)   ;211-223

dd 120 dup(0)   ;224-480(224,14行开头)

data ends


stack segment
dw 16 dup(0)
stack ends


code segment

start:MOV AX,stack
      MOV SS,AX
      MOV SP,32
      
      MOV AX,data
      MOV DS,AX
               
               
                mov word ptr ds:,168
                mov bx,84
                mov si,0
                mov di,168                ;指向人数
      mov bp,288               
                mov cx,21
               
               
      z1:      push cx
            call movn   ;年份移到指定位置
      
      
               
                call shoru;总收入改成SACII码移到指定位置
               
               
                call men    ;人数改成SACII码移到指定位置
               
                call pjsr   ;平均收入改成SACII码移到指定位置
               
                pop cx
      loop z1
               
                callshow_str;显示
               
               

      
      MOV AX,4C00H
      INT 21H
               
movn:   
         
             mov cx,4
            
         w2: mov al,
               inc si
               mov ds:,al
               inc bp
               
               loop w2
               
               mov byte ptr ds:,0
               inc bp
               
            
      
      ret               
               

shoru:   
      
               
                                          
               mov ax,;读数据(收入)                                 
                         add bx,2
                         mov dx,                              
                         add bx,2   ;si 指向下一个数据
                                 
                                 push ax
                                 push dx
                                                               
                                 mov cx,
                                 add di,2

               call divdw    ;这次为求平均数
                           mov ds:,ax    ;平均收入低16位
                                 mov ds:,dx    ;平均收入高16位
                                                                                 
                                 pop dx
                                 pop ax
                            call sjbw   ; 分解各位
                        
                                 
               
               
                                 
               ret      

sjbw:   

         mov word ptr ds:,0   ;暂存被除数低16位
               mov word ptr ds:,0   ;用来记录cx(数据的长度)
               

               
                        s0:         mov cx,10
                           call divdw   ;这次目的是分解 年的总收入
                        
                         mov ds:,ax    ;保护被除数低16位
                                                   
                         push cx   ; 余数入栈(从低位到高位顺序入栈)
                           mov ax,ds:   ;这个内存单元用来记录入栈次数即数值长度
                         inc ax
                           mov ds:,ax
                        
                           mov ax,ds:
                           
                                 push dx
                                 or cx,dx
                           or cx,ax   ;商(高低16位全部为零)并且余数同时为零,即此数据被分解完毕
                                 pop dx
                                 inc cx    ;当cx为零时,用于退出循环
                         loop s0   ;余数为零,代表这个数已经按从低到高入栈完毕
               
                         mov cx,ds: ;数值长度给cx用于循环次数
                           
               
               
                     pop ax      ;数据个个位倒序出栈
                                 
                        
                           dec cx      ;每串数都以零开头,所以第一个数(0)不加30h,同时cx减少一次循环
               
               s1: pop ax
                         add al,30h;每位改成ASICII码
                         mov ds:,al               
                         inc bp
                         loop s1
                                 
         mov byte ptr ds:,0 ; 因为每组数字都以零开头,补个零结尾,这样要显示的数字实际开始位置为,ds:
               inc bp
               
               
               
         ret                                 
               
               
               
               
divdw:
          push bx
                  push ax
         
                  mov ax,dx
                  mov dx,0
                  div cx      ;高16位作除法
                  
                  mov bx,ax    ;ax高16位的商,dx余数
                  
                  pop ax      
                  div cx          ;低16位作除法

                  mov cx,dx
                  mov dx,bx
                  
         pop bx
             ret
               

               

               
men :   push di
      
         mov di,ds:
         mov ax,
               add di,2
               mov dx,0
               
               call sjbw
               
               mov ds:,di
         pop di   
   ret   

         
pjsr:    mov ax,ds:
         mov dx,ds:
               
               call sjbw
               
      ret         
               

show_str: mov ax,0b800h   ;显示字符串
          mov es,ax            
          mov ax,0
                  
                  mov al,3    ;显示位置,第九行                  
                  mov cl,10    ; 第三例
                  
                  mov bx,0
                  mov bl,160
                  mul bl
                  mov bx,0
                  add bx,ax
                  mov ax,0
                  mov al,2   
                  
                  mul cl
                  add bx,ax   ;bx为首字偏移值
                  
                  
                   mov ch,2      ; 颜色为绿色
                  
                  mov al,ch   ;颜色放al中保存
                  
                  mov di,0                  
                  mov si,288
               
                  mov cx,21
      x2:   push cx
            call show_str11                        
                  add bx,160
          mov di,0      

                  pop cx
                  loop x2
                  
                  ret
               
                  
                  
                  
show_str11:mov cx,4

      x5:push di
                x3:         push cx
                     

                  mov cl,
               mov ch,0
               jcxz x4      ;cx为零时 跳到s1
            
      
                                 
                      mov es:,cl
                      mov es:,al
                  
                      inc si
                      add di,2
                  
                      pop cx
                      jmp short x3
                  
                     
                  
         x4:         pop cx
                  pop di
                  
                        inc si
                        add di,28;显示二个数字之间加个空格,di必须为2的倍数
            loop x5      
                              
               
                     
               
               
ret               
               
               
               
               
               
code ends
end start               
               
               



               
               

         



用了一个白天的时间,大多数时间,在纠结几个基本的错误,比如2个小时,纠结 data 段设得小了,自己全然不知,导致错误,等

现在这个可以显示出来了就是有一部分被 debug 给刷新了,有谁能给个办法,看到全陪呀?


页: [1]
查看完整版本: 课程设计 1 我回来了