汇编网首页登录博客注册
youthangel的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
文章收藏

[2012-10-14 10:39] 课程设计一

图片载入中
comment            ;

这算是我写过的第一个汇编大程序了。虽然只有100多行,但这1区区一百行跟C的一百行可没法比。挺考验我对
代码的驾驭能力的。尤其是对子程序调用。
进步之处:
1、对整个程序的框架的把握还算到位,基本上是用子程序实现的
2、对现场的保护和恢复有的些许进步
不足之处:
1、代码的灵活性还不够,代码一直在生搬硬套 
2、对汇编程序的调试能力有点弱,调成代码占用了整个工作的把部分时间 
3、标号名称起的有点乱
4、最后的输出结果不够整齐,这个以后再做修改(我现在还没想到怎么弄,时间有点仓促) 

下面开始贴代码……      
     课程设计一
算法描述:
1、调用实验七的程序,设置table的数据
2、从table段取数据传给deal子程序进行处理
3、在deal子程序里返回调用溢出子程序divdw把得到的余数入栈(为了逆置),把栈中数据给mydata段
4、利用deal把一行的数据处理完,调用show_str子程序,显示一行的数据
5、把以上的工作重复21次(有21年的数据)    
;  
              assume    cs:code,ds:data,ss:stack
        data  segment
;年份
              db        '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984'
              db        '1985','1986','1987','1988','1989', '1990','1991','1992','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        21 dup('year summ ne ?? ')
       table  ends
;临时存储段192b       
      mydata  segment
              dw        16 dup(0)   ;32个字节
      mydata  ends
 ;栈段 192d     
       stack  segment
              dw        4 dup (0)   ;24个字节
       stack  ends
;代码段  
;bx,dx,cx            
        code  segment
      start:
              mov       ax,mydata
              mov       ax,stack
              mov       ss,ax
              mov       sp ,10h     ;初始化栈段
              call      settable    ;设置表格
              
              mov       dh,3        ;行
              mov       dl,5        ;列
              mov       bx,0        ;bx控制table段的行
              mov       cx,21       ;循环21次
              
          s:
              mov       si,0        ;记录一行的十进制数的个数
              push      dx
              mov       ax,table
              mov       ds,ax
              mov       ax,[bx]
              mov       dx,[bx+2]   ;取出年份
               
              mov       bp,mydata   ;年份就是按字符存储的直接显示
              mov       es,bp
              sub       ax,3030h
              mov       es:[si],ax
              sub       dx,3030h
              mov       es:[si+2],dx
              mov       al,20h
              mov       es:[si+4],al
              add       si,5
             
              mov       ax,[bx+5]
              mov       dx,[bx+7]   ;取出收入
              call      deal
              
              mov       ax,table
              mov       ds,ax
              mov       ax,[bx+10]  ;取出雇员数
              mov       dx,0fffh
              call      deal

              mov       ax,table
              mov       ds,ax
              mov       ax,[bx+13]  ;取出人均收入
              mov       dx,0fffh
              call      deal
              mov       ax,21h
              mov       [si],al
 ;显示一行子程序 
 ;dx控制显示位置,不能被其他子程序占用
              mov       ax,mydata
              mov       ds,ax
              mov       si,0        ;指定数据位置
              pop       dx
              call      show_str    ;调用子程序

              inc       dh          ;行加一
              add       bx,16       ;进入下一行
              loop      s
;暂停
              mov       ah,1
              int       21h
;退出
              mov       ax,4c00h
              int       21h
     comment            ;----------------显示子程序------------------------------
功能: 显示子程序
参数:DH 行,dl列 DS:[SI]数据位置
返回:无 
;  
   show_str:
              push      di
              push      es
              push      ax          ;保护现场

              mov       al,160
              mul       dh          ;算出第dh行在显存中的位置
              mov       di,ax
              mov       al,2
              mul       dl          ;算出第dl列在第dh行的第几个内存单元
              add       di,ax       ;算出显存的开始单元
              mov       ax,0b800h
              mov       es,ax       ;初始es
;开始显示    
         s1:
              mov       al,[si]     ;取出要显示的字符
              cmp       al,21h      ;判断是否是行结束符
              je        return      ;是的话就返回的主程序
              cmp       al,20h      ;判断是否是空格
              je        space       ;是的话就空八个格
              add       al,30h      ;不是空格,开始处理变成对应的ASCII
              mov       es:[di],al  ;放入显存
              mov       al,2
              mov       es:[di+1],al            ;设置显示属性
              add       di,2
         sc:
              inc       si
              jmp       s1
      space:                        ;处理空格
              add       di,16       ;空八个格
              jmp       sc
;显示结束     
     return:
              pop       ax          ;恢复现场
              pop       es
              pop       di
              ret
                             
     comment            ;-----------------数据处理子程序----------------------------
功能:处理数据
参数: DX AX
返回:myData段中的一行数据 
;调用除法子程序
;判断是否除尽
;没除尽,入栈,循环
;除尽了,放入temp段中 加上标志' '空格20h
;
       deal:
 ;保护现场
              push      cx
              push      bx
;开始处理
              mov       bp,0        ;初始化计数器
              cmp       dx,0fffh    ;判断是多少位的数据,其实这一步有点多余,16位的除法可以用32位的除法子程序处理
              jne       l
       lows:                        ;16位的被除数处理
              mov       bx,10
              call      divw        ;调用除法子程序
              cmp       ax,0        ;判断商是否为零
              je        lo
              push      bx          ;把余数入栈
              inc       bp
              jmp       lows
         lo:
              push      bx
              inc       bp
              jmp       same
              
          l:                        ;32位的被除数处理
              mov       bx,10
              call      divdw       ;调用除法子程序
              cmp       dx,0        ;判断商是否为零
              je        putdata
       n0ax:
              push      cx          ;把余数入栈
              inc       bp
              jmp       l
    putdata:
              cmp       ax,0        ;判断商是否为零
              jne       n0ax
              push      cx
              inc       bp
;-----------------从栈到mydata-----------------             
       same:
              mov       ax,mydata
              mov       ds,ax
         s0:
              cmp       bp,0
              je        bk
              pop       ax          ;从栈中取数据
              mov       [si],al
              inc       si
              dec       bp
              jmp       s0
       back:
;处理结束                   
              pop       bx
              pop       cx
 ;恢复现场 
              ret
         bk:
              mov       al,20h      ;加空格表示一个数结束如:16
              mov       [si],al
              inc       si
              jmp       back

;------------------子程序 16位的除法溢出-------------------------- 
     comment            ;
 功能:解决16位除法溢出问题
参数:ax被除数,bh除数
返回:AX 商,bl余数  
;             
       divw:                        ;15位的除法溢出
;保护现场
              push      dx
;开始运算 
              mov       dl,al       ;保存低位
              mov       al,ah
              mov       ah,0
              div       bl          ;商在al中,余数在ah中
              mov       dh,al       ;保存高位商
              mov       al,dl       ;在次组成16位
              div       bl
              mov       bl,ah       ;余数放在bl中
              mov       ah,dh       ;商放在ax中
;运算结束,结果:商在ax中,余数在bl中 
              pop       dx
;恢复现场
              ret
;------------------子程序32位的除法溢出-------------------------- 
     comment            ;
 功能:解决32位除法溢出问题
参数:dx ax被除数,bx除数
返回:DX AX 商,cx余数  
;        
      divdw:                        ;32位的除法溢出
;保护现场
;开始运算 
              push      ax          ;把低位保存起来
              mov       ax,dx
              mov       dx,0
              div       bx          ;高八位的商在ax中,余数在dx中
              mov       cx,ax       ;把高位商给cx
              pop       ax          ;低位出栈
              div       bx          ;低位商在ax中,余数在dx中
              xchg      cx,dx       ;dx和cx中的数据交换
;运算结束,结果:商在dx:ax中,余数在cx中 
;恢复现场
              ret
     comment            ;-------------设置表格--------------------------
功能:设置表格子程序
参数:无
返回:无     
;    
   settable:
              mov       ax,data
              mov       ds,ax
              mov       bx,0        ;ds:bx->数据
              mov       si,168      ;ds:si->雇员人数
              
              mov       ax,table
              mov       es,ax
              mov       di,0        ;es:di->表格

              mov       cx,21       ;循环21次
         s2:
;复制年份 
              mov       ax,[bx]
              mov       dx,[bx+2]
              mov       es:[di],ax
              mov       es:[di+2],dx            ;完成复制年份  四个字节
;复制收入
              mov       ax,[bx+84]
              mov       dx,[bx+86]
              mov       es:[di+5],ax
              mov       es:[di+7],dx            ;完成收入的复制

              div       word ptr[si]
;将人均收入放入指定位置
              mov       es:[di+13],ax
;复制雇员数
              mov       ax,[si]
              mov       es:[di+10],ax           ;完成雇员数的复制
              
              add       bx,4
              add       si,2
              add       di,10h
              loop      s2
              ret
              
        code  ends
              end       start
评论次数(2)  |  浏览次数(251)  |  类型(汇编作业) |  收藏此文  | 

[  fpamc   发表于  2012-10-15 08:03  ]

博主可以调整下。让显示列左对其的。

[  youthangel   发表于  2012-10-15 09:54  ]

恩恩,会的。

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码