您的位置:首页 > 其它

汇编语言(王爽) 课程设计1

2011-01-27 09:34 731 查看
这边是要将实验7的公司的数据显示在dos窗口下,这边只给出代码

DATAS SEGMENT
;此处输入数据段代码
db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985','1986','1987','1988','1989','1990','1991','1992','1993','1994','1995'
;以上是21年的21个字符串
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514,345980,590827,803530,1183000,1843000,2759000,3753000,4549000,5937000
;以上是公司的21年各个年份的总输入
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226,11542,14430,15257,17800
;以上是21个员工人数
dd 21 dup (0)
;起始这边没有必要弄成事双字节型的,因为刚好员工的平均收入都没有 超过65535这边设置双字节型只是为了巩固学习的知识
db 10 dup (0) ;作为数据送入现存的一个缓存中介
DATAS ENDS

STACKS SEGMENT
;此处输入堆栈段代码
dw 20h dup (0)
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
mov ax,stacks
mov ss,ax
mov sp,20h
;这边先算出员工平均收入,然后再将所有的数据写入到显存中
mov cx,21
mov si,84	;设置公司总收入游标
mov di,168	;设置员工人数游标
averg:
mov ax,ds:[si]
mov dx,ds:[si+2]
mov bx,ds:[di]
call divdw	;进行相除运算
;将结果放入到定义好的数据段中
mov word ptr ds:[si+126],ax
mov word ptr ds:[si+126+2],dx
add si,4
add di,2
loop averg

;接下来我们逐个项目的放入表中
;先是年份,再试每年总收入,再试员工数,再是员工平均收入
;重新初始化一些内存数据
mov cx,21
mov si,0
mov di,294 ;缓存段起始地址
mov dl,2	;第二行
mov dh,2	;第二列
show_year:
push cx ;暂存循环次数
mov cl,2h

mov ax,ds:[si]
mov ds:[di],ax
mov ax,ds:[si+2]
mov ds:[di+2],ax
mov byte ptr ds:[di+4],0 ;将年份放入缓存区,并且使其最后一个字节是0
;将缓存区中的内容放入显存中
push si
mov si,di
call show_str

pop si	;恢复si
pop cx	;恢复cx
add si,4 ;指向下一个年份
inc dh	;显示的位置移到下一行
loop show_year

;先是总收入
mov cx,21
mov si,84	;年总收入的数据的偏移
add di,8
mov dl,18
mov dh,2
show_sum:
push cx ;暂存循环次数,一边下边设置显示字符串的属性
push dx	;暂时保存显示位置数据
mov ax,ds:[si]
mov dx,ds:[si+2]
call dtoc
mov ax,si
mov si,di
pop dx
mov cx,2
call show_str
mov si,ax
add si,4	;指向下一个数值
mov di,302	;从新确定缓存区模拟对战顶部位置
inc dh	;移到下一行准备显示下一条数据
pop cx
loop show_sum

;下面是员工人数的显示
mov cx,21
mov si,168
mov di,302
mov dl,34
mov dh,2
show_wksnum:
push cx
mov ax,ds:[si]
call dtocword	;这边因为函数中调用的方法是不一样的所以才如此
push si
mov si,di
mov cx,2
call show_str
pop si
add si,2
mov di,302
inc dh
pop cx
loop show_wksnum

;员工人均收入的显示
mov cx,21
mov si,210
mov di,302
mov dl,50
mov dh,2
show_salary:
push cx
push dx
mov ax,ds:[si]
mov dx,ds:[si+2]
call dtoc
mov ax,si	;暂时保存si的值
mov si,di
pop dx
mov cx,2
call show_str
mov si,ax
add si,4	;指向下一个数值
mov di,302	;从新确定缓存区模拟对战顶部位置
inc dh	;移到下一行准备显示下一条数据
pop cx
loop show_salary

finals:
jmp short finals

MOV AH,4CH
INT 21H

divdw:
;说明一下,这边的被除数是双字型,除数是字型,商是双字型
;参数说明:ax:存放被除数的低位;dx:存放被除数的高位;bx:除数
;返回:ax:商的低位;dx:商的低位;bx:余数

push cx
push si
push di

push ax		;将低位暂存	,这边用的是书中的算法(有一个公式)
mov ax,dx	;将高位移向低位
mov dx,0	;高位赋0
div bx		;做除法
mov cx,ax	;将商暂存
pop ax		;将原来除数的低位恢复,刚刚的余数dx显示是除数的高位
div bx		;再做除法
mov bx,dx	;现在的余数是原来除数的最终于舒
mov dx,cx	;原来第一次的商事最终商的高位,这个是可以证明的

;解除除法溢出子程序结束
pop di
pop si
pop cx
ret

show_str:
push dx;保存数据
push cx
push di
push ax
mov ax,0b800h
mov es,ax
;确定字符显示位置的偏移量
mov al,160 ;这边显示缓存虽是80个字符,但是容量是160字节,每个字符占2个字节的容量
mul dh
mov dh,0
add ax,dx
add ax,dx ;因为一个字符占两个字节的缘故
mov bx,ax
mov al,cl
;标记显示内存的偏移
mov di,0
s:
mov ch,0
mov cl,[si]
jcxz ok
mov	byte ptr es:[bx+di],cl
mov byte ptr es:[bx+di+1],al
inc si
add di,2
jmp short s
ok:
pop ax
pop di
pop cx ;恢复数据
pop dx
ret

dtoc:
push cx
dtocs:
mov bx,0ah	;除数是10
call divdw ;求余
add bx,30h
mov byte ptr ds:[di],bl	;将余数放入到显存中
mov cx,dx
or cx,ax	;上面两句是判断上是不是0
jcxz ok2	;如果商是零的话,求余结束
dec di	;这边di是模拟堆栈指针,放入一个字节后,di自减
jmp short dtocs

ok2:
pop cx
ret

dtocword:
push cx
dtocwords:
mov bl,0ah
call divw
add bl,30h
mov byte ptr ds:[di],bl
mov cx,ax
jcxz ok1
dec di
jmp short dtocwords
ok1:
pop cx
ret

divw:
;说明:这边的被除数是字型,除数字节型,商是字型
;参数说明:ax:存放被除数 bl:除数
;返回:ax:商 bl:余数
push dx
mov dl,al
mov al,ah
mov ah,0
div bl
mov dh,al
mov al,dl
div bl
mov bl,ah
mov ah,dh
pop dx
ret
CODES ENDS
END START


执行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: