assume cs:code,ds:data,ss:stack
data segment
;years
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
; income
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;stuff count
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
data ends
stack segment
dw 8 dup (0)
stack ends
code segment
start:
call clear_screen
init:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov ax,0b80ah
mov es,ax
mov bx,0 ; data address
mov bp,0 ; screen address
call output_year
call output_income
call output_stuff
call output_avg_income
mov ax,4c00h
int 21h
; =============== output years =================
output_year:
mov cx,21
mov ah,2
call outputYear
ret
outputYear:
mov al,[bx]
mov es:[bp],ax
mov al,[bx+1]
mov es:[bp+2*1],ax
mov al,[bx+2]
mov es:[bp+2*2],ax
mov al,[bx+3]
mov es:[bp+2*3],ax
add bx,4
add bp,160 ; add a row of position
loop outputYear
ret
; ==============================================
output_avg_income:
mov di,0 ; row
mov cx,21
mov bx,84 ; skip years
mov si,168 ; skip years & income ; 21*4+21*4
call outputAvgIncome
ret
outputAvgIncome:
mov ax,[bx]
mov dx,[bx+2]
mov bp,90 ; 45 cols
push cx
push bx
call _outputAvgIncome
pop bx
pop cx
add di,160
add bx,4
add si,2
loop outputAvgIncome
ret
_outputAvgIncome:
mov cx,[si]
call divdw
call _print_num
ret
; ==============================================
output_stuff:
mov di,0 ; row
mov cx,21
call outputStuff
ret
outputStuff:
mov ax,[bx]
mov bp,60 ; 30 cols
push cx
call _outputStuff
pop cx
add di,160
add bx,2
loop outputStuff
ret
_outputStuff:
mov cx,10
div cx
add dl,30h
mov dh,2
mov es:[bp+di],dx
mov dx,0
mov cx,ax
jcxz divRet
sub bp,2
jmp short _outputStuff
; ==============================================
output_income:
mov di,0 ; row
mov cx,21
call outputIncome
ret
outputIncome:
mov ax,[bx]
mov dx,[bx+2]
mov bp,30 ; 2*4+22*2 = 15 cols
push cx
push bx
call _print_num
pop bx
pop cx
add di,160
add bx,4
loop outputIncome
ret
divRet:
ret
; ===============================================
clear_screen:
mov ax,0b800h
mov es,ax
mov ax,0
mov dx,0700h
mov cx,1760
clearScreen:
mov es:[bx],ax
add bx,2
loop clearScreen
ret
; ===============================================
divdw:
mov bx,ax
mov ax,dx
mov dx,0
div cx
xor ax,bx
xor bx,ax
xor ax,bx
div cx
xor dx,bx
xor bx,dx
xor dx,bx
mov cx,bx
ret
; ===============================================
_print_num:
;; ax=L; dx=H
mov cx,10
mov bx,ax
mov ax,dx
mov dx,0 ;; 以上三步则是 计算 H/N, 之后ax=int(H/N), dx=rem(H/N)
div cx
; 因为当前ax中存放的是 int(H/N),相当于存放的是高位的数据
; 所以下面这3个 xor 操作是将高位的值放到bx中,然后再将 L 的数据放到ax中
xor ax,bx ; 交换 ax和bx 的值
xor bx,ax ; 交换 ax和bx 的值
xor ax,bx ; 交换 ax和bx 的值
; 交换的目的其实只是为了减少空间的使用,不使用多余的内存来存储数据
div cx
; 这一步之后,存放的是 ax=(rem(H/N)*65536+L)/N 的结果
; dx=余数
; 将高位的结果放到dx中
xor dx,bx
xor bx,dx
xor dx,bx
mov cx,bx ; 将余数存入cx
mov ch,2
add cl,30h
mov es:[bp+di],cx
mov cx,0
or cx,dx
or cx,ax
jcxz divRet
sub bp,2
jmp short _print_num
; ===============================================
code ends
end start