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' ;0-83
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,19514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000 ;84-167
dw 3,7,9,13,28,38,130,220,476,778,1001,1142,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800 ;168-210
db 14 dup(0) ;211-223
dd 120 dup(0) ;224-480(224,14行开头)
data ends
stack segment
dw 16 dup(0)
stack ends
code segment
start: MOV AX,stack
MOV SS,AX
MOV SP,32
MOV AX,data
MOV DS,AX
mov word ptr ds:[220],168
mov bx,84
mov si,0
mov di,168 ;指向人数
mov bp,288
mov cx,21
z1: push cx
call movn ;年份移到指定位置
call shoru ;总收入改成SACII码移到指定位置
call men ;人数改成SACII码移到指定位置
call pjsr ;平均收入改成SACII码移到指定位置
pop cx
loop z1
call show_str ;显示
MOV AX,4C00H
INT 21H
movn:
mov cx,4
w2: mov al,[si]
inc si
mov ds:[bp],al
inc bp
loop w2
mov byte ptr ds:[bp],0
inc bp
ret
shoru:
mov ax,[bx] ;读数据(收入)
add bx,2
mov dx,[bx]
add bx,2 ;si 指向下一个数据
push ax
push dx
mov cx,[di]
add di,2
call divdw ;这次为求平均数
mov ds:[211],ax ;平均收入低16位
mov ds:[213],dx ;平均收入高16位
pop dx
pop ax
call sjbw ; 分解各位
ret
sjbw:
mov word ptr ds:[215],0 ;暂存被除数低16位
mov word ptr ds:[217],0 ;用来记录cx(数据的长度)
s0: mov cx,10
call divdw ;这次目的是分解 年的总收入
mov ds:[215],ax ;保护被除数低16位
push cx ; 余数入栈(从低位到高位顺序入栈)
mov ax,ds:[217] ;这个内存单元用来记录入栈次数即数值长度
inc ax
mov ds:[217],ax
mov ax,ds:[215]
push dx
or cx,dx
or cx,ax ;商(高低16位全部为零)并且余数同时为零,即此数据被分解完毕
pop dx
inc cx ;当cx为零时,用于退出循环
loop s0 ;余数为零,代表这个数已经按从低到高入栈完毕
mov cx,ds:[217] ;数值长度给cx用于循环次数
pop ax ;数据个个位倒序出栈
dec cx ;每串数都以零开头,所以第一个数(0)不加30h,同时cx减少一次循环
s1: pop ax
add al,30h ;每位改成ASICII码
mov ds:[bp],al
inc bp
loop s1
mov byte ptr ds:[bp],0 ; 因为每组数字都以零开头,补个零结尾,这样要显示的数字实际开始位置为,ds:[32]
inc bp
ret
divdw:
push bx
push ax
mov ax,dx
mov dx,0
div cx ;高16位作除法
mov bx,ax ;ax高16位的商,dx余数
pop ax
div cx ;低16位作除法
mov cx,dx
mov dx,bx
pop bx
ret
men : push di
mov di,ds:[220]
mov ax,[di]
add di,2
mov dx,0
call sjbw
mov ds:[220],di
pop di
ret
pjsr: mov ax,ds:[211]
mov dx,ds:[213]
call sjbw
ret
show_str: mov ax,0b800h ;显示字符串
mov es,ax
mov ax,0
mov al,3 ;显示位置,第九行
mov cl,10 ; 第三例
mov bx,0
mov bl,160
mul bl
mov bx,0
add bx,ax
mov ax,0
mov al,2
mul cl
add bx,ax ;bx为首字偏移值
mov ch,2 ; 颜色为绿色
mov al,ch ;颜色放al中保存
mov di,0
mov si,288
mov cx,21
x2: push cx
call show_str11
add bx,160
mov di,0
pop cx
loop x2
ret
show_str11: mov cx,4
x5: push di
x3: push cx
mov cl,[si]
mov ch,0
jcxz x4 ;cx为零时 跳到s1
mov es:[bx+di],cl
mov es:[bx+di+1],al
inc si
add di,2
pop cx
jmp short x3
x4: pop cx
pop di
inc si
add di,28 ;显示二个数字之间加个空格,di必须为2的倍数
loop x5
ret
code ends
end start
用了一个白天的时间,大多数时间,在纠结几个基本的错误,比如2个小时,纠结 data 段设得小了,自己全然不知,导致错误,等