|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
断断续续做完,各位如果有时间的话,帮忙看下,提提建议。
assume cs:codesg
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
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'
; 以上为21个年份的字符串
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;以上为21年公司收入数据
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635
dw 8226,11542,14430,15257,17800
;以上为21年公司员工人数
dw 21 dup (0) ;预设21个人均年创收数存储区
data ends
table segment
db 21 dup (0,0,0,0,0,0,0,0) ;预设年份字符存储区,每个占8字节
db 21 dup (0,0,0,0,0,0,0,0) ;预设年收入字符存储区,每个占8字节
db 21 dup (0,0,0,0,0,0,0,0) ;预设员工数量字符存储区,每个占8字节
db 21 dup (0,0,0,0,0,0,0,0) ;预设人均年创收字符存储区,每个占8字节
table ends
;预设转为字符的数据存储区
codesg segment
start:
;step1求出人均年创收存入data预设存储区------------------start
mov ax,data
mov ds,ax
mov bx,0
mov si,84 ;被除数指针
mov di,168 ;除数指针
mov bp,210 ;结果指针
mov cx,21
s11:
mov ax,ds:[bx+si] ;被除数低16位
mov dx,ds:[bx+si+2] ;被除数高16位
div word ptr ds:[bx+di];除数,结果在ax中
mov ds:[bp],ax ;结果存入指定区域
add si,4
add di,2
add bp,2
loop s11
;step1--------------------------------------------------ends
;step2将data段数据转成字符型存入table区----------------------------------------start
;step2.1将data段中年份数据存入table区-----------------start
mov ax,table
mov es,ax
mov bx,0
mov bp,0
mov si,0
mov di,0
mov cx,21
s211:
mov dx,ds:[bx+si]
mov es:[bp+di],dx
mov dx,ds:[bx+si+2]
mov es:[bp+di+2],dx
mov word ptr es:[bp+di+4],0
mov word ptr es:[bp+di+6],0
add si,4
add di,8
loop s211
;step2.1----------------------------------------------ends
;step2.2将data段中收入数据转成字符然后存入table区-----------------start
mov si,84 ;原数据存储区基址,指针
mov bp,168 ;目标存储区基址
mov cx,21
s221:
push cx ;保护循环数
mov di,0 ;目标存储区指针
mov bx,0 ;计位器
mov ax,ds:[si]
mov dx,ds:[si+2]
s222:
inc bx
call divdw ;商在dx-ax中,余数在cx中
push cx ;余数入栈
mov cx,ax
jcxz ok221 ;若ax为0,则跳转继续判断dx是否为0
jmp short s222 ;ax不为0,即商不为0,继续求余
ok221:
mov cx,dx
jcxz ok222 ;若dx为0,则整个商为0,跳转至取出源数据各位转成字符
jmp short s222 ;dx不为0,即商不为0,继续求余
ok222:
mov cx,bx ;计位器数值作循环次数
s223:
pop ax
add al,30h
mov es:[bp+di],al
inc di
loop s223
add bp,8 ;目标区基址+8指向下一字符串首地址
add si,4 ;源数据区指针指向下一数据
pop cx
loop s221
;step2.2----------------------------------------------------------ends
;step2.3将data段中员工数量数据转成字符然后存入table区-----------------start
mov si,168 ;原数据存储区基址,指针
mov bp,336 ;目标存储区基址
mov cx,21
s231:
push cx ;保护循环数
mov di,0 ;目标存储区指针
mov bx,0 ;计位器
mov ax,ds:[si]
s232:
inc bx
call divw ;商在ax中,余数在cx中
push cx ;余数入栈
mov cx,ax
jcxz ok231 ;若ax为0,则整个商为0,跳转至取出源数据各位转成字符
jmp short s232 ;ax不为0,即商不为0,继续求余
ok231:
mov cx,bx ;计位器数值作循环次数
s233:
pop ax
add al,30h
mov es:[bp+di],al
inc di
loop s233
add bp,8 ;目标区基址+8指向下一字符串首地址
add si,2 ;源数据区指针指向下一数据
pop cx
loop s231
;step2.3--------------------------------------------------------------ends
;step2.4将data段中人均年创收数据转成字符然后存入table区---------------start
mov si,210 ;原数据存储区基址,指针
mov bp,504 ;目标存储区基址
mov cx,21
s241:
push cx ;保护循环数
mov di,0 ;目标存储区指针
mov bx,0 ;计位器
mov ax,ds:[si]
s242:
inc bx
call divw ;商在ax中,余数在cx中
push cx ;余数入栈
mov cx,ax
jcxz ok241 ;若ax为0,则整个商为0,跳转至取出源数据各位转成字符
jmp short s242 ;ax不为0,即商不为0,继续求余
ok241:
mov cx,bx ;计位器数值作循环次数
s243:
pop ax
add al,30h
mov es:[bp+di],al
inc di
loop s243
add bp,8 ;目标区基址+8指向下一字符串首地址
add si,2 ;源数据区指针指向下一数据
pop cx
loop s241
;step2.4--------------------------------------------------------------ends
;step2-------------------------------------------------------------------------ends
;step3将table区字符按格式显示在屏幕上----------------------------start
mov ax,table
mov ds,ax
mov bx,0
mov si,0
mov dl,3
mov dh,3
mov al,2
mov cx,4
s31:
push cx ;保护外循环次数
mov cx,21
s32:
call showdata
mov si,0
mov di,0 ;指针置0返回
add bx,8 ;指向同区下一串字符
inc dl ;指向显示的下一行
loop s32
mov dl,3 ;设置下一区显示的起始行
add dh,8 ;设置下一区显示的起始列
pop cx
loop s31
;step3-----------------------------------------------------------ends
mov ax,4c00H
int 21h
;----------子程序1-------------start
;name:divdw.
;function:dword型数据除以10求余运算.
;input:商高16位dx,商低16位ax,除数=10.
;return:结果为dword型数据,高16位dx,低16位ax,余数cx.
divdw:
push bx ;保护
push ax
mov ax,dx
mov dx,0
mov bx,10
div bx
mov cx,ax ;暂存商高16位保存进cx
pop ax
push cx ;商高16位入栈
div bx ;商为ax,即最终商的低16位
mov cx,dx ;余数赋给cx
pop dx ;取出商高16位
pop bx ;恢复现场
ret
;----------子程序1-------------ends
;----------子程序2-------------start
;name:divw.
;function:word型数据除以10求余运算.
;input:商ax,除数=10.
;return:结果为word型数据ax,余数cx.
divw:
push bx
push dx ;保护
push ax
mov al,ah
mov ah,0
mov dx,10
div dl
mov bl,al ;保存商高8位进bl
mov bh,ah ;保存本次余数进bh
pop ax
mov ah,bh
div dl ;商为al,即最终商的低8位
mov cx,0
mov cl,ah ;余数赋给cx
mov ah,bl ;取出商高8位
pop dx
pop bx ;恢复现场
ret
;----------子程序2-------------ends
;----------子程序3-------------start
;----------子程序3-------------start
;name:showdata
;function:将指定内存区8位字符串显示在屏幕指定位置
;input:(ds:bx+si)=字符串首地址,(es:bp+di)=显示区首地址;(dl)=起始显示行序号,(dh)=起始显示列序号,(al)=字符属性
;return:无
showdata:
push cx ;保护现场
push dx ;保护行列
push ax ;保护字符属性
mov ax,0b800h
mov es,ax
mov bp,0
mov di,0
mov al,160
mul dl
add bp,ax
add dh,dh
mov ah,0
mov al,dh
add bp,ax ;确定显示区基址
pop ax ;取出字符属性
mov cx,8
sf31:
mov ah,ds:[bx+si]
mov es:[bp+di],ah ;写入字符值
inc di
mov es:[bp+di],al ;写入字符属性
inc si
inc di
loop sf31
pop dx ;取出初始行列
pop cx ;恢复现场
ret
;----------子程序3-------------ends
;----------子程序3-------------ends
codesg ends
end start
几个注意点和感受:
1、调用divdw子程序时候,判定商为0,须高低位同时为0;
2、数据段如何预设才最合理,最省事?
3、寄存器的使用,感觉不够用,push来pop去很饶人。。
4、显示子程序提供的是只显示一串8位字符的功能;调用很方便,但在主程序中的循环和进入下循环预设条件上有些头大。
|
|