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

我的博客

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

[2013-02-24 15:30] 课程设计一

assume cs:code

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

table1 segment
  db 21 dup ('year summ ne ?? ')      ;预备21个16位段;预设空格;给整理后的数据。
table1 ends

table2 segment
  db 1024 dup (0)
table2 ends          ;数据对应ASCII码预留          

stack segment
  dw 32 dup (0)   
stack ends           ;设置栈段

code segment

  start:mov ax,stack
        mov ss,ax
        mov sp,64              ;ss:sp为栈段
        mov ax,table1
        mov ds,ax
        mov bp,0               ;ds:bp指向整理后字符串首地址
        mov ax,data
        mov es,ax
        mov bx,0               ;es:bx指向需整理数据的首地址;同时是年份和总收入变量
        mov si,0               ;雇员人数变量初始化
        mov cx,21              ;有21组数据,设21个循环
     z0:push cx                ;21组数据循环入栈
        mov cx,4               ;年份数字4循环
        mov di,0               ;年份列变量
     z1:mov al,es:[bx][di]
        mov ds:[bp][di],al
        inc di                 ;将年份从data段移入table段
        loop z1
        mov ax,es:84[bx]
        mov dx,es:86[bx]
        mov ds:5[bp],ax
        mov ds:7[bp],dx        ;将总收入从data段移入table段
        mov cx,es:168[si]
        mov ds:10[bp],cx       ;将雇员人数从data段移入table段
        div cx
        mov ds:13[bp],ax       ;总收入/雇员人数,商放入table段
        add bx,4               ;年份和总收入变量bx+4
        add bp,16              ;table段中完成一行数据整理,行变量bp指向下一行
        add si,2               ;雇员人数变量+2
        pop cx                 ;21组数据循环参数出栈
        loop z0

        mov ax,table2
        mov ds,ax
        mov si,0               ;ds:si作为数据转换成ASCII码字符串后的存放地址,同时si也作为字符的列变量
        mov ax,table1
        mov es,ax
        mov bx,0               ;es:bx指向整理好后数据(bx为行变量)
        mov dh,2               ;(dh)=字符显示行号(取值范围0~24)
        mov cx,21              ;21组数据及字符串循环
     g0:push cx
        mov dl,10              ;(dl)=字符显示列号(取值范围0~80);此处设置其在行内的初始位置
        mov di,0               ;年份从table1段移入table2段的列变量
        mov cx,4
     g1:mov al,es:[bx][di]
        mov ds:[si],al
        inc di
        inc si
        loop g1                ;将年份从table1段移入table2段
        push si                ;将si的偏移量入栈,在处理年份后的第一组数据时恢复
        sub si,4               ;将si指向年份的第一个字符
        mov cl,01000010b
        call show_str          ;在屏幕上显示年份
        pop si                 ;恢复si
        inc si                 ;si+1。
        push dx                ;因随后的除法要用到dx,所以dx先入栈,以保护dh值
        mov ax,es:5[bx]
        mov dx,es:7[bx]
        call dtoc              ;总收入数据变为ASCII码,移入table2段
        pop dx
        mov dl,18              ;总收入显示的列地址
        mov cl,01000010b
        call show_str          ;在屏幕上显示总收入
        call w0                ;调用w0子程序,其作用是找到字符串结束的偏移地址,并将si指向下一个字符串的首地址
        push dx
        mov ax,es:10[bx]
        mov dx,0
        call dtoc
        pop dx
        mov dl,29              ;雇员人数显示的列地址
        mov cl,01000010b
        call show_str          ;在屏幕上显示雇员人数
        call w0                ;调用w0子程序
        push dx
        mov ax,es:13[bx]
        mov dx,0
        call dtoc
        pop dx
        mov dl,40              ;人均收入显示的列地址
        mov cl,01000010b
        call show_str          ;在屏幕上显示人均收入
        call w0                ;调用w0子程序
        inc dh                 ;屏幕显示指向下一行
        add bx,16              ;table1段指向下一行数据
        pop cx
        loop g0
        mov ax,4c00h
        int 21h

     w0:mov cl,ds:[si]         ;字符串首地址内的内容放入cl
        mov ch,0
        jcxz c0                ;判断cx是否为0(字符是否是“.”,即字符串是否结束),如不是si+1,判断下一个字符;如是,si+1(使table2段中字符串分开),返回主程序
        inc si
        jmp short w0
     c0:inc si
        ret
        
   dtoc:push bx
        push cx
        push dx
        push ax
        push si
        push bp           ;子程序中会使用的寄存器入栈
        mov bp,0          ;余数计算器初始化
     d0:mov cx,10         ;除10取余法,将10放入cx
        call divdw        ;调用除法溢出子程序
        push cx           ;将余数依次入栈
        inc bp            ;纪录余数的数量
        mov cx,dx         ;商高位存入cx
        jcxz d1           ;判断商高位是否为0,如是0跳到d1处执行
        jmp short d0      ;跳到d0处执行
     d1:mov cx,ax         ;商低位存入cx
        jcxz d2           ;判断商低位是否为0,如是0跳到d2处执行
        jmp short d0      ;跳到d0处执行
     d2:mov cx,bp         ;将余数的数量存入cx
     d3:pop bx            ;倒序输出余数
        add bx,30h        ;将十进制数码转换成ASCII码
        mov [si],bl       ;将余数以字节方式输入ds:si。
        inc si
        loop d3 
        mov bx,0
        mov [si],bx       ;设置ASCII码结束符,显示字符串子程序根据此符号判断字符串是否结束     
        pop bp
        pop si
        pop ax
        pop dx
        pop cx
        pop bx            ;子程序中会使用的寄存器出栈
        ret               ;ip跳到call指令的下一条指令执行

  divdw:push bx  
        push bp       ;将子程序中使用的寄存器入栈 
        mov bp,ax     ;将L存入bp中
        mov ax,dx     ;将H放入ax中
        mov dx,0      ;dx置0(即将H变为dword型)
        div cx        ;H/N(商在ax中,余数在dx中)
        mov bx,ax     ;将H/N的商放入bx中
        mov ax,bp     ;L存入ax中
        div cx        ;[rem(H/N)*65536+L]/N;L值在ax中,rem(H/N)值为H/N的余数,在dx中
        mov cx,dx     ;将[rem(H/N)*65536+L]/N的余数放入cx中
        mov dx,bx     ;将H/N的商放入高16位的dx中;结果的低16位([rem(H/N)*65536+L]/N的商)仍然在ax中
        pop bp
        pop bx        ;子程序中使用的寄存器出栈
        ret

show_str:push es
         push dx
         push cx
         push bx
         push ax
         push si          ;子程序中会使用的寄存器入栈
         mov al,dh
         mov ah,0ah
         mul ah           ;第N行的段地址偏移量(相对于第0行的基础段地址)
         add ax,0b800h    ;第N行的段地址存入ax
         mov es,ax        ;屏幕上行号的段地址存入es
         mov ah,cl        ;将颜色存入ah,因后面要用到cx
         mov bh,0
         mov bl,dl
         add bl,bl
         sub bx,2         ;将列号存入bx,因内存寻址变量只能选bx、bp、si、di四个
      s0:mov cl,[si]
         mov ch,0
         jcxz ok          ;字符串中出现0,字符处理完毕,跳到ok处
         mov al,[si]      ;将字符存入al
         mov es:[bx],ax   ;将带属性的字符在屏幕上显示
         inc si           ;字符串列变量加1,指向下个字符
         add bx,2         ;屏幕列变量指向下一个字节
         jmp short s0     ;ip跳到s0处执行指令
      ok:pop si
         pop ax
         pop bx
         pop cx
         pop dx
         pop es           ;子程序中会使用的寄存器出栈
         ret              ;ip跳到call指令的下一条指令执行

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