《汇编语言》王爽——第十章实验10.2 10.3

10.2 解决除法溢出的问题

给出的公式:X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N

参数: ax存放被除数低16 dx存放被除数高16 cx存放除数
分析:

 *65536相当于进到高16位  rem(H/N)*65536不用算,因为算H/N的时候已经把这个结果算出来了,存放在dx,相当于只要计算H/N 和L/H
 

完整代码:

assume cs:code,ss:stack
stack segment
dw 10 dup(0)
stack ends 

code segment
start: 
mov ax,stack
mov ss,ax 
mov sp,20

mov ax,4240h
mov dx,0fh
mov cx,0ah
call divdw 

mov ax,4c00h
int 21h

divdw:

;X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N
;分析 *65536相当于进到高16位  rem(H/N)*65536不用算,因为算h/n的时候已经把这个结果算出来了,存放在dx,相当于只要计算h/n 和l/n
;ax存放被除数低16 dx存放被除数高16 cx存放除数
		push ax 
		
		mov ax,dx ;取出高16位
		
		mov dx,0  ;被除数高16位置0,因为要计算H/N
		
		div cx    ;int()H/N 商结果存放ax,余数结果存放dx,一切都是那么的恰到好处
		
		mov bx,ax ;存放结果
		
		pop ax    ;取出低16位
		
		div cx    ;L/N  商ax 余数dx 
		
		mov cx,dx ;存储余数
		
		mov dx,bx ;存储低16位
			
        ret

code ends 
end start

实验10.3 数值显示

这里要用到前面的子程序showptr(显示以0结尾字符串在显示器上),将数值显示出来。

我们也需要写一个通用的小程序dtoc,用来将数据转化为10进制的ASCII码

算法规则:

12345/10=1234 余数5  --> 5+30H=35H  入栈

1234/10=123 余数4      -->4+30H=34H  入栈

123/10=12 余数3          -->3+30H=33H  入栈

12/10=1 余数2              -->2+30H=32H  入栈

1/10=0  余数1               -->1+30H=31H  入栈  到此结束计算

然后统统出栈到data段之中就可以了。

最后再调用showptr小程序就可以显示到屏幕上了.

完整代码:

assume cs:code,ds:data,ss:stack
data segment
db 20 dup(0)
data ends
stack segment
dw 20 dup(0)
stack ends 

code segment
start:
mov bx,data
mov ds,bx
mov bx,stack
mov ss,bx
mov sp,40

mov ax,12345
mov si,0

call dtoc 	;将word型数据转变成十进制字符串,字符串以0结尾,存放于data段

mov dh,12
mov dl,64
mov cl,02h
mov si,0
call showptr ;显示字符串 dh是行,dl是列,cl是颜色,ds:si指向字符串首地址

mov ax,4c00h
int 21h

dtoc:
push ax
push bx
push cx
push dx
push di
push si

mov bx,10;除数为10
mov di,0 ;计数器置0

s0:
mov dx,0 ;被除数高位置0
div bx   ;做除法 dx存放余数 ax存放商


add dx,30h ;余数加30h
push dx    ;存放ascii码,入栈
inc di     ;计数器加1
;判断商是否为0
mov cx,ax 
jcxz dtoc_ok
jmp short s0 ;跳转回去继续做除法直到商为0

dtoc_ok:
;inc di 
mov cx,di  ;计数器存进cx做循环
;inc cx 
s2:
pop ds:[si];出栈 弹出到data空间
inc si     ;指针后移
loop s2    ;结束循环表示出栈成功
;归还寄存器
pop si 
pop di
pop dx 
pop cx 
pop bx 
pop ax 
ret

showptr: ;将用到的寄存器统统存储一遍,后续结束小程序时全部返还
push di
push dx
push cx
push si 
push ds 
push es
push ax


show:
;将字符串显示在屏幕上,dh是行,dl是列,cl是颜色,ds:si指向字符串首地址
;1.首先计算显存位置
sub dh,1  		;dh减一
mov al,dh 		;做乘法运算
mov ah,160
mul ah   		;行数减一乘以160 最后将结果ax加上dl即可
mov dh,0
add ax,dx 		;ax此时存放写入的地址位置
mov di,ax 		;作为显存指针使用
mov ax,0b800h
mov es,ax		;将显存地址写入es

;2.确定颜色属性
mov dh,cl 		;将颜色属性赋值高位过去

;3.写入字符串,ds:si指向字符串首地址,需要将字符串存放到dl中
show0:
;这里要利用jcxz了
mov ch,0
mov cl,ds:[si]
jcxz show_ok 
mov dl,ds:[si] 	;获取字符串字节
mov es:[di],dx  ;将dx写入到es:[di]中去 也就是显存地址
inc si 			;字符串指针后移
add di,2		;显存地址后移
jmp short show0 ;跳转回去

show_ok:;出口
pop ax
pop es 
pop ds 
pop si 
pop cx 
pop dx 
pop di 
ret
code ends
end start 

效果如下图 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值