[2011-06-03 17:27] 10章课程设计
assume cs:codesg
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'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
data ends
table segment
db 150h dup (0)
table ends
stack segment
db 0ffffh dup (0)
stack ends
codesg segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov ax,stack
mov ss,ax
mov sp,0h
sub bx,bx
mov cx,21
xh: push cx ;压栈cx
mov cx,2 ;初始化内循环 cx=2
sub si,si ;初始化内循环 si=0
mov di,ss:[0] ;将ss:[0]中的数据送入di
s: mov ax,ds:[di] ;将ds:[di]中的数据送入ax
mov es:[bx+si],ax ;将ax中的数据送入 es:[bx+si]
mov ax,ds:[di+84] ;将ds:[di+84]中的数据送入ax
push ax ;压栈 ax
mov es:[bx+si+5],ax ;将ax中的数据送入es:[bx+si+5]
add di,2 ;di=di+2
add si,2 ;si=di+2
loop s ;cx=cx-1 cx不等于0 跳转到标号
mov ss:[0],di ;将di送入ss:[0]暂存
mov di,ss:[2] ;将ss:[2]中的数据送入di
pop dx ;出栈dx
pop ax ;出栈ax
div word ptr ds:[di+168] ;ax=(dx*65536+ax)/ds:[di+168]
mov es:[bx+0dh],ax ;将ax中的商送入es:[bx+0dh]
mov ax,ds:[di+168] ;将ds:[di+168]送入ax
mov es:[bx+0ah],ax ;将ax送入es:[bx+0ah]
add di,2 ;di=di+2
mov ss:[2],di ;将di送入ss:[2]暂存
add bx,16 ;bx=bx+16指向table的下一行
pop cx ;出栈cx
loop xh ;cx=cx-1 cx<>0则跳转到标号
;;;;;;;;;;;;;;;;;;;;;;;以上位公司的年份、收入、雇员和人均收入的计算即传送。;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,table ;es指向table段
mov es,ax
mov ax,stack ;ds指向stack段
mov ds,ax
sub di,di ;初始化di=0
sub bx,bx
mov cx,21 ;初始化循环 cx=21
sub dh,dh ;dh=0 行
call qp ;调用子列程清屏
show1: push cx
push bx ;因为年份本来就是十进制字符不必转换就直接调用子列程bx定位行
;,又因为同一循环内年份下面的程序也要调用子列程所以会冲突那么可以将bx压栈后面在恢复
mov cx,3 ;将行压栈三次
d: push dx
loop d
sub si,si ;初始化si=0传入子列程
push ds ;压栈ds中的段地址
push es ;压栈es中的段地址
pop ds ;出栈到ds
mov cl,2 ;cl=2 绿色
mov dl,10 ;dl=10 列
call show_str ;调用子列程 show_str 显示
pop ds ;恢复原段地址到ds
;年份显示
sub bx,bx ;初始化子列程 bx=0
mov ax,es:[di+5] ;将es:[bx+5]中的数据送入ax 传入子列程 ax为低16位被除数
mov dx,es:[di+7] ;将es:[bx+7]中的数据送入ax 传入子列程 dx为高16位被除数
call dtco ;调用子列程 dtco 计算出十进制字符串 返回的结果存放在 ss:[0]为起始处
;收入转换为十进制字符
pop dx ;出栈行
mov dl,20 ;dl=20列 传入子列程
call show_str ;调用 show_str
;显示收入
mov ax,es:[di+0ah] ;将es:[bx+0ah]中的数据送入ax 传入子列程
sub dx,dx ;dx传入0
call dtco ;......
;雇员转换
pop dx
mov dl,30
call show_str
;显示雇员
mov ax,es:[di+0dh]
sub dx,dx
call dtco
;人均收入转换
pop dx
mov dl,40
call show_str
;人均收入显示
inc dh ;dh=dh+1
add di,16 ;di=di+16
pop bx ;出栈bx并加16
add bx,16
pop cx ;出栈cx计数循环
loop show1
;;;;;;;;;;;;;;;;;;;;;;;;;;;年份 收入 雇员及人均收入的 显示;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,4c00h
int 21h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 程序返回 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 一下为子列程 dtco ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dtco: push ax
push bx
push cx
push dx
push si
push bp
;压栈寄存器中的数据
sub bp,bp
sub si,si
dtco_s: mov cx,0ah ;除数为10
push ax ;首先压栈低16位(ax)中的数据
mov ax,dx ;然后将高16位(dx)赋给ax
sub dx,dx ;清除dx中的数据
div cx ;(dx*65536+ax)/(cx)=(ax)商 (dx)余
mov bx,ax ;将商赋给bx暂存
pop ax ;出栈压栈的低16位被除数到ax
div cx ;(dx*65536+ax)/(cx)=(ax)商 (dx)余
add dx,30h ;余数加上30h等于十进制字符
push dx ;压栈十进制字符
mov dx,bx ;将高16位上赋给dx
mov cx,ax ;将定16位商赋给cx
inc si ;用si进行计数
jcxz ret_dtco ;(cx)不等于0则不跳转
jmp short dtco_s ;进行循环
ret_dtco: mov cx,si ;将si中的数据赋给cx进行循环
ret_s: pop [bp] ;出栈十进制字符到cx
inc bp ;(bp)=(bp)+2 bp指向下一个字单元
loop ret_s
pop bp
pop si
pop dx
pop cx
pop bx
pop ax
;出栈数据
ret ;返回上次执行call dtco 下条指令的ip 最后才是返回sub dh,0
;;;;;;;;;;;;;;;;;;;;;;;;;; 一下为子列程show_dtr ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
show_str: push ax ;压栈各个寄存器的数据
push bx
push cx
push dx
push si
push di
push ds
push es
mov ax,0b800h ;初始化显存段地址
mov es,ax
mov al,160 ;al*dh+dl 得出显存的偏移地址
inc dh ;行号是从0开始所以8行应该是8+1
mul dh
sub dh,dh
add dx,dx
add ax,dx
mov di,ax ;将偏移地址赋给di
mov al,cl ;将属性送入到al存放
show: sub cx,cx
mov cl,ds:[bx+si]
jcxz ret_show
mov ch,al ;将内存ss:[0]单元中存放的属性送入ah
mov es:[di],cx ;将(ax)送入显存es:[di]
inc si ;(si)=(si)+1
add di,2 ;(di)=(di)+2
jmp short show
ret_show: pop es ;出栈
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;一下为子列程qp(作用清屏);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
qp: push ax
push cx
push ds
push si
;压栈关联寄存器
mov ax,0b800h ;初始化需要清屏的显存地址
mov ds,ax
sub si,si
mov ax,' ' ;给ax寄存器赋空字符然后把它传送到显存达到清屏的效果
mov cx,2000 ;ax为16为寄存器对应一个显存字单元所以 循环次数=25行*(160列/2)
q: mov [si],ax
add si,2
loop q
pop si
pop ds
pop cx
pop ax
ret
codesg ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
data ends
table segment
db 150h dup (0)
table ends
stack segment
db 0ffffh dup (0)
stack ends
codesg segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov ax,stack
mov ss,ax
mov sp,0h
sub bx,bx
mov cx,21
xh: push cx ;压栈cx
mov cx,2 ;初始化内循环 cx=2
sub si,si ;初始化内循环 si=0
mov di,ss:[0] ;将ss:[0]中的数据送入di
s: mov ax,ds:[di] ;将ds:[di]中的数据送入ax
mov es:[bx+si],ax ;将ax中的数据送入 es:[bx+si]
mov ax,ds:[di+84] ;将ds:[di+84]中的数据送入ax
push ax ;压栈 ax
mov es:[bx+si+5],ax ;将ax中的数据送入es:[bx+si+5]
add di,2 ;di=di+2
add si,2 ;si=di+2
loop s ;cx=cx-1 cx不等于0 跳转到标号
mov ss:[0],di ;将di送入ss:[0]暂存
mov di,ss:[2] ;将ss:[2]中的数据送入di
pop dx ;出栈dx
pop ax ;出栈ax
div word ptr ds:[di+168] ;ax=(dx*65536+ax)/ds:[di+168]
mov es:[bx+0dh],ax ;将ax中的商送入es:[bx+0dh]
mov ax,ds:[di+168] ;将ds:[di+168]送入ax
mov es:[bx+0ah],ax ;将ax送入es:[bx+0ah]
add di,2 ;di=di+2
mov ss:[2],di ;将di送入ss:[2]暂存
add bx,16 ;bx=bx+16指向table的下一行
pop cx ;出栈cx
loop xh ;cx=cx-1 cx<>0则跳转到标号
;;;;;;;;;;;;;;;;;;;;;;;以上位公司的年份、收入、雇员和人均收入的计算即传送。;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,table ;es指向table段
mov es,ax
mov ax,stack ;ds指向stack段
mov ds,ax
sub di,di ;初始化di=0
sub bx,bx
mov cx,21 ;初始化循环 cx=21
sub dh,dh ;dh=0 行
call qp ;调用子列程清屏
show1: push cx
push bx ;因为年份本来就是十进制字符不必转换就直接调用子列程bx定位行
;,又因为同一循环内年份下面的程序也要调用子列程所以会冲突那么可以将bx压栈后面在恢复
mov cx,3 ;将行压栈三次
d: push dx
loop d
sub si,si ;初始化si=0传入子列程
push ds ;压栈ds中的段地址
push es ;压栈es中的段地址
pop ds ;出栈到ds
mov cl,2 ;cl=2 绿色
mov dl,10 ;dl=10 列
call show_str ;调用子列程 show_str 显示
pop ds ;恢复原段地址到ds
;年份显示
sub bx,bx ;初始化子列程 bx=0
mov ax,es:[di+5] ;将es:[bx+5]中的数据送入ax 传入子列程 ax为低16位被除数
mov dx,es:[di+7] ;将es:[bx+7]中的数据送入ax 传入子列程 dx为高16位被除数
call dtco ;调用子列程 dtco 计算出十进制字符串 返回的结果存放在 ss:[0]为起始处
;收入转换为十进制字符
pop dx ;出栈行
mov dl,20 ;dl=20列 传入子列程
call show_str ;调用 show_str
;显示收入
mov ax,es:[di+0ah] ;将es:[bx+0ah]中的数据送入ax 传入子列程
sub dx,dx ;dx传入0
call dtco ;......
;雇员转换
pop dx
mov dl,30
call show_str
;显示雇员
mov ax,es:[di+0dh]
sub dx,dx
call dtco
;人均收入转换
pop dx
mov dl,40
call show_str
;人均收入显示
inc dh ;dh=dh+1
add di,16 ;di=di+16
pop bx ;出栈bx并加16
add bx,16
pop cx ;出栈cx计数循环
loop show1
;;;;;;;;;;;;;;;;;;;;;;;;;;;年份 收入 雇员及人均收入的 显示;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,4c00h
int 21h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 程序返回 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 一下为子列程 dtco ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dtco: push ax
push bx
push cx
push dx
push si
push bp
;压栈寄存器中的数据
sub bp,bp
sub si,si
dtco_s: mov cx,0ah ;除数为10
push ax ;首先压栈低16位(ax)中的数据
mov ax,dx ;然后将高16位(dx)赋给ax
sub dx,dx ;清除dx中的数据
div cx ;(dx*65536+ax)/(cx)=(ax)商 (dx)余
mov bx,ax ;将商赋给bx暂存
pop ax ;出栈压栈的低16位被除数到ax
div cx ;(dx*65536+ax)/(cx)=(ax)商 (dx)余
add dx,30h ;余数加上30h等于十进制字符
push dx ;压栈十进制字符
mov dx,bx ;将高16位上赋给dx
mov cx,ax ;将定16位商赋给cx
inc si ;用si进行计数
jcxz ret_dtco ;(cx)不等于0则不跳转
jmp short dtco_s ;进行循环
ret_dtco: mov cx,si ;将si中的数据赋给cx进行循环
ret_s: pop [bp] ;出栈十进制字符到cx
inc bp ;(bp)=(bp)+2 bp指向下一个字单元
loop ret_s
pop bp
pop si
pop dx
pop cx
pop bx
pop ax
;出栈数据
ret ;返回上次执行call dtco 下条指令的ip 最后才是返回sub dh,0
;;;;;;;;;;;;;;;;;;;;;;;;;; 一下为子列程show_dtr ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
show_str: push ax ;压栈各个寄存器的数据
push bx
push cx
push dx
push si
push di
push ds
push es
mov ax,0b800h ;初始化显存段地址
mov es,ax
mov al,160 ;al*dh+dl 得出显存的偏移地址
inc dh ;行号是从0开始所以8行应该是8+1
mul dh
sub dh,dh
add dx,dx
add ax,dx
mov di,ax ;将偏移地址赋给di
mov al,cl ;将属性送入到al存放
show: sub cx,cx
mov cl,ds:[bx+si]
jcxz ret_show
mov ch,al ;将内存ss:[0]单元中存放的属性送入ah
mov es:[di],cx ;将(ax)送入显存es:[di]
inc si ;(si)=(si)+1
add di,2 ;(di)=(di)+2
jmp short show
ret_show: pop es ;出栈
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;一下为子列程qp(作用清屏);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
qp: push ax
push cx
push ds
push si
;压栈关联寄存器
mov ax,0b800h ;初始化需要清屏的显存地址
mov ds,ax
sub si,si
mov ax,' ' ;给ax寄存器赋空字符然后把它传送到显存达到清屏的效果
mov cx,2000 ;ax为16为寄存器对应一个显存字单元所以 循环次数=25行*(160列/2)
q: mov [si],ax
add si,2
loop q
pop si
pop ds
pop cx
pop ax
ret
codesg ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
评论次数(0) |
浏览次数(495) |
类型(汇编作业) |
收藏此文 |