汇编语言——输入无符号、有符号的十进制数,存入BX,以十进制、十六进制输出

输入无符号的十进制数,存入BX

指令重点:

mul判断溢出

如果8位*8位=8位,无溢出,CF=OF=0;

如果8位*8位=16位,结果的高8位全为0,无溢出,CF=OF=0,

否则CF=OF=1。

算法核心:

bx*10+输入的字符

bx*10大于65535,溢出;

bx*10+输入的字符大于65535,溢出。

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

data segment
	string db 0dh,0ah,"overflow!",'$'
data ends
stack segment stack
	dw 100 dup (?)
	top label word
stack ends
code segment
	assume cs:code,ds:data,ss:stack
main proc far
	mov ax,data
	mov ds,ax
	mov ax,stack
	mov ss,ax
	lea sp,top
	
	mov bx,0			;bx清零
	mov si,10			;si为乘数/除数
	mov cx,0			;统计输入合法字符的个数

L1:		
	mov ah,7			;7号功能输入,不回显
	int 21h
	
	cmp al,0dh			;输入回车,以10进制显示输出bx
	je print
	cmp al,30h			;输入字符小于30h,重新输入
	jb L1
	cmp al,39h			;输入字符大于39h,重新输入
	ja L1
	
	mov dl,al			;合法字符,回显
	mov ah,2
	int 21h
	
	inc cx				;合法字符+1
	
	and dx,0fh			;屏蔽高12位,只留下低4位0-9
	mov ax,dx			
	
	xchg ax,bx			;交换ax,bx(因为mul默认在ax)
	mul si				;结果在(dx,ax)
	
	;判断溢出
	;乘法指令的CF和OF
	;如果8位*8位=8位,无溢出
	;如果8位*8位=16位,结果的高8位全为0,则CF=OF=0,否则CF=OF=1
	jc overflow			
	
	add bx,ax			;如果ax*10刚好等于65535,加上bx可能会溢出
	jc overflow
	jmp L1

;以10进制显示输出bx
print:
	cmp cx,0			;输入的合法字符为0,即一开始就敲了回车,直接退出
	je exit				
	
	;回车和换行
	mov dl,0dh
	mov ah,2
	int 21h
	
	mov dl,0ah
	mov ah,2
	int 21h
	
	mov cx,0			;统计余数个数
	mov ax,bx			;被除数(bx,ax)
	mov dx,0
L2:
	div si
	push dx				;余数进栈
	inc cx				;余数个数+1
	
	cmp ax,0			;商为0,跳转到L3
	je L3
	
	mov dx,0			;dx清零作为新的被除数
	jmp L2

L3:	
	pop dx
	add dl,30h			;转换成数字字符
	mov ah,2
	int 21h
	loop L3
	
	cmp cx,0			;跳过下面的overflow
	jmp exit

;溢出在屏幕上显示"overflow!"
overflow:	
	lea dx,string
	mov ah,9
	int 21h

exit:
	mov ah,4ch
	int 21h
main endp
code ends
	end main

输入带符号的十进制数,存入BX

输入的第一位可能是’+‘、’-'、数字,其他位都是数字。

实现的核心思想是:

输入的符号和数字分开,用一个寄存器记录输入的符号,bp=0为正数,bp=1为负数;

其他数字以无符号数的形式输入,范围为0-65535,判断溢出的方法跟上一题一样;

输完数字敲回车的时候,再去判断有符号数的溢出:

如果bp=1,即bx是负数,对bx求补,根据符号位判断溢出,bx求补的符号位为1,则无溢出;bx求补的符号位为0,则溢出;

如果bp=0,即bx是正数,根据符号位判断溢出,bx的符号位为0,则无溢出;bx的符号位为1,则溢出。

补充
求负数的二进制:对应正数的补码
最高位为1:负数
最高位为0:正数

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

data segment
	string db 0dh,0ah,"overflow!",'$'
data ends
stack segment stack
	dw 100 dup (?)
	top label word
stack ends
code segment
	assume cs:code,ds:data,ss:stack
main proc far
	mov ax,data
	mov ds,ax
	mov ax,stack
	mov ss,ax
	lea sp,top
	
	mov bx,0
	mov cx,0				;统计合法的数字字符个数
	mov si,10
	mov bp,0				;符号位默认为0(正数)

	mov ah,7				;输入第一个字符
	int 21h
	
	cmp al,0dh				;输入回车,退出
	je exit
	
	cmp al,'-'				;判断输入的第一个字符
	jne L1					;不是负号,跳转到L1继续判断
	mov bp,1				;输入负号,更改符号位
	
	mov dl,al				;显示负号
	mov ah,2
	int 21h
	
	jmp L2					;跳转到L2继续输入数字字符
	
L1:	
	cmp al,'+'
	jne L3					;不是正号,跳转到L3继续判断
	mov bp,0				;输入正号,更改符号位
	
	mov dl,al				;显示正号
	mov ah,2
	int 21h
	
	jmp L2					;跳转到L2继续输入数字字符
	
L2:
	mov ah,7
	int 21h
	
	cmp al,0dh				;输入回车,跳转到以10进制显示bx
	je print

L3:	
	cmp al,30h				;小于30h,继续输入
	jb L2
	cmp al,39h				;大于39h,继续输入
	ja L2
	
	mov dl,al				;显示合法的数字字符
	mov ah,2
	int 21h
	inc cx					;合法的数字字符+1
	
	and dx,0fh				;屏蔽dx高12位
	mov ax,dx
	
	xchg ax,bx				;交换ax和bx
	mul si					;ax*10
	
	;数字部分以无符号数输入
	;限制数字部分的输入范围0-65535
	jc overflow
	add bx,ax
	jc overflow
	
	jmp L2					;无溢出,跳转到L2继续输入数字字符
	
print:
	cmp cx,0				;判断合法的数字字符个数,cx为0退出
	je exit
	
	;接下来判断有符号数的溢出
	cmp bp,1				
	je negative				;判断负数的溢出
	
	cmp bp,0
	je positive				;判断正数的溢出

negative:
	neg bx					;bx是负数,求补
	add bx,0				;这条指令会改变psw,接下来判断符号位
	jns overflow			;符号位是0,溢出
	
	neg bx					;为了下面显示bx,要把bx还原
	
	;回车换行
	mov dl,0dh
	mov ah,2
	int 21h
	
	mov dl,0ah
	mov ah,2
	int 21h
	
	mov dl,'-'				;无溢出,显示字符数前加一个'-'
	mov ah,2
	int 21h
	
	jmp L4					;跳转到L4以10进制显示bx

positive:
	add bx,0				;bx是正数
	js overflow				;符号位是1,溢出
	
	;回车换行
	mov dl,0dh
	mov ah,2
	int 21h
	
	mov dl,0ah
	mov ah,2
	int 21h
	
	mov dl,'+'				;无溢出,显示字符数前加一个'+'
	mov ah,2
	int 21h
	
	jmp L4					;跳转到L4以10进制显示bx

L4:		
	mov cx,0				;余数个数
	mov ax,bx				;被除数(dx,ax)
	mov dx,0
	
L5:
	div si
	push dx					;余数进栈
	inc cx					;余数个数+1
	cmp ax,0				;商为0,退出
	je L6
	mov dx,0				;把dx清零作为新的被除数(dx,ax)
	jmp L5
	
L6:
	pop dx
	add dl,30h				;转换成数字字符
	mov ah,2
	int 21h
	loop L6
	cmp cx,0				;为了跳过下面的overflow
	jmp exit
		
overflow:
	lea dx,string
	mov ah,9
	int 21h

exit:
	mov ah,4ch
	int 21h
main endp
code ends
	end main	

输入一个有符号的十进制数,以十六进制输出

在这里插入图片描述

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

data segment
	string db 0dh,0ah,"overflow!",'$'
data ends
stack segment stack
	dw 100 dup (?)
	top label word
stack ends
code segment
	assume cs:code,ds:data,ss:stack
main proc far
	mov ax,data
	mov ds,ax
	mov ax,stack
	mov ss,ax
	lea sp,top
	
	mov bx,0
	mov cx,0				;统计合法的数字字符个数
	mov si,10
	mov bp,0				;符号位默认为0(正数)

	mov ah,7				;输入第一个字符
	int 21h
	
	cmp al,0dh				;输入回车,退出
	je exit
	
	cmp al,'-'				;判断输入的第一个字符
	jne L1					;不是负号,跳转到L1继续判断
	mov bp,1				;输入负号,更改符号位
	
	mov dl,al				;显示负号
	mov ah,2
	int 21h
	
	jmp L2					;跳转到L2继续输入数字字符
	
L1:	
	cmp al,'+'
	jne L3					;不是正号,跳转到L3继续判断
	mov bp,0				;输入正号,更改符号位
	
	mov dl,al				;显示正号
	mov ah,2
	int 21h
	
	jmp L2					;跳转到L2继续输入数字字符
	
L2:
	mov ah,7
	int 21h
	
	cmp al,0dh				;输入回车,跳转到以16进制显示bx
	je print

L3:	
	cmp al,30h				;小于30h,继续输入
	jb L2
	cmp al,39h				;大于39h,继续输入
	ja L2
	
	mov dl,al				;显示合法的数字字符
	mov ah,2
	int 21h
	inc cx					;合法的数字字符+1
	
	and dx,0fh				;屏蔽dx高12位
	mov ax,dx
	
	xchg ax,bx				;交换ax和bx
	mul si					;ax*10
	
	;数字部分以无符号数输入
	;限制数字部分的输入范围0-65535
	jc overflow
	add bx,ax
	jc overflow
	
	jmp L2					;无溢出,跳转到L2继续输入数字字符
	
print:
	cmp cx,0				;判断合法的数字字符个数,cx为0退出
	je exit
	
	;接下来判断有符号数的溢出
	cmp bp,1				
	je negative				;判断负数的溢出
	
	cmp bp,0
	je positive				;判断正数的溢出

negative:
	neg bx					;bx是负数,求补
	add bx,0				;这条指令会改变psw,接下来判断符号位
	jns overflow			;符号位是0,溢出	
	jmp L4					;跳转到L4以16进制显示bx

positive:
	add bx,0				;bx是正数
	js overflow				;符号位是1,溢出

L4:		
	mov cx,4
	
	mov dl,0dh
	mov ah,2
	int 21h
	
	mov dl,0ah
	mov ah,2
	int 21h
	
L5:
	push cx
	mov cl,4
	rol bx,cl
	mov dl,bl
	and dl,0fh
	cmp dl,9
	ja L6
	add dl,30h
	jmp L7

L6:
	add dl,37h
L7:	
	mov ah,2
	int 21h
	pop cx
	loop L5
	
	cmp cx,0
	je exit
		
overflow:
	lea dx,string
	mov ah,9
	int 21h

exit:
	mov ah,4ch
	int 21h
main endp
code ends
	end main	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值