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

任务:按照书中图片格式,打印一坨数据
注:dtoc_1子程序较实验十中dtoc有如下不同:1.操作数据范围由0-ffffH变为0-ffffffffH;2.向ds:si指向的字符串写入数据后不会添加数字0(方便后面)
代码如下:
assume cs:codesg

datasg segment
	db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985'
	db '1986','1987','1988','1989','1990','1991','1992','1993','1994','1995'

	dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514,345980,590827
	dd 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
datasg ends	;di->年份和收入 bx->雇员

string segment
	db '                               ',0	;占位32B(16字)
string ends

stacksg segment
	dw 0,0,0,0,0,0,0,0
	dw 0,0,0,0,0,0,0,0	;栈空间:0-1fH
stacksg ends

codesg segment
start:
	mov ax,stacksg
	mov ss,ax
	mov sp,20H	;初始化栈空间

	mov ax,datasg
	mov es,ax
	xor di,di
	xor bx,bx	;es->操作数据:di->年份和收入,bx->雇员
				;年份+0,收入+54H,雇员+0a8H
	mov ax,string
	mov ds,ax
	xor si,si	;ds:si->string
	
	mov cx,21	;打印21年信息
	mov dx,0312H;设置打印位置
s:	push cx		;保存程序计数,下面需要cx寄存器
	push dx		;保存打印位置,下面需要dx寄存器

	mov cx,40	;清空string:防止这公司哪年赔大了哈哈
s5:	mov byte ptr ds:[si],' '
	add si,1
	loop s5
	xor si,si

	mov ax,es:[di+0]
	mov dx,es:[di+2]
	mov ds:[si+0],ax
	mov ds:[si+2],dx
	add si,8	;写入年份信息并将si->下一位置

	mov ax,es:[di+54H]
	mov dx,es:[di+56H]	;(dx)(ax)=收入
	push ax
	push dx		;保存收入信息,以便计算人均收入
	call dtoc_1
	add si,8	;写入收入信息并将si->下一位置
	add di,4	;di->下一年份和收入

	xor dx,dx
	mov ax,es:[bx+0a8H]	;(dx)(ax)=雇员
	push ax		;保存雇员信息,以便计算人均收入
	call dtoc_1
	add si,8	;写入雇员信息并将si->下一位置
	add bx,2	;bx->下一雇员

	pop cx		;(cx)=雇员
	pop dx
	pop ax		;(dx)(ax)=收入,!注意高低位字顺序!
	call divdw	;当前数据并不会溢出,这里也可以用32位除
	call dtoc_1

	pop dx		;归还打印位置给dx,为show_str准备参数
	mov cx,2	;设置打印颜色,为show_str准备参数
	xor si,si	;将ds:si->string,为show_str准备参数
	call show_str
	pop cx
	inc dh		;下一年信息将打印到下一行
	loop s

	mov ax,4c00H
	int 21H
	
;ds:si->字符串,(bx)(ax)=操作数据
;寄存器均不会被修改
;与实验10的dtoc不同,dtoc_1的操作数据范围:0-ffffffffH
;	且字符串结尾不再添加数字0
dtoc_1:	
	push ax		
	push bx
	push dx		
	push cx
	push di		;将用到的寄存器入栈

	xor di,di	;di记录转化后字符串长度,方便ok1
s3:	mov cx,10
	call divdw	;32位除中,商可能溢出,所以用divdw
	push cx		;将余数压入栈:若直接写入string段则为逆序
	inc di
	mov cx,ax
	add cx,dx	;检查商((bx)+(ax))是否为0
	jcxz ok1
	jmp s3

ok1:mov cx,di
	xor bx,bx
s4:	pop ax
	add ax,30H	;将数字(0-9)转化为字符
	mov ds:[si+bx],al	;!注意,这里是al而不是ax
	inc bx
	loop s4

	pop di
	pop cx
	pop dx	
	pop bx	
	pop ax		;恢复被修改的寄存器
	ret

;ds:si->字符串首地址
;dh行号 dl列号 cl颜色
;寄存器均不会被修改
show_str:	
	push es	
	push di
	push ax	
	push bx		
	push cx
	push dx		;将用到的寄存器入栈
	
	mov ax,0b800H
	mov es,ax
	xor ax,ax
	mov al,160
	mul dh		;8位乘
	xor dh,dh
	add dx,dx
	add ax,dx
	mov di,ax	;es:di->指定显示首地址

	mov al,cl	;cl即将被用作判断
	xor bx,bx
s0:	mov cl,ds:[si+bx]
	jcxz ok0	;若(cx)=0退出循环
	mov es:[di+0],cl	;写入要打印的字符
	mov es:[di+1],al	;写入要打印字符的颜色
	inc bx
	add di,2
	jmp s0

ok0:pop dx
	pop cx
	pop bx
	pop ax
	pop di
	pop es		;恢复被修改的寄存器
	ret

;(dx)=H,(ax)=L,(cx)=N
;(dx)(ax)/(cx)=(dx)(ax)
;(dx)(ax)%(cx)=(cx)
;除返回所用寄存器外,其他均不会被修改
divdw:
    push bx     ;将用到的寄存器入栈 

    mov bx,ax   ;(bx)=被除数低16位
    mov ax,dx
    xor dx,dx   ;(dx)(ax)=H
    div cx      ;32位除,(ax)=H/N,(dx)=H%N
    push ax     ;压入H/N
    mov ax,bx   ;(dx)(ax)=H%N*65536+L
    div cx      ;(ax)=(H%N*65536+L)/N
    mov cx,dx   ;(cx)=(dx)=余数
    pop dx      ;(dx)(ax)=
                ;   H/N*65536+(H%N*65536+L)/N
    pop bx      ;恢复被修改的寄存器
    ret
codesg ends

end start
运行结果如下:

运行结果

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值