assume cs:codesg
stacksg segment
dw 16 dup( 0 )
stacksg ends
datasg 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个字符串
dd 16,22 ,382,1356,2390,8000,16000,24286,50065,97479,140417,197514
dd 345980,590827 ,803530,1183000,1843000,2759000,3753000,4649000,5937000
; 以上是表示21年公司总收入的21个dword型数据
dw 3,7 ,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430 ,15257,17800
; 以上是表示21年公司雇员人数的21个word型数据
datasg ends
datasg2 segment
db 32 dup ( 0 )
datasg2 ends
codesg segment
start:
mov ax,datasg ; 原始数据
mov es,ax
mov di,0
mov ax,stacksg ; 初始化栈
mov ss,ax
mov sp,32
mov ax,datasg2 ; 显示字符
mov ds,ax
mov si,0
mov bl,5 ; 设置行号
mov cx,21 ; 循环次数
s: push cx
mov ax,es:[ di] ; 低2个字节
mov [ si] ,ax
mov ax,es:[ di+2] ; 高2个字节
mov [ si+2] ,ax
mov word ptr [ si+4] ,0 ; 设置0结尾
mov dh,bl
mov dl,3
mov cl,2
call show_str
; 4 个字节年份
mov ax,es:[ di+84] ; 低2个字节
mov dx,es:[ di+86] ; 高2个字节
call dtoc
mov dh,bl
mov dl,23
mov cl,4
call show_str
; 4 个字节收入
mov ax,es:[ si+168]
mov dx,0
call dtoc
mov dh,bl
mov dl,43
mov cl,8
call show_str
; 2 个字节雇员数
mov ax,es:[ di+84] ; 低16位
mov dx,es:[ di+86] ; 高16位
; 被除数
div word ptr es:[ si+168]
; 除数
; 结果商存在ax中
mov dx,0
call dtoc
mov dh,bl
mov dl,63
mov cl,2
call show_str
; 2 字节人均收入
add di,4
add si,2
inc bl
pop cx
loop s
mov ax,4c00h
int 21h
; 名称:dtoc
; 功能:将word型数据转变为表示十进制的字符串,字符串以0结尾符
; 参数:( ax) = dword型数据的低16位,( dx) = dword型数据的高16位
; ds:si指向字符串的首地址
; 返回:无
dtoc: push ax
push bx
push cx
push dx
push si
push ds
mov bx,0 ; 用计数
dtoc_s: mov cx,10
call divdw
; 返回:( dx) = 结果的高16位,( ax) = 结果的低16位
; ( cx) = 余数
add cx,30h ; 转换为对于的ascii码
push cx ; 余数入栈
inc bx
mov cx,dx ; 判断结果的高16位是否为0
jcxz dtoc_s0
jmp short dtoc_s ; 不为零继续进行除法运算
dtoc_s0:mov cx,ax ; 判断结果的低16位是否为0
jcxz dtoc_s1
jmp short dtoc_s ; 不为零继续进行除法运算
dtoc_s1: mov cx,bx
dtoc_s2:
pop ax
mov [ si] ,al
inc si
loop dtoc_s2
mov ax,0
mov [ si] ,ax ; 最后加个0作为结尾
pop ds
pop si
pop dx
pop cx
pop bx
pop ax
ret
; 名称:show_str
; 功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串
; 参数:( dh) = 行号(取值范围1~25),( dl) = 列号(取值范围1-80),
; ( cl) = 颜色,ds:si指向字符串的首地址
; 返回:无
show_str: push ax
push bx
push cx
push dx
push es
push di
push ds
push si
mov ax,0b800h
mov es,ax
sub dh,1
mov al,dh
mov ah,160
mul ah
mov bx,ax ; bx = (( dh) -1) *160
sub dl,1
mov al,dl
mov ah,2
mul ah
add bx,ax ; bx = (( dh) -1) *160+(( dl) -1) *2
mov di,bx ; 计算出的显示的位置
mov al,cl ; al = cl 要设置显示的颜色
show_str_s: mov cl,[ si]
mov ch,0
jcxz show_str_ok ; 判断读取的字符是否为0,等于0结束,不等于0显示当前字符
mov ah,[ si]
mov es:[ bx] ,ah ; 设置显示的字符
mov es:[ bx+1] ,al ; 设置显示的颜色
inc si ; 读取下一个字符
add bx,2 ; 指向下一个字符显示的位置
jmp short show_str_s
show_str_ok:
pop si
pop ds
pop di
pop es
pop dx
pop cx
pop bx
pop ax
ret
; 名称:divdw
; 功能:进行不会产生溢出的出发运算,被除数为dword型,除数为word型,结果为dword
; 参数:( ax) = dword型数据的低16位
; ( dx) = dword型数据的高16位
; ( cx) = 除数
; 返回:( dx) = 结果的高16位,( ax) = 结果的低16位
; ( cx) = 余数
divdw: push bx
mov bx,ax ; bx = L
mov ax,dx ; ax = H
mov dx,0 ; dx = 0 作为高16位
div cx
push ax ; int( H/N) *65536入栈
mov ax,bx ; ax = L
; dx 余数作为高16位
div cx
mov cx,dx ; 余数
pop dx ; 结果的高16位
pop bx
ret
codesg ends
end start