现在的位置: 首页 > 综合 > 正文

王爽《汇编语言》课程设计1

2013年10月17日 ⁄ 综合 ⁄ 共 2929字 ⁄ 字号 评论关闭
运行结果(减少了部分数据量,不影响程序):
程序如下:
assume cs:code
;年份
year segment
	db '1975','1978','1981','1984','1987','1990','1993','1995'	
year ends
;收入
income segment
	dd 16,1356,16000,97479,345980,1183000,3753000,5937000
income ends
;雇员
employee segment
	dw 3,13,130,778,2258,5635,14430,17800
employee ends

table segment
	;每列占9格,4列,8行
	db 288 dup(' ')
table ends

code segment
start:
	mov ax,table
	mov es,ax
	
	mov bx,0 ;定义年份的递增量
	mov si,0 ;定义table的递增量
	mov cx,8 ;循环添加8组数据到table中
loopyear:	
	;添加年份到table
	mov ax,year
	mov ds,ax
	mov al,[bx]
	mov es:[si],al
	mov al,[bx+1]
	mov es:[si+1],al
	mov al,[bx+2]
	mov es:[si+2],al
	mov al,[bx+3]
	mov es:[si+3],al

	add bx,4 ;增加偏移量
	add si,36
	loop loopyear


	mov bx,0 ;定义收入的递增量
	mov si,0 ;定义table的递增量
	mov cx,8 ;循环添加8组数据到table中
loopincome:
	;转换收入为数字字符,添加到table中
	push es
	push si
	mov ax,income
	mov es,ax ;由于转换用到ds,所以我们用es来暂时表示income
	mov ax,table
	mov ds,ax
	add si,9 ;从第9列开始保存收入
	mov ax,es:[bx]
	mov dx,es:[bx+2]
	call ddtoc
	pop si
	pop es

	add bx,4 ;增加偏移量
	add si,36
	loop loopincome


	mov bx,0 ;定义收入的递增量
	mov si,0 ;定义table的递增量
	mov cx,8 ;循环添加8组数据到table中
loopemployee:
	;转换雇员为十进制字符,添加到table中
	push es
	push si
	mov ax,employee
	mov es,ax
	mov ax,table
	mov ds,ax
	add si,18
	mov ax,es:[bx]
	call dtoc
	pop si
	pop es

	add bx,2 ;增加偏移量
	add si,36
	loop loopemployee


	mov bx,0 ;定义收入的递增量
	mov si,0 ;定义table的递增量
	mov di,0 ;雇员递增量
	mov cx,8 ;循环添加8组数据到table中
loopaverage:
	;计算人均收入,并且转换为十进制字符,添加到tabl
	push es
	push si
	mov ax,employee
	mov es,ax
	mov ax,income
	mov ds,ax
	mov ax,[bx]
	mov dx,[bx+2]
	div word ptr es:[di] ;商保存在ax中
	mov dx,table
	mov ds,dx
	add si,27
	call dtoc
	pop si
	pop es

	;最后的空格保存为0表示这一行数据的结束,方便打印
	mov ax,table
	mov es,ax
	mov dl,0
	mov es:[si+35],dl

	add bx,4 ;增加偏移量
	add si,36
	add di,2
	loop loopaverage

	
	mov dh,8	;行号
	mov dl,3	;列号
	mov cl,07h	;白色字	
	mov ax,table
	mov ds,ax
	mov si,0	;循环加入字
	mov bl,cl
	mov cx,8
loopprint:
	push bx
	push cx
	mov cl,bl
	call show_str
	pop cx
	pop bx
	
	;让dh加1
	mov al,dh
	mov ah,0
	inc ax
	mov dh,al
	add si,36
	loop loopprint

	mov ax,4c00h
	int 21h

;将word型数据转换为十进制字符串,ax是word型数据,ds:si指向字符串首地址
dtoc:
	push ax
	push di
	push cx
	push dx
	push si
	mov di,0 ;记录入栈多少次,就是有多少位数
	s1:
	mov cx,10d ;除10
	mov dx,0
	div cx

	mov cx,ax ;如果商为0,那么求值完成
	jcxz s2

	add dx,30h
	push dx ;把求得的ACSII入栈
	inc di
	jmp short s1
	s2:
	add dx,30h ;最后一次也要记录
	push dx
	inc di

	mov cx,di
	s3:
	pop ax
	mov [si],al ;ACSII码只占用了低8位
	inc si
	loop s3

	pop si
	pop dx
	pop cx
	pop di
	pop ax
	ret

;将dword型数据转换为十进制字符串,ax是dword型低16位,dx为高16位,ds:si指向字符串首地址
ddtoc:
	push ax
	push di
	push cx
	push dx
	push si
	mov di,0 ;记录入栈多少次,就是有多少位数
	dds1:
	mov cx,10d ;除10
	call divdw

	push cx
	mov cx,ax ;如果商为0,那么求值完成
	add cx,dx ;低和高相加一下,看看是不是为0
	jcxz dds2
	pop cx

	add cx,30h
	push cx ;把求得的ACSII入栈
	inc di
	jmp short dds1
	dds2:
	pop cx
	add cx,30h ;最后一次也要记录
	push cx
	inc di

	mov cx,di
	dds3:
	pop ax
	mov [si],al ;ACSII码只占用了低8位
	inc si
	loop dds3

	pop si
	pop dx
	pop cx
	pop di
	pop ax
	ret

;解决除法溢出问题,ax保存低16位,dx高16位,cx为除数,
;结果低16位保存在ax,高16保存在dx,余数保存在cx
divdw:
	push bx
	push ax

	mov ax,dx ;int(H/N)
	mov dx,0
	div cx
	mov bx,ax ;商暂存到bx,乘65536是高16位

	pop ax ;取出ax作为低16位,上次计算的余数在dx中,刚好做为高16位
	div cx

	mov cx,dx ;余数赋值给cx
	mov dx,bx ;dx赋值为上次暂存的bx
	
	pop bx
	ret

;dh保存行号,dl保存列号,cl颜色,ds:si指向首地址
show_str:
	push cx	;保存用到的寄存器
	push si
	push es
	push di
	push bx
	push dx

	mov ax,0b800h
	mov es,ax

	mov al,0a0h	;一行的总列数160字节
	dec dh		;行号减1,因为是从0开始的
	mul dh		;计算行开始偏移地址
	mov bx,ax

	mov al,2
	mul dl		;计算列
	sub ax,2	;列也是从0开始,而且一个字符占两个字节
	add bx,ax	;求出开始位置	
	
	mov di,0
	mov al,cl
	mov ch,0	;高8位为0
	s:	
	mov cl,ds:[si]	;判断是否到了字符结束
	jcxz ok
	mov es:[bx+di],cl
	mov es:[bx+di+1],al

	inc si
	add di,2
	jmp short s
	ok:
	pop dx
	pop bx
	pop di
	pop es
	pop si
	pop cx
	ret
code ends
end start

抱歉!评论已关闭.