|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 kane080824 于 2011-11-21 20:57 编辑
kcsj1.rar
(1.91 KB, 下载次数: 3)
程序运行截图
assume cs:code,ds:data,ss:varreg
data segment
db '1975','1976','1977','1978','1979','1980','1981',
'1982','1983','1984','1985','1986','1987','1988',
'1989','1990','1991','1992','1993','1994','1995' ;年份(内存起始地址:0)
dd 16,22,382,1356,2390,8000,16000,24486,
50065,97479,140417,197514,345980,590827,803530,
1183000,1843000,2759000,3753000,4649000,5937000 ;公司收入数据(内存起始地址:84)
dd 3,7,9,13,28,38,130,220,476,778,1001,1442,
2258,2793,4037,5635,8226,11542,14430,15257,17800 ;公司人员数(内存起始地址:168)
dd 21 dup(0) ;公司人均收入(内存起始地址:252)
dw 10 ;分离字符所用的除数(内存起始地址:336)
db 16 dup(0) ;ascii码暂存区(内存起始地址:338)
data ends
varreg segment
dw 32 dup(0) ;栈,用于保存参数进行主\子程序间传递
varreg ends
code segment ;程序流程是处理一个数据显示一个数据,逐行显示
start: mov ax,data
mov ds,ax ;数据段
mov ax,varreg
mov ss,ax ;栈段
mov sp,32
;外循环入口
mov si,0 ;年份\收入\员工三项数据指针
mov bp,0 ;显示换行指针
mov cx,21 ;开始进行数据处理
s0: push cx ;保存外循环(行循环)次数
mov ax,0b800h
mov es,ax ;显存段地址复位
mov ax,84[si] ;取收入低16位
mov dx,84[si+2] ;取收入高16位
div word ptr 168[si] ;取员工数并计算人均收入
mov 252[si],ax ;将人均收入写入数据
push [si+2]
push [si]
pop ds:338[0]
pop ds:338[2] ;将年份数据写入ascii码保存区
;内循环入口
mov bx,0 ;内循环不同数据间读取指针
mov cx,4 ;内循环,每一轮循环处理一行四种数据,处理一个显示一个
push cx
jmp scrn ;年份无需转换ascii码可直接显示
s: push cx ;保存内循环(列循环)次数
call str_ascii ;调用ascii码转换子程序
scrn: call show_str ;调用显示字符串子程序
add bx,84
mov ax,es
inc ax ;通过循环改变显示段地址达到逐列显示
mov es,ax
pop cx
loop s ;内循环出口
add si,4
add bp,160
pop cx
loop s0 ;外循环出口
mov ax,4c00h
int 21h ;主程序结束
str_ascii: ;ascii码转换子程序
mov ax,[bx+si]
mov dx,[bx+si+2] ;取数据作为被除数
mov cx,0
push cx ;ascii串在栈中的结束标记
;以下是X/N无溢出除法算法,使用公式
;X/N=int(H/N)*65536+[H%N*65536+L]/N
M: mov cx, ax ;保存被除数低16位L至cx
mov ax, dx ;将被除数高16位H作被除数
mov dx, 0
div word ptr ds:[336] ;H/N,N为10
push ax ;保存H/N的商
mov ax, cx ;把低16位和dx组成[H%N*65536+L]
div word ptr ds:[336] ;[H%N*65536+L]/N
mov cx, dx ;将余数给cx,即X/N的余数
pop dx ;此时的dx,ax即为X/N的商
add cx, 30h ;把过滤出的余数转成ascii码值
push cx ;ascii码值入栈
mov cx, ax ;开始校验被除数是否为0
jcxz H ;判断被除数低16位是否为0
jmp M ;如果被除数不为0,继续除余
H: mov cx,dx
mov di,0 ;ascii码内存区指针
jcxz R ;判断被除数高16位是否为0
jmp M
;以下ascii码值出栈
R: pop cx ;将栈中的ascii值逐个弹出
jcxz RE ;如果为0,表明弹完回到主程序
mov 338[di],cl ;将ascii码值写入ascii保存区
inc di
jmp R
RE: ret
show_str: mov di,0 ;显示字符串子程序
TAKE: mov cl,338[di]
mov ch,0
jcxz GB
mov al,0
mov 338[di],al ;复位ascii码内存区
mov ch,2
push di
add di,di
mov es:326[bp+di],cx ;将ascii值写入显示区,326是根据行列得出的偏移量
pop di
inc di
jmp TAKE
GB: ret
code ends
end start
|
|