ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-10-16 14:31:46  阅读:170  来源: 互联网

标签:10.3 10.2 mov pop cx dx push ax 王爽


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 

效果如下图 

 

标签:10.3,10.2,mov,pop,cx,dx,push,ax,王爽
来源: https://blog.csdn.net/Onthr/article/details/120798081

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有