汇编语言课程设计一完整代码及详细解析

汇编语言课程设计一完整代码及详细解析


建议先自己思考问题的答案,不懂则返回看书

在这里插入图片描述
第二列需要用除法的溢出公式计算,第三列需要32/16 位的除法,第四列需要16/8位的除法。详细解析看代码注释。

assume cs:code
data segment
 db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985'
 db '1986','1987','1988','1989','1990','1991','1992','1993','1994','1995'
 ;db占21*4Byte  0-83

 dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514,345980
 dd 590827,803530,1183000,1843000,2758000,3753000,4649000,5937000
 ;dd型数据,需要两个寄存器存放 占21*4Byte  84-167
 ;0010计算机中低字节存放高位00h,高字节存放低位10h

 dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
 dw 11542,14430,15257,17800
 ;dw占21*2Byte 168-209
data ends

temp segment
  dw 24 dup (0)
temp ends

table segment
 db 21 dup ('year    r          e        s  ',0)
table ends

stack segment
  dw 32 dup(0)
stack ends

;1.用第二、三列的值计算得到第四列的值。。计算到哪
;2.将第二、三、四列的值转换为十进制字符串。。转换后存在哪
;3.按格式显示。。格式如何安排

code segment
start:
	mov ax,data
	mov ds,ax
	mov si,84
	mov di,168

	mov bx,table
	mov es,bx
	mov bx,28		;ds,si,di,es,bx,是此函数中的全局变量,28是table中存放salary的列号

	call divsalary	;此函数结束,第四列的值计算完毕,十进制存在table中

	call moveyear	;此函数结束,year的值移到table中的相应位置
	
	call revenue	;此函数结束,利润的值移到table中

	call employee	;此函数结束,员工数复制到table中

	call showstr	;显示所有信息
	
mov ax,4c00h
int 21h



;计算第四列的值,并将第四列的值存放在table段中
divsalary:
	push ax
	push bx
	push cx
	push dx
	push ds
	push si
	push di
	push es

	mov cx,21		;21次计算
      divs:
	push cx
	mov ax,ds:[si]	;低位在ax中
	mov dx,ds:[si+2]	;高位在dx中
	add si,4		;指向下一个dd型数据
	mov cx,ds:[di]
	div cx
;	div word ptr ds:[di]	;结果,得到需要的值在ax中
	add di,2		;指向下一个dw型数据

	call divDtoc

	pop cx
	loop divs

	pop es
	pop di
	pop si
	pop ds
	pop dx
	pop cx
	pop bx
	pop ax

	ret

    ;将divsalary内计算得到的薪水ax的值显示为十进制存放在table中的第四数值列
    divDtoc:
	push cx
	push si
	;进入此函数时未改变ax的值
	;由图知第四列最大值333=14DH,采用8位除法,不会溢出
	
	;8位除法,被除数ax中,结果AL商,AH余数
	;进入此函数时未改变ax的值,即ax就是被除数
	mov si,0
	mov bp,0
	mov cx,0
	mov dx,10
      divDtocs:
	div dl		;结果AL商,AH余数
	
	mov cl,al		;先把商保存在cl中
	mov al,0
	add ah,30h
	push ax		;把余数在栈中保存,但此时余数在高位,弹出时留意
	inc bp		;用bp对位数计数

	jcxz divDtocOver
	mov ax,cx		;覆盖AH的值,ch是零
	jmp short divDtocs
	
        divDtocOver:		;分离结束,准备存放
	mov cx,bp		;bp对位数计数,即push次数、需pop次数、循环次数
           divDtocOvers:
	pop ax
	mov es:[bx+si],ah
	inc si
	loop divDtocOvers
	add bx,32
	
	pop si
	pop cx
	ret


;此函数将db型年份从data段移到table段的相应位置,仅移动
moveyear:	
	push ax
	push bx
	push cx
;	push dx
;	push ds
	push si
	push di
;	push es	
	
	mov si,0	;ds未变,还是data段
	mov bx,0	;es未变,还是指向table段
	mov di,0

	mov cx,21		;21个数据
    yearwai:
	push cx
	mov cx,4
        yearnei:
	mov al,ds:[si]
	inc si
	mov es:[bx+di],al
	inc di
	loop yearnei

	add bx,32
	mov di,0
	pop cx
	loop yearwai

;	pop es
	pop di
	pop si
;	pop ds
;	pop dx
	pop cx
	pop bx
	pop ax

	ret


revenue:
;第二列收入转为十进制时,存在除法溢出问题,需要用公式
;X/N = int(H/N)*65536 + [rem(H/N)*65536+L]/N   N是除数,X是被除数,H是X高位,L是X低位
	push ax
	push bx
	push cx
	push dx
	push ds
	push si
	push di
	push es
	push bp
	
	mov ax,data
	mov ds,ax
	mov si,84		;全局变量

;	mov ax,temp
;	mov es,ax
;	mov di,0

	mov bx,8		;全局变量,table中第8列开始
	mov bp,0
	mov cx,21
revenuewai:
	push cx

	mov ax,temp
	mov es,ax

	mov ax,ds:[si]	;低位在ax中
	mov dx,ds:[si+2]	;高位在dx中
	add si,4
	
	;更新这两内存单元的值保证进入内层循环是分别存放计算的数据低、高位
	mov es:[0],ax	;es:[0]始终存放着要计算数据的低位
	mov es:[2],dx	;es:[2]始终存放着要计算数据的高位

         revenuenei:
	mov ax,es:[0]	
	mov dx,es:[2]

	mov ax,dx		;被除数:dx存放高位,ax存放低位
	mov dx,0
	mov cx,10
	div cx		;ax存放着商(高位),dx存放着余数
	
	mov es:[2],ax	;商的高位
	
	;对与右侧数据而言,余数dx的值为高位数据,L(原始被除数低16的值)
	mov ax,es:[0]	;此时右侧数据,dx高位,ax低位
	mov cx,10		;每次div前,临时使用cx作为除数
	div cx		;ax存放着商(低位),dx存放着余数
	
	add dx,30h
	push dx		;先将余数存起来
	inc bp		;计算余数的个数

	mov es:[0],ax	;商的低位
	
	mov cx,ax
	jcxz revenueneiOver
	jmp revenuenei

      revenueneiOver:
	mov ax,table
	mov es,ax
;	mov bx,bx
	mov di,0
	
	mov cx,bp		;原始数据的位数
	mov bp,0		;bp的值忘记清零造成了巨大错误
          revenueneiOvers:
	pop ax
	mov es:[bx+di],al
	inc di
	loop revenueneiOvers
	
	add bx,32

	pop cx
	loop revenuewai
	
	pop bp
	pop es
	pop di
	pop si
	pop ds
	pop dx
	pop cx
	pop bx
	pop ax	
	
	ret

		
;此函数将员工数复制到table中
;32位被除数除法运算,DX高位(0),AX低位,AX商,DX余数
employee:
	push ax
	push bx
	push cx
	push dx
	push ds
	push si
	push di
	push es
	push bp		
	
	mov ax,data
	mov ds,ax
	mov si,168
	
	mov ax,table
	mov es,ax
	mov bx,19
	mov di,0
	mov bp,0

	mov cx,21
employeewai:
	push cx
	mov cx,0
	mov ax,ds:[si]
	add si,2

      employeenei:
	mov dx,0
	mov cx,10
	div cx
	
	add dl,30h
	push dx
	inc bp
	
	mov cx,ax
	jcxz employeeneiOver
	jmp short employeenei
	
      employeeneiOver:
	mov cx,bp
          employeeneiOvers:
	pop ax
	mov es:[bx+di],al
	inc di
	loop employeeneiOvers
	
	add bx,32
	mov di,0
	mov bp,0
	pop cx
	loop employeewai


	pop bp
	pop es
	pop di
	pop si
	pop ds
	pop dx
	pop cx
	pop bx
	pop ax	
	
	ret	
	

;将所有信息显示出来
showstr:
	push ax
	push bx
	push cx
	push dx
	push ds
	push si
	push di
	push es
	push bp	
	
	mov ax,table
	mov ds,ax
	mov si,0

	mov ax,0b800h
	mov es,ax
	mov bx,160*2+24*2
	mov di,0

	mov ah,00000010b
	mov cx,21
       showwai:
	push cx

	mov cx,32
            shownei:
	mov al,ds:[si]
	inc si
	mov es:[bx+di],ax
	add di,2
	loop shownei

	add bx,160
	mov di,0
	pop cx
	loop showwai
	
	pop bp
	pop es
	pop di
	pop si
	pop ds
	pop dx
	pop cx
	pop bx
	pop ax	
	
	ret		
	
code ends
end start

此代码在DOSBox中的运行结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值