汇编语言 王爽 第三版 实验十

╄→гoц情女王★ 提交于 2020-01-28 20:38:24

实验10 三题 对跳转指令的巩固

显示字符串
解决除法溢出
数值显示

显示字符串

题目要求

在这里插入图片描述

题目分析

实验9中代码改为一个接口
行对应地址为 行数 X A0
列对应地址为 (列数 X 2) H

代码
assume cs:code, ds:data

data segment
	db 'Welcome to Masm!',0
data ends

code segment
start:
	mov dh,8
	mov dl,3
	mov cl,2
	mov ax,data
	mov ds,ax
	mov si,0
	call show_str
	
	mov ax,4c00h
	int 21h
	show_str:
		mov ax,0b800h
		mov es,ax
		mov bh,dh
		mov bl,dl
		
		mov ax,0a0h
		mul bh	
		mov si,ax	;行
		
		mov ax,2
		mul bl	
		mov di,ax	;列
		
		add si,di
		mov bx,si
		mov si,0
		mov di,0
	
		s:	
			push cx
			mov cl,ds:[si]
			jcxz ok
			
			mov al,ds:[si]	;字符及属性
			pop cx
			mov ah,cl
			mov es:[bx+di],ax
			inc si
			add di,2
			jmp short s
	
		ok:
			pop cx
			ret
	
code ends
end start
结果

在这里插入图片描述

问题

题目用dx存储行列信息 但是再运算乘法的时候,dx被默认存储结果高位
所以要注意dx先赋值 再运算

cx规定存储字体属性信息 由于目前学到的内容只能用jcxz来判断最后一位是否为0
所以要用栈控制cx的值

解决除法溢出

题目要求

在这里插入图片描述
在这里插入图片描述

题目分析

根据题目给出的提示运算1000000/10 即F4240H/AH
高位为dx = fh 低位ax = 4240h
除数cx = a
X/N = int(dx/cx) * 10000h+[rem(dx/cx) * 10000h+ax]/cx
代入可得答案

32位除法被分解为16位的除 乘 除 乘 加 除 加
其中第一三步为同一操作的不同结果 写在一个段里即可
注意到乘10000H时 低位恒等于0 高位恒等于被乘数 所以ax dx均不需要入栈操作

在运算乘除时需要用到ax与整体上的ax冲突
所以需要用到栈

代码

为了方便分析 注释由题目数据给出
测试数据为987654321/15056
结果为1003E…2A51

assume cs:codesg,ss:stack

stack segment
	dw 8 dup(0)
stack ends

codesg segment
start:
	mov ax,stack
	mov ss,ax
	mov sp,16
	mov ax,68b1h
	mov dx,3adeh
	mov cx,0ffffh
	
	call divdw	;第一个入栈的是ip
	mov ax,4c00h
	int 21h
	
	divdw:
		push ax
		mov ax,dx
		mov dx,0
		div cx	;/ ax为X/N的商1 dx为余数5
		
		mov bx,ax	;商高位
		pop ax
		div cx
		mov cx,dx
		mov dx,bx
		ret
codesg ends
end start
结果

在这里插入图片描述

问题

第一个入栈的是call执行后的ip

汇编中如2/3 ax为0 dx为2
这就导致当字型数据高位>除数时 得不到正确结果

数值显示

题目要求

在这里插入图片描述
在这里插入图片描述

题目分析

根据题目所给提示
1.用求余方法确定每位值
2.加上30H位对应ascii码
3.JCXZ判断

代码
assume cs:codesg,ds:datasg

datasg segment
db 10 dup(0)
datasg ends

codesg segment
start:
	mov ax,12666
	mov bx,datasg
	mov ds,bx
	mov si,0
	call dtoc
	
	mov dh,8
	mov dl,3
	mov cl,2
	
	call show_str
	mov ax,4c00h
	int 21h

	dtoc:
		mov dx,0	;初始化
		mov bx,0ah
		div bx
		add dx,30h
		mov ds:[si],dl
		mov dx,0
		inc si
		mov cx,ax
		jcxz finsh
		jmp short dtoc
		
		finsh:
			mov dx,si
			mov cx,dx
			mov si,0
			s1:
				mov bl,ds:[si]	;栈一次传一个字节
				push bx
				inc si
				loop s1
			mov cx,dx
			mov si,0
			s2:
				pop ds:[si]
				inc si
				loop s2
			ret
		
	show_str:
		mov ax,0b800h
		mov es,ax
		mov bh,dh
		mov bl,dl
		
		mov ax,0a0h
		mul bh	
		mov si,ax	;行
		
		mov ax,2
		mul bl	
		mov di,ax	;列
		
		add si,di
		mov bx,si
		mov si,0
		mov di,0

		s:	
			push cx
			mov cl,ds:[si]
			jcxz ok
			
			mov al,ds:[si]	;字符及属性
			pop cx
			mov ah,cl
			mov es:[bx+di],ax
			inc si
			add di,2
			jmp short s

		ok:
			pop cx
			ret
codesg ends
end start
结果

在这里插入图片描述

问题

算每位值的时候存储顺序是逆的 要用栈排正

用栈传递字节的时候还是只赋值低位比较好,这样看的也比较清晰

dtoc中用了除法 但是在主代码段中没有给dx赋值,导致debug正常 运行出错
在编写程序时要检查寄存器的初始化

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!