效果图如下:
代码如下:写了好久,有点啰嗦
assume cs:codesg
data segment
db 'year income pnum ain',0
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
;以上是表示21年的21个字符串
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;以上是表示21年公司的总收入的21个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年公司雇员人数的21个word型数据
data ends
stack segment
db 64 dup(0)
stack ends
codesg segment
start: mov ax,data
mov ds,ax
mov bx,0
mov ax,stack
mov ss,ax
mov sp,64
;清空显示缓冲区
call clear
;先显示year,income,pnum,ain
mov dh,3
mov dl,0
call display2
;再显示年份,红色
mov cx,21
mov dh,4 ;初始行为4
s: mov dl,0 ;列归零
push cx
mov cx,4
s2:
mov al,[bx]
mov ah,02h ;字体为红色
call display1
inc bx
inc dl
loop s2
pop cx
inc dh ;行自增
loop s
;显示总收入,绿色02h
mov cx,21
mov dh,4 ;从第4行开始
s5: mov dl,7 ;每行从第7列开始
push dx
mov ax,[bx]
mov dx,[bx+2]
call dtoc1 ;将该双字变成字符串存在ds:[0]中,字符串以0为结尾
;显示
pop dx
push bx
mov bx,0
call display2
pop bx
add bx,4 ;处理下一个数值
inc dh ;显示到下一行
loop s5
;显示人数,?色??
mov cx,21
mov dh,4 ;从第4行开始
s10: mov dl,16;每行从第16列开始
push dx
mov ax,[bx]
mov dx,0
call dtoc1 ;将该双字变成字符串存在ds:[0]中,字符串以0为结尾
;显示
pop dx
push bx
mov bx,0
call display2
pop bx
add bx,2 ;处理下一个数值
inc dh ;显示到下一行
loop s10
;显示人均收入,?色??
mov cx,21
mov dh,4 ;从第4行开始
mov bx,111 ;总收入
mov bp,bx
mov bx,195 ;总人数
s11:
mov dl,23 ;每行从第23列开始
push dx
mov dx,ds:[bp+2]
mov ax,ds:[bp]
push cx
mov cx,[bx]
call divdw
pop cx
call dtoc1 ;将该双字变成字符串存在ds:[0]中,字符串以0为结尾
;显示
pop dx
push bx
mov bx,0
call display2
pop bx
add bp,4
add bx,2
inc dh ;显示到下一行
loop s11
mov ax,4c00h
int 21h
;名称:display1
;功能:将ax中的字符显示在指定位置
;参数:(ax):需要显示的字符 (dh):行 (dl):列
;返回值:无
display1: ;先保存寄存器值
push bx
push es
push cx
;操作
push ax ;先保存显示字符
mov al,dh
mov cl,160
mul cl
mov bx,ax ;bx存放偏移量
mov al,dl
mov cl,2
mul cl
add bx,ax ;bx存放偏移量
pop ax ;取出显示字符
mov cx,0b800h
mov es,cx
mov es:[bx],ax ;显示字符即可
;恢复寄存器值
pop cx
pop es
pop bx
ret
;名称:display2
;功能:显示一段以0为结尾的字符串
;参数:(bx):该字符串在ds段中的偏移地址 (dh):行 (dl):列
;返回值:无
display2: ;先保存寄存器值
push ax
push cx
;操作
s1: mov al,[bx]
mov ah,0
mov cx,ax
inc bx ;处理下一个字符
jcxz ok ;若到0再退出
mov ah,0fh
call display1 ;调用display1挨个显示
inc dl ;显示到下一列上
jmp short s1 ;没到0则处理下一个
;恢复寄存器值
ok: pop cx
pop ax
ret
;名称:clear
;功能:清空显示缓冲区
;参数:无
;返回值:无
clear: ;保存
push cx
push ax
push dx
;操作
mov dh,0 ;0行
mov cx,80
s3:
push cx
mov dl,0 ;0列
mov cx,80
s4: mov ax,0
call display1
inc dl
loop s4
pop cx
inc dh
loop s3
;还原
pop dx
pop ax
pop cx
ret
;名称:dtoc1
;功能:将dx:ax中的dword型数据转换为字符串形式存放在ds:[0]中,以0为结束符
;参数:(dx):双字高位 (ax):双字低位
;返回值:无
dtoc1: ;保存
push cx
push bx
;操作
mov bx,32
push bx ;放一个空格进去,匹配到32则说明中止
mov bx,0
s7: mov cx,10
call divdw
;cx加30h入栈
add cx,30h
push cx ;余数入栈
;先判断dx是否为0
mov cx,dx
jcxz s8
jmp short s7
;再判断ax是否为0
s8: mov cx,ax
jcxz ok1
jmp short s7
;还原
ok1:;余数挨个出栈,写入ds:0中
s9: pop cx
sub cx,32
jcxz ok2
;判断完后加回32
add cx,32
mov [bx],cl
inc bx
jmp short s9
ok2:;末尾加0
mov cl,0
mov [bx],cl
pop bx
pop cx
ret
;名称:divdw
;功能:实现双字除以字且不溢出
;参数:(dx):双字高位 (ax):双字低位 (cx):除数
;返回值:(dx):商高位 (ax):商低位 (cx):余数
divdw: ;保存
push bx
;操作
push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax ;此时bx存放高位商
pop ax
div cx
mov cx,dx ;余数挪到cx
mov dx,bx
;还原
pop bx
ret
codesg ends
end start