. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  课程设计1终于完成了~~~~  [待解决] 回复[ 12次 ]   点击[ 781次 ]  
qiangzi
[帖 主]   [ 发表时间:2010-01-27 14:12 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2010-01-07 10:37
自学汇编一个多月了吧!课程设计1终于完成了!
开始时思路不是很清晰,想了几个思路,都不系统,而且没办法对一个子程序多次调用,因为,每次调用子程序,都必须对子程序做一定的修改,没办法模块化!
后天在论坛上看到asm_sande的思路后,才开始了自己的设计,写完一个程序很快,不到一个小时吧,可是调试却让我很伤脑筋,先是不能编译,能编译后没有结果显示,想一步一步的跟踪,可是循环次数太多,最后,我把循环次数都改为一次,一步一步的跟踪,才完成了这个课程设计!
我觉得学汇编最重要的就是调试,在自己的调试过程中,慢慢的知道什么地方是自己容易忽视的地方,比如寄存器的冲突,栈的使用,深入理解计算机处理数据的过程,这次我才发现了对自己写的程序做注释的好处,这样不仅能把自己的思路系统一下,而且以后看到自己的程序也会很清楚的知道是什么作用!!(说了些废话)
大家多提点建议吧~~
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'  
    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,15275,17800  
data ends  
table segment
  db 672 dup (0)
table ends
stack segment
  dw 32 dup (0)
stack ends
code segment

start:mov ax,data
      mov ds,ax        ;ds指向data
      mov ax,table
      mov es,ax        ;es指向table 
      mov ax,stack
      mov ss,ax        ;ss指向stack
      mov sp,20h       ;sp指向栈顶
      mov bx,0         ;写入时寻址增量
      mov di,0         ;读取时双字增量
      mov si,0         ;读取时单字增量
         
      mov cx,21        ;循环次数       
    d:push ds:[di]
      push ds:[di+2]   
      pop es:[bx+2]
      pop es:[bx]      ;转移年份
      mov byte ptr es:[bx+4],0   ;末尾标识符
      mov ax,ds:[di+54h]         ;ax 被除数低位
      mov dx,ds:[di+56h]         ;dx 被除数高位
      mov es:[bx+7],dx           
      mov es:[bx+5],ax           ;转移总量
      push cx
      mov cx,ds:[si+0a8h]     ;cx 除数
      mov es:[bx+16],cx       ;转移人数
      call divdw              ;调用divdw
      pop cx
      mov es:[bx+22],ax       ;平均数低位入table
      mov es:[bx+24],dx       ;平均数高位入table
      add di,4                 
      add si,2
      add bx,32               ;增量
      loop d                  ;循环
     
      mov bx,0
      mov cx,21               ;循环次数
    e:mov ax,es:[bx+5]               
      mov dx,es:[bx+7]        
      mov di,5
      add di,bx
      call dtoc               ;总量化为ASCII码

      mov ax,es:[bx+16]
      mov dx,0
      mov di,16
      add di,bx
      call dtoc               ;人数化为ASCII码

      mov ax,es:[bx+22]       
      mov dx,es:[bx+24]
      mov di,22
      add di,bx
      call dtoc               ;平均值化为ASCII码
      add bx,32               ;增量
      loop e                  ;循环

      mov cx,21               ;循环次数
      mov di,0
      mov dh,2                ;行
    f:mov dl,4                ;列
      push cx                 ;因为下面要用的cl保存属性,所以cx入栈
      mov cl,2                ;属性:绿色
      mov si,0                
      add si,di               ;在es中读取年份              
      call show_str           ;调用show_str 

      mov dl,20
      mov cl,2
      mov si,5
      add si,di
      call show_str

      mov dl,40
      mov cl,2
      mov si,16
      add si,di
      call show_str

      mov dl,60
      mov cl,2     
      mov si,22
      add si,di
      call show_str
      pop cx

      add di,32                  ;增量,读取下一条
      inc dh                     ;行加1
      loop f
      mov ah,01h                 ;中断
      int 21h

      mov ax,4c00h
      int 21h
divdw:push bx         ;入参ax被除数低位,dx被除数高位,cx除数
      push di
      mov bp,ax      
      mov ax,dx
      mov dx,0
      div cx
      mov di,ax      
      mov ax,bp
      div cx
      mov cx,dx
      mov dx,di      ;回参ax商低位,dx商高位
      pop di
      pop bx  
      ret
 dtoc:push bx          
      push cx
      push si          ;子程序中使用的寄存器入栈
      mov si,0
    a:mov cx,10        ;除数
      call divdw
      add cx,30h
      push cx
      inc si
      mov cx,ax
      jcxz b
      jmp short a     
    b:mov cx,si        ;cx中储存循环次数
      mov bx,0         
    c:pop es:[bx+di]    
      inc bx           ;后来出栈的数据的低16为把前面出栈的高16为覆盖
      loop c
      pop si
      pop cx
      pop bx           ;子程序中使用的寄存器出栈
      ret
show_str:push dx
         push bx
         push cx
         mov ax,0B800H
         mov ds,ax     ;es指向显示缓冲区
         dec dh
         mov al,0a0h
         mul dh
         dec dl
         add dl,dl
         mov dh,0
         add ax,dx
         mov bx,ax     ;计算偏移地址
         mov ah,cl     ;ah暂时储存颜色
       s:mov cl,es:[si];字符放在cl中
         mov ch,0
         jcxz ok       ;判断是否结束
         mov ch,ah     ;颜色放在ch中
         mov ds:[bx],cx;放于显示缓存区
         add bx,2
         inc si        ;计数增加
         jmp short s   ;跳转
      ok:pop cx
         pop bx
         pop dx
         ret
code ends
end start
versaariel
[第1楼]   [ 回复时间:2010-01-27 14:21 ]   [引用]   [回复]   [ top ] 
荣誉值:62
信誉值:0
注册日期:2009-12-03 13:14
引用:
我觉得学汇编最重要的就是调试
------------------------------------------
调试了才能充分的理解掌握,别人说的未必能让自己很好的消化,加油^-^
qiangzi
[第2楼]   [ 回复时间:2010-01-27 15:00 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2010-01-07 10:37
回复:[第1楼]
------------------
说的对啊,呵呵,大家一起努力
regex
[第3楼]   [ 回复时间:2010-01-30 12:25 ]   [引用]   [回复]   [ top ] 
荣誉值:61
信誉值:0
注册日期:2009-12-19 01:51
佩服一下~~~, 我才做完三个实验。。。
qiangzi
[第4楼]   [ 回复时间:2010-01-30 18:50 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2010-01-07 10:37
回复:[第3楼]
------------------
呵呵,你比我学的细致,经常在论坛上看到你的评论~~
regex
[第5楼]   [ 回复时间:2010-01-30 23:49 ]   [引用]   [回复]   [ top ] 
荣誉值:61
信誉值:0
注册日期:2009-12-19 01:51
回复:[第3楼]
------------------
呵呵,你比我学的细致,经常在论坛上看到你的评论~~
------------------
回复:⊙﹏⊙b汗, 无地自容一下先。。。
thedaydreamwang
[第6楼]   [ 回复时间:2010-02-01 04:12 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18
高手!!我学了三个多月了还卡在第十章
thedaydreamwang
[第7楼]   [ 回复时间:2010-02-05 07:26 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18
show子程序不能显示0行0列吗???
thedaydreamwang
[第8楼]   [ 回复时间:2010-02-05 07:26 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18
如果dh和cl为零的情况程序会出错!!
qiangzi
[第9楼]   [ 回复时间:2010-02-05 11:05 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2010-01-07 10:37
回复:[第7楼]
------------------
我认为应该可以,最好在实dos下试试
thedaydreamwang
[第10楼]   [ 回复时间:2010-02-06 07:24 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18
总算完成了贴出来吧高手指点
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'   
    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,15275,17800   
data ends   
table segment 
  db 672 dup (0) 
table ends 
stack segment 
  dw 32 dup (0) 
stack ends 
code segment 
   start:mov ax,data
          mov ds,ax
          mov ss,ax
          mov ax,0
          mov sp,ax
          mov ax,table
          mov es,ax
          call show_str1
                call show_str2
                call show_str3
                call quyu
                call show_str4
          mov ax,4c00h
            int 21h
show_str1:push ax
               push bx
               push cx
               push dx
                        mov ax,0
               mov dx,0
               mov bx,0
               mov cx,21
    d:        mov ax,ds:[bx]
               push ax
               pop es:[bx+2]
               mov ax,ds:[bx+2]
               push ax
               pop es:[bx+4]
               mov ax,0
               mov ds:[bx],ax
               mov ds:[bx+2],ax
               add bx,4
               loop d
               mov cx,21
               mov bx,0
                        mov dh,2         ;显示坐标一定要放在loop之前
               mov dl,2
    e:         mov ax,es:[bx+2]
               push ax
               mov ax,es:[bx+4]
               push ax
               pop ds:[2]
               pop ds:[0]
               push cx
                        mov cx,02h
               call show_str
               pop cx
               add bx,4
               inc dh
               loop e
              
               pop dx
               pop cx
               pop bx
               pop ax
               ret
show_str2:push ax
               push bx
                        push bp
               push cx
               push dx
                        mov ax,0
               mov dx,0
               mov bx,0
                        mov dh,2         ;显示坐标一定要放在loop之前
               mov dl,20
                        mov cx,21
        f:                mov bp,dx
                  mov ax,ds:[bx+84]
                        mov dx,ds:[bx+86]
                        call dtoc
                        mov dx,bp
                        push cx
                        mov cx,02h
                        call show_str
                        pop cx
               add bx,4
               inc dh
                        loop f
                        pop dx
               pop cx
                        pop bp
               pop bx
               pop ax
               ret



show_str3:push ax
               push bx
                        push bp
               push cx
               push dx
                        mov ax,0
               mov dx,0
               mov bx,0
                        mov dh,2         ;显示坐标一定要放在loop之前
               mov dl,40
                        mov cx,21
        g:                mov bp,dx
                  mov ax,ds:[bx+168]
                        mov dx,0
                        call dtoc
                        mov dx,bp
                        push cx
                        mov cx,02h
                        call show_str
                        pop cx
               add bx,2
               inc dh
                        loop g
                        pop dx
               pop cx
                        pop bp
               pop bx
               pop ax
               ret




show_str4:push ax
               push bx
                        push bp
               push cx
               push dx
                        mov ax,0
               mov dx,0
               mov bx,0
                        mov dh,2         ;显示坐标一定要放在loop之前
               mov dl,60
                        mov cx,21
        t:                mov bp,dx
                  mov ax,es:[bx+186]
                        mov dx,es:[bx+188]
                        call dtoc
                        mov dx,bp
                        push cx
                        mov cx,02h
                        call show_str
                        pop cx
               add bx,4
               inc dh
                        loop t
                        pop dx
               pop cx
                        pop bp
               pop bx
               pop ax
               ret












quyu:       push ax
               push bx
                        push di
                        push bp
               push cx
               push dx
                        mov di,0
                        mov dx,0
                        mov bx,0
                        mov cx,21
        x:                mov bp,cx
                  mov ax,ds:[bx+84]
                        mov dx,ds:[bx+86]
                        mov cx,ds:[di+168]
                        call div_str
                        mov es:[bx+186],ax
                        mov es:[bx+188],dx
                        mov cx,bp
                        add bx,4
                        add di,2
                        loop x
                        pop dx
               pop cx
                        pop bp
                        pop di
               pop bx
               pop ax
               ret








                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
dtoc: push di
           push ax
           push bx
        push si 
        push bx 
        push cx 
a:      mov cx,dx 
        jcxz goon   ;判断dx高位是否为0 
        mov cx,0ah 
        call div_str 
        push cx 
        inc si 
        jmp short a 
goon:mov cx,ax 
         jcxz  re_num 
         mov cx,0ah 
         call div_str 
         push cx 
         inc si 
         jmp short goon 
re_num: mov cx,si 
s:           pop ax 
             mov bx,30h 
             add  ax,bx 
             mov ds:[di],ax 
             inc di 
             loop s 
             pop cx 
             pop bx 
             pop si 
                   pop bx
                   pop ax
             pop di 
             ret 
div_str:push bx 
          push ax  
          mov ax,dx  
          div cl  
          mov bx,ax  
          mov ah,0  
          mov dx,ax  
          pop ax  
          push dx 
          mov dx,bx  
          mov dl,dh 
          mov dh,0  
          div cx  
          mov cx,dx  
          pop dx 
          pop bx 
          ret




show_str:     push di 
                  push si
                           push dx
                  push bx  
                  push es                  ;注意ss:sp指向长度
                  dec dh                   ;送入变量dh行号,dl为排号注意寄存器的使用cl为颜色 
                   dec dl    
                   mov ax,0 
                   mov al,dh    
                   mov bx,0    
                    mov bl,10    
                    mul bl 
                    mov bx,ax 
                    mov ax,0b800h 
                    add ax,bx 
                    mov es,ax 
                    mov ax,0 
                    mov  al,dl    
                    add al,dl    
                    mov bx,ax    
                    mov di,0    
                    mov  ch,cl     
       ok:        mov cl,[si]    
                    push cx    
                    mov ch,0    
                    jcxz return    
                    pop cx   
                    mov es:[bx+di],cx   
                    add di,2    
                    inc si    
                    jmp short ok    
       return:   pop cx 
                    pop es 
                    pop bx
                                pop dx
                    pop si 
                    pop di 
                    ret 
code ends
end start
thedaydreamwang
[第11楼]   [ 回复时间:2010-02-06 07:38 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18
55结果出错了,郁闷啊!!又要debug32了!!!要走的路很长哇!!
thedaydreamwang
[第12楼]   [ 回复时间:2010-02-07 23:16 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18
找到原因了子程序div_str的问题改成这样就OK了不影响
div_str:push bx 
          push ax  
          mov ax,dx
             mov dx,0
          div cx
          mov bx,ax  
          pop ax  
          push bx 
          div cx  
          mov cx,dx  
          pop dx 
          pop bx 
          ret
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved