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