《汇编语言》(王爽)学习笔记---实验十(编写子程序)

1.显示字符串

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
先说明一点,本次编程,发现了书中错误之处,书中在讲解MUL指令时,两个相乘的数,如果是8位,一个默认应该存储在AL中,书中错写成AH。导致笔者在编写程序时错误使用AH。。。特此纠正。。

思路简单,就是定位显存缓冲区位置,然后把对应字符送到该位置即可。

assume cs:code

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

stack segment
	dw 8 dup(0)
stack ends

code segment
	start:
		  mov dh,8	;显存页对应的行
		  mov dl,3	;显存页对应的列
		  mov cl,2	;字符属性,这里是绿色
		  mov ax,stack
		  mov ss,ax
		  mov sp,16
		  mov ax,data
		  mov ds,ax
		  mov si,0	;data数据偏移地址
		  call show_str	;调用显示字符子程序
		  
	all:
		  jmp short all	;一直循环,为了看效果
		  
		  mov ax,4c00h
		  int 21h
		  
	show_str:
		  push ax	;把子程序中使用到的寄存器值入栈
		  push es
		  push dx
		  push bx
		  push si
		  push di
		  
		  mov ax,0b800h	;显存缓冲区段地址
		  mov es,ax
		  
		  mov al,160	;计算行上的偏移量
		  mul dh
		  mov bx,ax
		  
		  mov al,2	;计算列上的偏移量
		  mul dl
		  add bx,ax	;得到最终偏移地址,存入bx
		  
		  mov di,0	;辅助计算显存对应的偏移地址
		  mov al,cl	;把cl中字符属性值存入al。
		  mov ah,0	;后面还要用cl判断当前字符是否是0
		  
	show:
		  mov cl,ds:[si]	;把单个字符存入cl
		  jcxz ok
		  mov es:[bx+di],cl
		  mov es:[bx+di+1],al
		  inc si
		  add di,2
		  jmp short show
		
	ok:
		  pop ax	;把子程序中使用到的寄存器值还原
		  pop es
		  pop dx
		  pop bx
		  pop si
		  pop di
		  ret
code ends
end start

在这里插入图片描述

2.解决除法溢出的问题

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

assume cs:code

code segment
start:
	mov ax,4240h
	mov dx,000fh
	mov cx,0Ah
	call divdw
	mov ax,4c00H
	int 21h
divdw:
	push ax
	mov ax,dx
	mov dx,0
	div cx
	mov bx,ax
	pop ax
	div cx
	mov cx,dx
	mov dx,bx
	ret    
code ends
end start

3.数值显示

计算机里存储的二进制数字,转换成十进制,并显示在屏幕指定位置。

assume cs:code

data segment
	db 10 dup(0)
data ends

code segment
	start:
		  mov ax,12666
		  
		  mov bx,data
		  mov ds,bx
		  mov si,0	;data数据偏移地址
		  call dtoc
		  
		  mov dh,8	;显存页对应的行
		  mov dl,3	;显存页对应的列
		  mov cl,2	;字符属性,这里是绿色
		  call show_str	;调用显示字符子程序
		  
	all:
		  jmp short all	;一直循环,为了看效果
		  
		  mov ax,4c00h
		  int 21h
		  
	dtoc:
		  push si
		  push dx
		  push cx
		  push bx
		  push ax
			
		  mov si,0
		  mov bx,10	;除10取余,转为10进制
	change:
		  mov dx,0
		  div bx
		  mov cx,ax	;商存入cx,便于使用jcxz
		  jcxz last
		  add dx,30h	;转为ASCII对应的数字
		  push dx
		  inc si	;统计余数个数,便于后续循环
		  jmp short change
	last:			;最后一次除法
		  add dx,30h
		  push dx
		  inc si
		  
		  mov cx,si
		  mov si,0
		  
	s:
		  pop ds:[si]
		  inc si
		  loop s
		  
	exit_dtoc:
		  pop ax
		  pop bx
		  pop cx
		  pop dx
		  pop si
		  ret
		
	show_str:
		  push ax	;把子程序中使用到的寄存器值入栈
		  push es
		  push dx
		  push bx
		  push si
		  push di
		  
		  mov ax,0b800h	;显存缓冲区段地址
		  mov es,ax
		  
		  mov al,160	;计算行上的偏移量
		  mul dh
		  mov bx,ax
		  
		  mov al,2	;计算列上的偏移量
		  mul dl
		  add bx,ax	;得到最终偏移地址,存入bx
		  
		  mov di,0	;辅助计算显存对应的偏移地址
		  mov al,cl	;把cl中字符属性值存入al。
		  mov ah,0	;后面还要用cl判断当前字符是否是0
		  
	show:
		  mov cl,ds:[si]	;把单个字符存入cl
		  jcxz exit_show_str
		  mov es:[bx+di],cl
		  mov es:[bx+di+1],al
		  inc si
		  add di,2
		  jmp short show
		
	exit_show_str:
		  pop ax	;把子程序中使用到的寄存器值还原
		  pop es
		  pop dx
		  pop bx
		  pop si
		  pop di
		  ret
code ends
end start

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值