assume cs:code
data segment
;首先:将原始数据写入内存
db '1975','1976','1977','1978','1979','1980','1981','1982'
db '1983','1984','1985','1986','1987','1988','1989','1990'
db '1991','1992','1993','1994','1995'
;--------21个年份字符串
dd 16,22,382,1356,2390,8000,16000,24486
dd 50065,97479,140417,197514,345980,590287,803530,1183000
dd 1843000,2759000,3753000,4649000,5937000
;--------21个公司总收入
dw 3,7,9,13,28,38,130,220
dw 476,778,1001,1442,2258,2793,4037,5635
dw 8226,11542,14430,15257,17800
;--------21个公司雇员人数
data ends
table segment
;其次:定义整体内存空间,最终将所有结果转写入此段
db 21 dup ('year summ ne ?? ') ;每条为1年的信息
table ends
ascii segment
db 840 dup (' ')
db 8 dup (0)
ascii ends
stack segment
dw 16 dup(0) ;32B
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,32
mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0
mov si,0
mov di,0
;将内存中的数据及计算出的数据写入table段中
mov cx,21
totable:
push cx ;非常重要
mov ax,ds:[bx]
mov es:[di],ax
mov ax,ds:[bx+2]
mov es:[di+2],ax
mov ax,ds:[84+bx]
mov es:[di+5],ax
mov ax,ds:[84+bx+2]
mov es:[di+5+2],ax
mov ax,ds:[168+si]
mov es:[di+0ah],ax
mov dx,es:[di+5+2]
mov ax,es:[di+5]
mov cx,es:[di+0ah]
call divdw
mov es:[di+0dh],ax ;此处丢弃了dx(商的高位),只取了ax,因原table中直给出了2B空间存储人均收入
add bx,4
add si,2
add di,16
pop cx
loop totable ;存储完毕跳转
;将table段中数据转换为ASCII码,存入ascii段中
;存储方式:年份10B_[0]开始,收入10B_[10]开始,雇员数10B_[20]开始,人均收入10B_[30]开始
;占用空间40*21=840B,无数据处为空格
mov ax,table
mov ds,ax
mov ax,ascii
mov es,ax
mov si,0
mov di,0
mov cx,21
toascii:
push cx
;年份传递------->>>>>>>>
mov ax,ds:[si]
mov es:[di],ax
mov ax,ds:[si+2]
mov es:[di+2],ax
;收入传递------->>>>>>>>
mov dx,ds:[si+7]
mov ax,ds:[si+5]
mov bx,0 ;计算余数cx的推入次数
dtocloop_sr:
mov cx,10
call divdw ;返回值:dx给出商的的高位,ax给出商的低位,cx余数
push cx
inc bx
mov cx,dx
add cx,ax
jcxz xr_ok
jmp short dtocloop_sr
xr_ok: mov cx,bx
mov bp,0
qz_sr:
pop ax
add ax,30h
mov byte ptr es:[di+10+bp],al
inc bp
loop qz_sr
;雇员数传递------->>>>>>>>
mov dx,0
mov ax,ds:[si+0ah]
mov bx,0 ;计算余数cx的推入次数
dtocloop_gys:
mov cx,10
call divdw ;返回值:dx给出商的的高位,ax给出商的低位,cx余数
push cx
inc bx
mov cx,dx
add cx,ax
jcxz gys_ok
jmp dtocloop_gys
gys_ok: mov cx,bx
mov bp,0
qz_gys:
pop ax
add ax,30h
mov byte ptr es:[di+20+bp],al
inc bp
loop qz_gys
;人均收入传递-------->>>>>>>>
mov dx,0
mov ax,ds:[si+0dh]
mov bx,0 ;计算余数cx的推入次数
dtocloop_rjsr:
mov cx,10
call divdw ;返回值:dx给出商的的高位,ax给出商的低位,cx余数
push cx
inc bx
mov cx,dx
add cx,ax
jcxz rjsr_ok
jmp short dtocloop_rjsr
rjsr_ok:
mov cx,bx
mov bp,0
qz_rjsr:
pop ax
add ax,30h
mov byte ptr es:[di+30+bp],al
inc bp
loop qz_rjsr
mov ax,0
mov es:[di+30+8],ax ;最后两字节设置00为断点
add si,16
add di,40
pop cx ;此处无法使用loop,借用跳转命令
dec cx
jcxz toascii_ok
jmp near ptr toascii
;调用“显示”子程序,给定初始化值
toascii_ok:
mov dh,3 ;给定显示的位置及颜色要求:8行3列、绿色
mov dl,3
mov cl,2
mov ax,ascii
mov ds,ax
mov bx,0
mov cx,21
show21: push cx
mov cl,2
call show_str
add bx,40
inc dh
pop cx
loop show21
mov ax,4c00h
int 21h
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
show_str:
;参数:行=dh,列=dl,颜色值=cl,bx为设置循环使用
;返回值:将内存中的ASCII码内容显示出来
;此子程序要求给定值在相应的寄存器中:行=dh,列=dl,颜色值=cl
;此程序要求栈段的长度为32B
;要调用此子程序,须ASCII码内容在ds段中
;遇到字节00,停止显示
push ds
push es
push si
push di
push ax
push bx
push cx
push dx
;求目标地址
mov ax,0b800h
mov es,ax
mov si,0
mov di,0
mov ax,0
mov al,160
dec dh ;从0行开始计数
add dh,2 ;显存从第3行开始显示
mul dh
add di,ax
mov ax,0
mov al,2 ;每个要显示的字符占用2B
dec dl ;列值-1,第一列转变为第0列
mul dl
add di,ax ;求得显示的起始位置di
mov ah,cl ;颜色值入ah
mov cx,0 ;清空cx的值
;向目标地址写入数据
show_str_s:
mov cl,ds:[bx+si] ;判断0,退出显示
jcxz show_str_ok
mov al,ds:[bx+si]
mov es:[di],al
mov es:[di+1],ah
inc si
add di,2
jmp show_str_s
show_str_ok:
pop dx
pop cx
pop bx
pop ax
pop di
pop si
pop es
pop ds
ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
divdw:
;此子程序的作用为防止被除数位32位时,商的溢出
;参数:dx给出32位被除数的高位,ax给出32位被除数的低位,cx除数
;返回值:dx给出商的的高位,ax给出商的低位,cx余数
push si
mov si,ax
mov ax,dx
mov dx,0
div cx
push ax
mov ax,si
div cx
mov cx,dx
pop dx
pop si
ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
dtoc:
;参数:ax给出被除数
;返回值:转换结果存在ds:[si]中,逆序存放
;此子程序要求给定16位被除数在寄存器ax中,除数为8位=10
;此程序要求栈段的长度为32B
push ax
push bx
push cx
push dx
push si
mov dx,10 ;设定除数
mov bx,ax
dtoc_2bdiv1b_s:
mov ah,0
mov al,bh
div dl
mov ch,al
mov al,bl
div dl
mov cl,al
add ah,30h
mov ds:[si],ah ;余数写入内存ds:[si]中
jcxz dtoc_2bdiv1b_ok
inc si
mov bx,cx
jmp dtoc_2bdiv1b_s
dtoc_2bdiv1b_ok:
pop si
pop dx
pop cx
pop bx
pop ax
ret
code ends
end start