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'
;以上是表示21年的21个字符串,最大位置在54h
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个数据,最大位置在a8h
dw 3,7,9,13,28,38,130,220,479,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;以上是表示21年公司雇员人数的21个数据,最大的位置在d2h,地址结束位置为e0h
data ends
shows segment
db 32 dup(0)
shows ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
code segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov si,0
mov di,0
mov cx,21
call year_copy
call get_copy
call mana_copy
call aver_copy
call show
mov ax,4c00h
int 21h
year_copy: mov bx,0 ;控制复制后的每行第一个字符位置
call time
call copy4db
ret
get_copy: mov bx,5
call time
call copy4db
ret
mana_copy: mov bx,10
call time
call copy2db
ret
aver_copy: mov bx,5
call time
call avers
ret
show: mov ax,table
mov ds,ax
mov ax,0b800h
mov es,ax
mov si,0 ;目标数据的地址
mov di,0 ;目的数据的地址
mov dx,7 ;字的属性
call show_year
call show_get
call show_mana
call show_aver
ret
copy4db: mov di,0 ;四字节的复制
mov ax,[si]
mov es:[bx+di],ax
add si,2
add di,2
mov ax,[si]
mov es:[bx+di],ax
add si,2
add bx,16
loop copy4db
ret
copy2db: mov di,0 ;双字节的复制
mov ax,[si]
mov es:[bx+di],ax
add si,2
add bx,16
loop copy2db
ret
avers: push cx
mov ax,es:[bx+2]
mov si,es:[bx+5]
mov dx,0
div si
mov cx,ax
mov ax,es:[bx]
div si
add ax,cx
mov dx,0
mov es:[bx+8],ax
add bx,16
pop cx
loop avers
ret
show_year: call time ;显示年份
year_s0: push cx
mov cx,4
year_s: mov al,[si] ;一个字符复制
mov es:[di],al
inc di
mov es:[di],dl
inc si
inc di
loop year_s
add si,12
add di,98h
pop cx
loop year_s0
jmp ok
show_get: mov bx,5 ;显示总收入,bx为table段中需要处理的数据的位置
mov si,2 ;si寄存器中存放需要处理的数据中最高位的偏移地址
mov di,12 ;di寄存器赋值用于后续转换时的除数但在这里我们对其表示为后期需要显示的列数位置
call time
call take
ret
show_mana: mov bx,10
mov si,0
mov di,22
call time
call take
ret
show_aver: mov bx,13
mov si,0
mov di,32
call time
call take
ret
take: push cx
mov dx,0
mov bp,0 ;bp寄存器是栈寄存器但是现在我将其用于计数
push di
push bx
call hchanged
pop bx
pop di
add bx,16
add di,50h
pop cx
loop take
jmp ok
hchanged: mov cx,si ;利用si是否为0判断是否有高位数据需要处理
mov ax,[bx+si]
jcxz hchangedl
sub si,2
mov cx,[bx+si]
add si,2
jmp hchangedh
hchangedh:
push di
mov di,10
div di
pop di
push ax
mov ax,cx
push di
mov di,10
div di
pop di
mov cx,dx
pop dx
push cx ;余数入栈
mov cx,ax
mov ax,dx
mov dx,0
inc bp
jcxz popshow
jmp hchangedh
change: sub si,2
jmp hchanged
hchangedl: ;低位十六进制转换为十进制的计算
push di
mov di,10
div di
pop di
push dx
mov dx,0
mov cx,ax
inc bp
jcxz popshow
jmp hchangedl
popshow:
add di,di ;数据直接从栈中弹入显存,将列数转化为在显存中的偏移地址数
popr: pop es:[di]
push ax
mov ax,30h
add es:[di],ax
mov al,7
mov es:[di+1],al
pop ax
add di,2
dec bp
mov cx,bp
jcxz ok1
jmp popr
ok1: mov ax,di
mov di,2
div di
mov di,ax
ret
ok0: mov ax,di
mov di,2
div di
mov di,ax
jmp change
ok: ret
time: mov cx,21
ret
code ends
end start