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

课程设计1
将实验7(见原书)中Power idea 公司的数据按照如下格式在屏幕上显示出来。
在这里插入图片描述
提示:因为程序要显示的数据有些己经大于65535,应该编写一个新的数据到字符串的转化子程序,完成dword型数据到字符串的转化。说明如下:

名称:dtoc
功能:将dword型数据转变为表示十进制的字符串,字符串以0为结尾符。
参数:(ax)=dword型数据的低16位
(dx)=dword型数据的高16位
ds:si指向字符串的首地址
返回:无

在这个子程序中要注意除法溢出的问题,可以用实验10中设计的子程序divdw来解决。

代码如下:

  assume cs:code

data segment
	dw 1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,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,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,11542,14430,15257,17800
	dw 5,3,42,104,85,210,123,111,105,125,140,136,153,211,199,209,224,239,260,304,333
	db 10,0,0,0,0,10,0,0,0  ;内存数据初始地址  ds:[0d2h]
	;内存单元的使用:第一个用作8位除数		第二三个暂存cx		第4.5个存call后的ip   第6.7位做16位除数10  第8.9位暂存si
data ends

stack segment
	dw 16 dup(0)			;已开始一位一位放入字符+属性
stack ends

;寄存器使用记录:cs,ip不能动   ds用作 数据段地址   si用作年份、雇员数、工资、内存数据的偏移地址		di用作总收入偏移地址	ss,sp设置栈
;				cx 放21次循环,中间可保存再利用    es:bp显存
;所有寄存器,已使用标记* 	ax		bx		cx*		dx		ds*		es*		cs*		ip*		ss*		sp*		si*		di*		bp*
;
code segment
	start:	mov ax,data
			mov ds,ax
			mov si,0h		;雇员si+7eh  工资si+0a8h   内存数据初始地址  ds:[0d2h]
			mov di,2ah       ;di表示总收入偏移地址
			;设置数据段偏移地址
			mov ax,stack
			mov ss,ax
			mov sp,20h
			;设置栈
			mov ax,0b800h
			mov es,ax 
			mov bp,0h			
			;设置显存初始段地址
		
		mov cx,21
	s:	mov ds:[0d3h],cx     ;将循环次数cx存入内存单元,。。。。。。。。。。。。。。。。保存cx,释放cx
		mov ax,0ah
		push ax				;先入栈0ah作为结束标志
		mov ax,ds:[si]		;将月份放入ax中,之后用除法。。。。。。。。。。。锁定ax
	s0:	div byte ptr ds:[0d2h]
		add ah,30h		;数字加30h变为对应字符
		mov cl,al		
		mov ch,0		;商暂存到cx中......................锁定cx
		mov al,ah		;放到低位
		mov ah,2h		;高位存放颜色属性  黑底绿字
		push ax			;入栈一个年份的一个字符
		jcxz ok
		mov ax,cx		;将商再存入ax......................释放cx
		jmp short s0	;循环得把每一位入栈
	
	ok:			;........................。。。。。。。。。。。。。。。。。。。。释放ax		
	s1:	pop ax
		mov cx,0ah
		sub cx,ax
		jcxz ok2
	
		mov es:[bp],ax
		add bp,2
		jmp short s1	;将字符放入显存,     完成一个年份的显示
	
	
	ok2:mov ax,ds:[di]
		mov dx,ds:[di+2]		;ax,dx被除数,。。。。。。。。。。。。锁定ax,dx
		
		call dtoc
								;。。。。。。。。。。。。。。。。。。释放ax,dx
		mov bp,40
	s3:	pop ax
		mov cx,0ah
		sub cx,ax
		jcxz oks
		mov ah,2h
		mov es:[bp],ax
		add bp,2
		jmp short s3	;将字符放入显存,     完成一个总收入的显示


oks:	mov dx,0
		mov ax,ds:[si+7eh]		;将雇员数放入ax中,之后用除法。。。。。。。。。。。锁定ax
		call dtoc
	
				;........................。。。。。。。。。。。。。。。。。。。。释放ax	
		mov bp,80	;改变显存行偏移地址
	s6:	pop ax
		mov cx,0ah
		sub cx,ax
		jcxz ok_s6
		mov ah,2h
		mov es:[bp],ax
		add bp,2
		jmp short s6	;将字符放入显存,     完成一个雇员数的显示
		
		
ok_s6:	mov ax,0ah
		push ax				;先入栈0ah作为结束标志
		mov ax,ds:[si+0a8h]		;将工资放入ax中,之后用除法。。。。。。。。。。。锁定ax
	s7:	div byte ptr ds:[0d2h]
		add ah,30h		;数字加30h变为对应字符
		mov cl,al		
		mov ch,0		;商暂存到cx中......................锁定cx
		mov al,ah		;放到低位
		mov ah,2h		;高位存放颜色属性  黑底绿字
		push ax			;入栈一个工资的一个字符
		jcxz ok_s7
		mov ax,cx		;将商再存入ax......................释放cx
		jmp short s7	;循环得把每一位入栈
	
	ok_s7:			;........................。。。。。。。。。。。。。。。。。。。。释放ax	
		mov bp,120	;改变显存行偏移地址
	s8:	pop ax
		mov cx,0ah
		sub cx,ax
		jcxz ok_s8
	
		mov es:[bp],ax
		add bp,2
		jmp short s8	;将字符放入显存,     完成一个雇员数的显示	
		
		
ok_s8:	mov ax,es
		add ax,0ah
		mov es,ax    ;显存下一行
		mov bp,0		;重置显存行偏移地址
		add si,2		;下一组年份、雇员、工资
		add di,4		;下一组总收入
		mov cx,ds:[0d3h]    ;.................。。。。。。。。。。。。。。。。恢复cx
		sub cx,1
		jcxz wan
		jmp near ptr s
	
	wan:mov ax,4c00h
		int 21h
		
dtoc:	mov ds:[0d9h],si ;暂存si。。。。。。。。。。。。暂时释放si
		pop ds:[0d5h]	;出栈ip到内存单元,防止取不出来
		mov si,0ah
		push si			;入栈0a0h作为一个数据结束标志
	s4:	push ax			;保存被除数低16位
		mov ax,dx
		mov dx,0h
		div word ptr ds:[0d7h]			;高16位先除
		mov si,ax		;高16位先除的商放在si,商还在dx中,当做低16位除的高16位
		pop ax			;恢复低16位到ax中
		div word ptr ds:[0d7h]
		add dx,30h
		push dx		    ;最终商的余数入栈
		mov dx,si		;高16位先除的商也是最终商的高16位,最终商的低16为就在ax中
		
		mov cx,ax
		jcxz s88			;判断低16位是否为0,为0则继续判断高16位,否则执行下一句,继续循环
		jmp near ptr s4			
s88:	mov cx,dx	                      
		jcxz ok_dtoc              ;高16位也为0则结束一个数字,否则执行下一句,继续循环
		jmp near ptr s4
ok_dtoc:mov si,ds:[0d9h]          ;。。。。。。。。。。。。。。。。。恢复si
		push ds:[0d5h]    ;从内存单元找到ip,并跳转
		ret
		
code ends
end start

代码结果图:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值