缓存页
assume cs:code, ds:data, ss:stack
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985'
db '1986','1987','1988','1989','1990','1991','1992','1993','1994','1995'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514,345980
dd 590827,803530,1183000,1843000,2758000,3753000,4649000,5937000
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
number segment
db 1024 dup(0)
number ends
stack segment stack ;!!!事实证明,后面这个stack加上可以自动赋值sp,不加默认sp从0开始
db 1024 dup(0)
stack ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 1024 ;养成习惯,数据段及时初始化
call clear_screen
call show_year
call show_summ
call show_ne
call show_av
mov ax, 4c00h
int 21h
;=================Function=================
;==================================
show_year:
;输入:年份数据段
;将内容输出到屏幕
push ax
push cx
push dx
push si
push di
mov si, 500 ;指定位置
mov di, 0
mov cx, 21
total_year:
mov ax, ds:[di]
mov dx, ds:[di+2]
call str_store
call show_str
add di, 4
add si, 160
loop total_year
pop di
pop si
pop dx
pop cx
pop ax
ret
;==================================
show_summ:
;输入总收入字段
;输出数据到屏幕
push ax
push cx
push si
push di
mov si, 530
mov di, 0
mov cx, 21
total_summ:
mov ax, ds:[84+di]
mov dx, ds:[84+di+2]
call dtoc_pro
call show_str
add di, 4
;sub si, 0 ;这里不需要减去偏移量,因为都是从0开始
add si, 160
loop total_summ
pop di
pop si
pop cx
pop ax
ret
;==================================
show_ne:
;输入人数字段
;输出数据到屏幕
push ax
push cx
push si
push di
mov si, 570
mov di, 0
mov cx, 21
total_ne:
mov ax, ds:[168+di]
call dtoc
call show_str
add di, 2
;sub si, 0 ;这里不需要减去偏移量,因为都是从0开始
add si, 160
loop total_ne
pop di
pop si
pop cx
pop ax
ret
;==================================
show_av:
;输入数据段:总收入和人数
;输出平均值(取整)
push ax
push bx
push cx
push dx
push di
push si
mov si, 610
mov bx, 0
mov di, 0
mov cx, 21
total_av:
push cx
mov ax, ds:[84+bx]
mov dx, ds:[84+bx+2]
add bx, 4
mov cx, ds:[168+di]
add di, 2
call div_dw
call dtoc_pro
call show_str
add si, 160
pop cx
loop total_av
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret
;==================================
div_dw:
;(输入):ax低16位,dx高16位,cx为16位除数
;(输出):dx结果高16位,ax结果低16位,cx为余数
push bx
mov bx, ax ;暂存ax,低位
mov ax, dx ;设置被除数
mov dx, 0 ;高位置为0
div cx ;高16作除法,余数dx并到低16位,这里无需改动,dx也是除法的高位
push ax ;暂存高16位除法结果中的商
mov ax, bx
div cx ;低16位除法,结果,ax为商,dx为余数
mov cx, dx
pop dx ;将暂存的高位ax,置于dx
pop bx
ret
;==================================
dtoc_pro:
;输入ax低16,dx高16
;内容输出到number字段
;注意,检测商为0才跳出
push bx
push cx
push si
push ds
mov si, 0 ;记录次数
mov bx, number
mov ds, bx ;目标地址
in_num_pro:
mov cx, 10 ;除数10
call div_dw ;返回余数cx
push cx ;保存余数
inc si
push cx
mov cx, ax ;判断商为0
or cx, 0
or cx, dx
jcxz in_num_pro_exit ;商为0,跳转,开始存入number字段
pop cx
jmp in_num_pro
in_num_pro_exit:
pop bx ;!!!!!!!!!!!注意多余的push要及时出栈,影响数据排布!!!!
mov cx, si
mov si, 0
mov bx, 0
set_num_pro:
pop bx ;写入目标地址操作
add bx, 30h
mov ds:[si], bl
inc si
loop set_num_pro
mov byte ptr ds:[si], 0 ;末尾添0,表示字符串结束
pop ds
pop si
pop cx
pop bx
ret
;==================================
dtoc:
;X输入ax,(16位)
;结果保存在number字段
;注意,检测商为0才跳出!!
push bx
push cx
push dx
push ds
push si
mov bx, number
mov ds, bx ;目标地址
mov si, 0 ;偏移指针,个数
mov bx, 10 ;除数
mov dx, 0 ;32位除法,但这里只有ax参与,dx得置0
in_num:
div bx
push dx
inc si
mov cx, ax ;这里没有loop循环,cx可放心使用
jcxz in_num_exit
mov dx, 0
jmp in_num
in_num_exit:
mov cx, si
mov si, 0
mov bx, 0
set_num:
pop bx
add bx, 30h
mov ds:[si], bl
inc si
loop set_num
mov byte ptr ds:[si], 0 ;末尾添0,表示字符串结束
pop si
pop ds
pop dx
pop cx
pop bx
ret
;==================================
str_store:
;输入;字码,ax低16,dx高16
;输出:number字段
push ds
mov bx, number
mov ds, bx
mov ds:[0], ax
mov ds:[2], dx
mov byte ptr ds:[4], 0 ;结束符号
pop ds
ret
;==================================
show_str:
;X参数cx输入字节
;直接输出number字段中的数值
push ax
push bx ;这里有bl暂存颜色
push cx ;cl暂存字符,这俩都不能删
push es
push ds
push si
push di
mov ax, number
mov ds, ax
;mov si, 1500 ;指定位置
mov di, 0 ;字符串起始位置
mov bl, 00000010B ;指定颜色
mov ax, 0b800h
mov es, ax ;输出位置
mov ch, 0
forward:
mov cl, ds:[di]
jcxz exit
mov es:[si], cl
mov es:[si+1], bl
add si, 2
inc di
jmp forward
exit:
pop di
pop si
pop ds
pop es
pop cx
pop bx
pop ax
ret
;==================================
clear_screen:
;无输入
;执行清屏操作
push bx
push cx
push es
push si
mov bx, 0b800h
mov es, bx
mov cx, 4096
mov si, 0
swap: mov byte ptr es:[si], 0
inc si
loop swap
pop si
pop es
pop cx
pop bx
ret
;==================================
code ends
end start