鱼C论坛

 找回密码
 立即注册
查看: 1925|回复: 4

[技术交流] [jeset]课程设计1简介版完整程序解释

[复制链接]
发表于 2013-4-16 17:01:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-4-16 17:54:03 | 显示全部楼层
强烈支持楼主ing……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-4-16 18:45:28 | 显示全部楼层
真是难得给力的帖子啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2013-4-17 14:30:05 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2013-4-17 14:30:54 | 显示全部楼层
Win32 发表于 2013-4-16 18:45
真是难得给力的帖子啊。

谢谢朋友支持!!!!!!!!!!!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-7 22:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表