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

我的博客

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

[2011-06-03 17:27] 10章课程设计

图片载入中
assume cs:codesg 

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 150h dup (0) 
table ends 

stack segment 
      db 0ffffh dup (0) 
stack ends 

codesg segment 
start: mov ax,data 
       mov ds,ax 

       mov ax,table 
       mov es,ax 

       mov ax,stack 
       mov ss,ax 
       mov sp,0h 

       sub bx,bx 
       mov cx,21

   xh: push cx                 ;压栈cx

       mov cx,2                ;初始化内循环 cx=2
       sub si,si               ;初始化内循环 si=0 
       mov di,ss:[0]           ;将ss:[0]中的数据送入di

    s: mov ax,ds:[di]          ;将ds:[di]中的数据送入ax
       mov es:[bx+si],ax       ;将ax中的数据送入 es:[bx+si]
       
       mov ax,ds:[di+84]       ;将ds:[di+84]中的数据送入ax
       push ax                 ;压栈 ax
       mov es:[bx+si+5],ax     ;将ax中的数据送入es:[bx+si+5]

       add di,2                ;di=di+2
       add si,2                ;si=di+2
       loop s                  ;cx=cx-1 cx不等于0 跳转到标号
       mov ss:[0],di           ;将di送入ss:[0]暂存
       
       mov di,ss:[2]           ;将ss:[2]中的数据送入di           

       pop dx                  ;出栈dx
       pop ax                  ;出栈ax

       div word ptr ds:[di+168] ;ax=(dx*65536+ax)/ds:[di+168]
       mov es:[bx+0dh],ax       ;将ax中的商送入es:[bx+0dh]
       mov ax,ds:[di+168]       ;将ds:[di+168]送入ax
       mov es:[bx+0ah],ax       ;将ax送入es:[bx+0ah]

       add di,2                 ;di=di+2
       mov ss:[2],di            ;将di送入ss:[2]暂存

       add bx,16                ;bx=bx+16指向table的下一行
       pop cx                   ;出栈cx
       
       loop xh                  ;cx=cx-1 cx<>0则跳转到标号
      
;;;;;;;;;;;;;;;;;;;;;;;以上位公司的年份、收入、雇员和人均收入的计算即传送。;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


       mov ax,table             ;es指向table段
       mov es,ax
       
       mov ax,stack             ;ds指向stack段
       mov ds,ax

       sub di,di                ;初始化di=0
       sub bx,bx
       mov cx,21                ;初始化循环 cx=21
       sub dh,dh                ;dh=0 行

       call qp                  ;调用子列程清屏
       
show1: push cx
       push bx                  ;因为年份本来就是十进制字符不必转换就直接调用子列程bx定位行
                                ;,又因为同一循环内年份下面的程序也要调用子列程所以会冲突那么可以将bx压栈后面在恢复        

       mov cx,3                 ;将行压栈三次
    d: push dx
       loop d

       sub si,si                ;初始化si=0传入子列程
       
       
       push ds                  ;压栈ds中的段地址
       push es                  ;压栈es中的段地址
       pop ds                   ;出栈到ds

       mov cl,2                 ;cl=2 绿色      
       mov dl,10                ;dl=10 列
       call show_str            ;调用子列程 show_str 显示
       pop ds                   ;恢复原段地址到ds
       ;年份显示
        
       sub bx,bx                ;初始化子列程 bx=0

       mov ax,es:[di+5]         ;将es:[bx+5]中的数据送入ax 传入子列程 ax为低16位被除数
       mov dx,es:[di+7]         ;将es:[bx+7]中的数据送入ax 传入子列程 dx为高16位被除数
       call dtco                ;调用子列程 dtco 计算出十进制字符串 返回的结果存放在 ss:[0]为起始处
       ;收入转换为十进制字符

       pop dx                   ;出栈行
       mov dl,20                ;dl=20列 传入子列程 
       call show_str            ;调用 show_str
       ;显示收入
        
       mov ax,es:[di+0ah]       ;将es:[bx+0ah]中的数据送入ax 传入子列程
       sub dx,dx                ;dx传入0
       call dtco                ;......
       ;雇员转换

       pop dx
       mov dl,30                
       call show_str
       ;显示雇员 

       mov ax,es:[di+0dh]
       sub dx,dx
       call dtco
       ;人均收入转换

       pop dx       
       mov dl,40
       call show_str
       ;人均收入显示
       
       inc dh                           ;dh=dh+1
       add di,16                        ;di=di+16
       pop bx                           ;出栈bx并加16
       add bx,16
       pop cx                           ;出栈cx计数循环
       loop show1

;;;;;;;;;;;;;;;;;;;;;;;;;;;年份 收入 雇员及人均收入的 显示;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
     mov ax,4c00h  
     int 21h
     
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 程序返回 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 一下为子列程 dtco ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 dtco: push ax             
       push bx
       push cx
       push dx
       push si
       push bp
       ;压栈寄存器中的数据

        sub bp,bp
        sub si,si
dtco_s: mov cx,0ah                ;除数为10
        push ax                   ;首先压栈低16位(ax)中的数据
        mov ax,dx                 ;然后将高16位(dx)赋给ax
        sub dx,dx                 ;清除dx中的数据
        div cx                    ;(dx*65536+ax)/(cx)=(ax)商 (dx)余
        mov bx,ax                 ;将商赋给bx暂存
        pop ax                    ;出栈压栈的低16位被除数到ax
        div cx                    ;(dx*65536+ax)/(cx)=(ax)商 (dx)余
        add dx,30h                ;余数加上30h等于十进制字符
        push dx                   ;压栈十进制字符
        mov dx,bx                 ;将高16位上赋给dx
        mov cx,ax                 ;将定16位商赋给cx
        inc si                    ;用si进行计数
        jcxz ret_dtco             ;(cx)不等于0则不跳转
        jmp short dtco_s          ;进行循环

ret_dtco: mov cx,si               ;将si中的数据赋给cx进行循环
   ret_s: pop [bp]                ;出栈十进制字符到cx    
          inc bp                  ;(bp)=(bp)+2 bp指向下一个字单元
          loop ret_s
          
          pop bp
          pop si
          pop dx                 
          pop cx
          pop bx
          pop ax
         ;出栈数据
          
          ret                    ;返回上次执行call dtco 下条指令的ip 最后才是返回sub dh,0


;;;;;;;;;;;;;;;;;;;;;;;;;; 一下为子列程show_dtr ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

show_str: push ax                ;压栈各个寄存器的数据 
          push bx 
          push cx 
          push dx 
          push si 
          push di
          push ds 
          push es 

          mov ax,0b800h          ;初始化显存段地址 
          mov es,ax 

          mov al,160             ;al*dh+dl 得出显存的偏移地址 
          inc dh                 ;行号是从0开始所以8行应该是8+1 
          mul dh 
          sub dh,dh 
          add dx,dx 
          add ax,dx 
          mov di,ax              ;将偏移地址赋给di 

          
          mov al,cl              ;将属性送入到al存放 
     
    show: sub cx,cx
          mov cl,ds:[bx+si]
          jcxz ret_show  
          mov ch,al              ;将内存ss:[0]单元中存放的属性送入ah              
          mov es:[di],cx         ;将(ax)送入显存es:[di]  
          inc si                 ;(si)=(si)+1 
          add di,2               ;(di)=(di)+2 
          jmp short show

ret_show: pop es                 ;出栈 
          pop ds
          pop di 
          pop si 
          pop dx 
          pop cx 
          pop bx 
          pop ax 
          ret 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;一下为子列程qp(作用清屏);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
qp: push ax
    push cx
    push ds
    push si
    ;压栈关联寄存器

    mov ax,0b800h      ;初始化需要清屏的显存地址
    mov ds,ax
    sub si,si

    mov ax,' '         ;给ax寄存器赋空字符然后把它传送到显存达到清屏的效果
    mov cx,2000        ;ax为16为寄存器对应一个显存字单元所以 循环次数=25行*(160列/2)
 q: mov [si],ax        
    add si,2
    loop q

    pop si
    pop ds
    pop cx
    pop ax
    ret
    
codesg ends

end start
       
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
评论次数(0)  |  浏览次数(495)  |  类型(汇编作业) |  收藏此文  | 
 
 请输入验证码  (提示:点击验证码输入框,以获取验证码