|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 jeset 于 2013-4-16 17:02 编辑
作者:jeset
程序自己编写的,如果有什么可以优化的地方请各位同学前辈指出!
- 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'
- ;定义年份完成,byte类型
- dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
- dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
- ;定义收入完成,dword类型
- dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
- dw 11542,14430,15257,17800
- ;定义21年雇佣人数
- data ends
- stack segment
- db 1000 dup (0)
- stack ends
- code segment
- ;**************************************************
- ;程序开始
- ;**************************************************
- start:
- ;***************************************************
- ;初始化段结束
- ;***************************************************
- mov ax,data
- mov ds,ax
- mov ax,stack
- mov ss,ax
- mov sp,1000
- mov ax,0b800h ;把显存地址给es
- mov es,ax
- ;***************************************************
- ;初始化段开始
- ;***************************************************
- ;****************************************************
- ;年份写入显存段开始
- ;****************************************************
- mov cx,21 ;设置循环次数
- mov bx,280H ;设置显存行
- mov si,0 ;设置源地址
- mov di,2 ;设置显存列
- nf:
- mov word ptr ax,ds:[si] ;把源地址给ax 一次性操作一个字,并把19分为:al=1 ah=7,因为一个ascii码占一个内存单元
- mov byte ptr es:[bx+di],al ;把al低位也就是1给显存的低位
- mov byte ptr es:[bx+di+1],02H ;把低位的显存属性设置为02H
- mov byte ptr es:[bx+di+2],ah ;把ah高位也就是9给显存的高位
- mov byte ptr es:[bx+di+3],02H ;把高位的显存属性设置为02H
-
- mov word ptr ax,ds:[si+2] ;把源地址给ax 一次性操作一个字,并把75分为:al=7 ah=5,因为一个ascii码占一个内存单元
- mov byte ptr es:[bx+di+4],al ;把al低位也就是7给显存的低位
- mov byte ptr es:[bx+di+5],02H ;把低位的显存属性设置为02H
- mov byte ptr es:[bx+di+6],ah ;把ah高位也就是5给显存的高位
- mov byte ptr es:[bx+di+7],02H ;把高位的显存属性设置为02H
- add si,4 ;源地址+4
- add bx,160 ;行号加一行
- loop nf
- ;****************************************************
- ;年份写入显存段结束
- ;****************************************************
- ;****************************************************
- ;收入写入显存段开始
- ;****************************************************
- mov cx,21 ;设置循环次数
- mov bx,280H ;设置显存行
- mov di,30 ;设置显存列
- mov si,0 ;设置源地址
- sr:
- mov ax,ds:[si+84] ;把低位被除数给ax
- mov dx,ds:[si+84+2] ;把高位被除数给dx
- call dtoc ;调用转换程序
- add si,4 ;源地址+4,因为收入是dword型数据
- add bx,160 ;指向下一行
- mov di,30 ;至di为下一行的收入列
- loop sr
- ;*****************************************************
- ;收入写入显存段结束
- ;*****************************************************
- ;*****************************************************
- ;人数写入显存段开始
- ;*****************************************************
- mov cx,21 ;设置循环次数
- mov bx,280H ;设置显存行
- mov di,60 ;设置显存列
- mov si,0 ;设置源地址
- rs:
- mov ax,ds:[si+168] ;把人数赋值给ax
- mov dx,0 ;因为人数为word型所以高位dx至零
- call dtoc ;调用转换程序
- add si,2 ;源地址+2,因为人数为word型数据
- add bx,160 ;指向下一行显存地址
- mov di,60 ;指向下一行显存地址的人数列
- loop rs
- ;*****************************************************
- ;人数写入显存段结束
- ;*****************************************************
- ;*****************************************************
- ;人均写入显存段开始
- ;*****************************************************
- mov cx,21 ;设置循环次数
- mov bx,280H ;设置显存行
- mov di,90 ;设置显存列
- mov si,0 ;设置源地址
- mov bp,0 ;设置bp为零,两个用处,一个用处为除数调用偏移地址,一个作为除数
- rj:
- push bp ;保存偏移地址bp
- mov ax,ds:[si+84] ;收入为dword型,所以低位给ax
- mov dx,ds:[si+84+2] ;收入为dword型,所以高位给dx
- mov bp,ds:[bp+168] ;把偏移地址bp+168地址的人数赋值给bp
- call divdw ;调用防除法溢出程序进行除法
- call dtoc ;调用转换程序
- pop bp ;恢复偏移地址bp
- add si,4 ;源地址+4
- add bp,2 ;偏移地址bp+4
- add bx,160 ;指向显存下一行
- mov di,90 ;指向显存下一行人均列
- loop rj
- ;****************************************************
- ;人均写入显存段结束
- ;****************************************************
- mov ax,4c00h ;设置中断
- int 21h ;中断程序结束并返回
- ;****************************************************
- ;程序结束
- ;****************************************************
- ;****************************************************
- ;divdw除法防溢出计算
- ;****************************************************
- divdw:
- push bx ;保存要用到的寄存器bx
- push ax ;保存低位被除数
- mov ax,dx ;把高位被除数赋值给低位ax
- mov dx,0 ;把高位被除数至零
- div bp ;除以除数,得到高位的商=ax,高位的余数=dx
- mov bx,ax ;把高位的商存放在bx中
- pop ax ;把低位被除数从栈中弹出到ax,此时dx=高位被除数的余数,ax=低位被除数
- div bp ;除以除数,dx=余数,ax=商
- mov dx,bx ;把bx高位数商给dx
- pop bx ;弹出保存的寄存器bx
- ret ;返回
- ;****************************************************
- ;divdw除法防溢出计算
- ;****************************************************
-
- ;****************************************************
- ;dtoc转换写入显存程序
- ;****************************************************
- dtoc:
- push bp ;人均运算用到的寄存器
- push cx ;循环次数进栈
- mov cx,0
- push cx ;cx=0进栈,用于检测pop弹出是否完毕
- dtoc1:
- push ax ;低位被除数进栈
- mov ax,dx ;把高位被除数赋值给ax
- mov dx,0 ;高位置零
- mov cx,10 ;除数=10
- div cx ;得到高位的商=ax,以及高位余=dx
- mov bp,ax ;把高位商存放在bp
- pop ax ;把低位被除数从栈中恢复
- div cx ;除以除数
- add dl,30H ;把余数dx中+30H,因为被除数的余数肯定小于除数,所以我直接操作8位寄存器
- push dx ;把转换过后的数压栈
- mov dx,bp ;把高位被除数的商恢复给dx
- mov cx,ax ;把ax商赋值给cx用于检测是否为零
- jcxz dtoc2 ;cx为零则跳转,不为零向下继续执行
- jmp short dtoc1
- dtoc2:
- pop cx ;从栈中弹出转换过后的ascii数值,一直弹出直到程序开头压栈的cx=0
- jcxz dtocok ;检测cx是否为零,不为零进行向下执行,为零则跳转
- mov es:[bx+di],cl ;因为余数小于除数,所以cx里面只有cl有数值,把转换过后的ascii数值付给显存
- mov byte ptr es:[bx+di+1],02H ;在后面设置每个要显示的属性
- add di,2 ;显存列+2
- jmp short dtoc2
-
- dtocok:
- pop cx ;恢复寄存器
- pop bp ;恢复寄存器
- ret ;返回程序
- ;****************************************************
- ;dtoc转换写入显存程序
- ;****************************************************
- code ends
- end start
复制代码
|
|