王爽《汇编语言》实验10:编写子程序

前几个实验都没记录,实验10想记录一下!
问一下!markdown里汇编咋高亮啊,灰了吧唧好难看

1.显示字符串

名称:show_str
功能:指定位置,指定颜色,显示一个以数字0结束的字符串
参数:(dh)=行号,(dl)=列号,(cl)=颜色,ds:si->字符串
返回:无

;ds:si->字符串首地址
;dh行号 dl列号 cl颜色
;寄存器均不会被修改
show_str:	
	push es	
	push di
	push ax	
	push bx		
	push cx
	push dx		;将用到的寄存器入栈
	
	mov ax,0b800H
	mov es,ax
	xor ax,ax
	mov al,160
	mul dh		;8位乘
	xor dh,dh
	add dx,dx
	add ax,dx
	mov di,ax	;es:di->指定显示首地址

	mov al,cl	;cl即将被用作判断
	xor bx,bx
s0:	mov cl,ds:[si+bx]
	jcxz ok0	;若(cx)=0退出循环
	mov es:[di+0],cl	;写入要打印的字符
	mov es:[di+1],al	;写入要打印字符的颜色
	inc bx
	add di,2
	jmp s0

ok0:pop dx
	pop cx
	pop bx
	pop ax
	pop di
	pop es		;恢复被修改的寄存器
	ret

2.解决除法溢出的问题

名称:divdw
功能:32位除商不会溢出(余数自然不会溢出)
参数:(dx)(ax)=被除数,(cx)=除数
返回:(dx)(ax)=商,(cx)=余数

;(dx)=H,(ax)=L,(cx)=N
;(dx)(ax)/(cx)=(dx)(ax)
;(dx)(ax)%(cx)=(cx)
;除返回所用寄存器外,其他均不会被修改
divdw:
    push bx     ;将用到的寄存器入栈 

    mov bx,ax   ;(bx)=被除数低16位
    mov ax,dx
    xor dx,dx   ;(dx)(ax)=H
    div cx      ;32位除,(ax)=H/N,(dx)=H%N
    push ax     ;压入H/N
    mov ax,bx   ;(dx)(ax)=H%N*65536+L
    div cx      ;(ax)=(H%N*65536+L)/N
    mov cx,dx   ;(cx)=(dx)=余数
    pop dx      ;(dx)(ax)=
                ;   H/N*65536+(H%N*65536+L)/N
    pop bx      ;恢复被修改的寄存器
    ret

3.数值显示

(1)dtoc子程序

名称:dtoc
功能:将范围在0-65535的数据转化为十进制字符串,并添加数字0结尾
参数:(ax)=操作数据,ds:si->字符串
返回:无

;ds:si->字符串,(ax)=操作数据
;字符串结尾添加数字0
;寄存器均不会被修改
dtoc:	
	push ax	
	push bx		
	push dx		
	push cx
	push di		;将用到的寄存器入栈

	xor di,di	;di记录转化后字符串长度,方便ok1
s3:	mov bx,10
	xor dx,dx	;(dx)(ax)=操作数据 
	div bx
	mov cx,ax
	push dx		;将余数压入栈:若直接写入string段则为逆序
	inc di
	jcxz ok1
	jmp s3

ok1:mov cx,di
	xor bx,bx
s4:	pop ax
	add ax,30H	;将数字(0-9)转化为字符
	mov ds:[si+bx],al	;!注意,这里是al而不是ax
	inc bx
	loop s4

	mov ds:[si+bx],0	;结尾添加数字0

	pop di
	pop cx
	pop dx
	pop bx		
	pop ax		;恢复被修改的寄存器
	ret

(2)问题:编程,将data段数据以十进制显示

data segment
	dw 123,12666,1,8,3,38
data ends

代码如下:

assume cs:codesg,ds:data

data segment
	dw 123,12666,1,8,3,38
data ends

string segment
	db 'I am a happy space occupying sentence!'
string ends

stack segment
	dw 0,0,0,0,0,0,0,0
	dw 0,0,0,0,0,0,0,0	;栈空间:0-1fH
stack ends

codesg segment
start:
	mov ax,stack
	mov ss,ax
	mov sp,20H	;初始化栈
	
	mov ax,string
	mov ds,ax
	xor si,si	;ds:si->字符串

	mov ax,data
	mov es,ax
	mov di,di	;es:di->操作数据集

	mov dh,5
	mov dl,20
	mov cl,2	;准备show_str参数:5行20列绿色

	push cx		;记录颜色信息,cx即将被用作循环计数
	mov cx,6
	xor bx,bx
s1:	mov ax,es:[di+bx]	;准备dtoc参数
	call dtoc
	mov ax,cx	;ax暂存循环计数
	pop cx		;归还颜色信息给cx
	call show_str
	push cx
	mov cx,ax	;归还循环计数给cx
	inc dh		;下个操作数据将打印在下一行,偷个懒哈哈哈
	add bx,2
	call dtoc
	loop s1

	mov ax,4c00H
	int 21H
	
;ds:si->字符串,(ax)=操作数据
;字符串结尾添加数字0
;寄存器均不会被修改
dtoc:	
	push ax	
	push bx		
	push dx		
	push cx
	push di		;将用到的寄存器入栈

	xor di,di	;di记录转化后字符串长度,方便ok1
s3:	mov bx,10
	xor dx,dx	;(dx)(ax)=操作数据 
	div bx
	mov cx,ax
	push dx		;将余数压入栈:若直接写入string段则为逆序
	inc di
	jcxz ok1
	jmp s3

ok1:mov cx,di
	xor bx,bx
s4:	pop ax
	add ax,30H	;将数字(0-9)转化为字符
	mov ds:[si+bx],al	;!注意,这里是al而不是ax
	inc bx
	loop s4

	mov ds:[si+bx],0	;结尾添加数字0

	pop di
	pop cx
	pop dx
	pop bx		
	pop ax		;恢复被修改的寄存器
	ret

;ds:si->字符串首地址
;dh行号 dl列号 cl颜色
;寄存器均不会被修改
show_str:	
	push es	
	push di
	push ax	
	push bx		
	push cx
	push dx		;将用到的寄存器入栈
	
	mov ax,0b800H
	mov es,ax
	xor ax,ax
	mov al,160
	mul dh		;8位乘
	xor dh,dh
	add dx,dx
	add ax,dx
	mov di,ax	;es:di->指定显示首地址

	mov al,cl	;cl即将被用作判断
	xor bx,bx
s0:	mov cl,ds:[si+bx]
	jcxz ok0	;若(cx)=0退出循环
	mov es:[di+0],cl	;写入要打印的字符
	mov es:[di+1],al	;写入要打印字符的颜色
	inc bx
	add di,2
	jmp s0

ok0:pop dx
	pop cx
	pop bx
	pop ax
	pop di
	pop es		;恢复被修改的寄存器
	ret
codesg ends

end start

运行结果如下:
运行结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值