汇编语言 实验四 子程序结构

本文详细介绍了如何使用汇编语言实现加法计算器,涉及子程序结构、十进制输入输出、加法运算及用户输入验证。通过实例演示了decibin和binidec子程序,以及主程序的编写过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验四 子程序结构

【实验目的】

1.掌握子程序结构
2.掌握如何输入输出十进制数字

【实验要求】

编写程序,在程序中设置两个加数,显示加法算式,用户输入运算结果,给出正确与否的信息。
提示:
1)显示十进制数据:p227 binidec
2)输入十进制数据:p200 decibin

【思考】

以为十进制好输入输出,实际上在汇编语言中还是得分成一位一位的,我以为在前三次上机里面是有过输入输出的,结果一看全是输出字符和字符串等,那么我们需要跟上次输出十六进制一样需要一位一位看,这里是不需要滚动的,因为我们正好是从左往右读的,直接输出即可。

【如何输入十进制】

步骤

我们将思路拆分成以下几个步骤:
1)读入一个字符
2)将字符减去48成为对应的数字,也就是30H
3)判断是否小于零和大于9,如果是的话就ret
4)用BX专门每次乘以10再加上AX

注意

在这里我们需要注意:
1)读入的字符数值是在AL中,我们需要用cbw指令将AL扩充至AX
2)我们得到的值和进行乘以10的操作都是AX寄存器中进行的,我们在对于BX乘以10的时候首先需要交换AXBX,用到xchg ax,bx指令
3)在退出的时候需要重新设置一个exit,不能直接写retjmp不能跳转到ret

decibin	proc	near
;从键盘输入一个十进制数,存入BX寄存器中
	mov	bx,0
getchar:
	mov 	ah,01h
	int	21h		;读入字符
	sub	al,30h	;减去30H,成为对应数字
	jl	exit		;如果小于0的话,就exit退出
	cmp	al,9d	;与9相比
	jg	exit	;如果大于9就退出
	cbw			;将al扩充至ax
	mov	cx,10	;给cx设置为10进行乘法操作
	xchg ax,bx	;交换ax,bx,因为乘法是在ax中完成的
	mul	cx
	add	bx,ax	;乘以10之后加上
	jmp	getchar	;重新回到getchar再次进行
exit:
	ret
decibin	endp

【如何输出十进制】

步骤

这里按照书上给出的,需要输出五位
1)将除数从10000、1000…1的顺序设置放入cx中,被除数放入bx中,每次进行dec_div从左往右一位一位输出
2)因为div cx指令是以ax为被除数,cx为除数,然后将余数放入dx中,商在al中,所以我们需要将余数dx放入bx中,以便后面继续除以,bx一直存的被除数,将商al放入dl中输出,因为输出指令是需要放入dl中才输出的
简略的步骤如下:
1)设置cx进入输出程序
2)除以cx
3)余数dx放入bx中(bx一直存被除数)
4)将商al放入dl中输出
5)返回

binidec	proc	near
;把BX寄存器中的数以十进制数的形式在屏幕上显示出来
	mov	cx,10000d
	call	dec_div
	mov	cx,1000d
	call	dec_div
	mov	cx,100d
	call	dec_div
	mov	cx,10d
	call	dec_div
	mov	cx,1d	;每次这样设置可以从左到右分为每一位处理
	call	dec_div
	ret
binidec	endp
;------------------------------
dec_div	proc	near
;除法运算:(bx)/(cx)
;入口参数:(bx)=被除数,(cx)=除数
;出口参数:(bx)<--余数,商显示
	mov	ax,bx	;被除数给ax,div的指令要求
	mov	dx,0	;dx置零
	div	cx		;除以cx
	mov	bx,dx	;余数给bx,成为下一次的被除数
	mov	dl,al	;al给dl输出,int指令要求是放入dl输出
	add	dl,30h	;+30H成为字符
	mov	ah,02h	;输出字符
	int	21h
	ret			;返回
dec_div	endp

【主程序】

main	proc	far
	assume	cs:code,ds:data
start:
	;段地址送段寄存器
	mov	ax,data
	mov	ds,ax
	
	;加法计算,结果存入result
	mov	ax,oper1	;将12放入ax中
	mov	bx,oper2	;将45放入bx中
	add	ax,bx		;相加 12+45
	mov	result,ax	;result存答案45
	
	;显示算式
	mov	bx,oper1	;12放入bx中输出
	call	binidec	;输出bx
	
	mov	al,2bh		;ASCII中'+'是2BH
	mov	dl,al		;al放入dl才能输出
	mov	ah,02h		;输出加号+
	int	21h
	
	mov	bx,oper2	;45放入bx中输出
	call	binidec	;输出45
	
	mov	al,3dh		;ASCII中'=是3DH
	mov	dl,al		;放入dl才能输出
	mov	ah,02h
	int	21h
	
	;用户输入运算结果,存入(bx)寄存器中
	call	decibin	;读入放入bx中
	
	;判断用户输入是否正常,并显示信息
	;根据以上程序bx是读入的
	mov ax,result	;ax放入result中
	cmp	ax,bx		;比较ax与bx
	jz	right		;jz:如果为0,那么就跳转right步骤,否则继续向下指向wrong
wrong:
	lea	dx,wrong_msg	;将wrong_msg字符串偏移地址给dx准备输出
	jmp	return		;返回到下面return中,这样可以跳过right指令
right:
	lea	dx,right_msg	;将right_msg字符串偏移地址给dx准备输出
	jmp return		;可以不写,为了好看我还是写了
return:
	mov	ah,09h		;通过dx输出字符串
	int	21h

	mov	ax,4c00h	;结束
	int	21h
main	endp

【总程序】

;-------------------------------
data	segment
	oper1	dw	12
	oper2	dw	45
	result	dw	?
	right_msg db	'right',0dh,0ah,'$'
	wrong_msg db	'wrong',0dh,0ah,'$'
	crlf	db	0dh,0ah,'$'
data	ends
;===================================
code	segment
;------------------------------------------------------------
main	proc	far
	assume	cs:code,ds:data
start:
	;段地址送段寄存器
	mov	ax,data
	mov	ds,ax
	;加法计算,结果存入result
	mov	ax,oper1
	mov	bx,oper2
	add	ax,bx
	mov	result,ax
	;显示算式
	mov	bx,oper1
	call	binidec
	mov	al,2bh
	mov	dl,al
	mov	ah,02h
	int	21h
	mov	bx,oper2
	call	binidec
	mov	al,3dh
	mov	dl,al
	mov	ah,02h
	int	21h
	;用户输入运算结果,存入(bx)寄存器中
	call	decibin
	;判断用户输入是否正常,并显示信息

	;bx是读入的,ax存result
	
	mov 	ax,result
	cmp	ax,bx
	jz	right
wrong:
	lea	dx,wrong_msg
	jmp	return
right:
	lea	dx,right_msg
	jmp 	return
return:
	mov	ah,09h
	int	21h

	mov	ax,4c00h
	int	21h
main	endp
;------------------------------
binidec	proc	near
;把BX寄存器中的数以十进制数的形式在屏幕上显示出来
	mov	cx,10000d
	call	dec_div
	mov	cx,1000d
	call	dec_div
	mov	cx,100d
	call	dec_div
	mov	cx,10d
	call	dec_div
	mov	cx,1d
	call	dec_div
	ret
binidec	endp
;------------------------------
dec_div	proc	near
;除法运算:(bx)/(cx)
;入口参数:(bx)=被除数,(cx)=除数
;出口参数:(bx)<--余数,商显示
	mov	ax,bx
	mov	dx,0
	div	cx
	mov	bx,dx
	mov	dl,al
	add	dl,30h
	mov	ah,02h
	int	21h
	ret
dec_div	endp
;------------------------------
decibin	proc	near
;从键盘输入一个十进制数,存入BX寄存器中
	mov	bx,0
getchar:
	mov 	ah,01h
	int	21h
	sub	al,30h
	jl	exit
	cmp	al,9d
	jg	exit
	cbw		;将al扩充至ax
	mov	cx,10
	xchg	ax,bx
	mul	cx
	add	bx,ax
	jmp	getchar
exit:
	ret
decibin	endp
;--------------------------------
code	ends
;===================================
	end	start

注意其他细节不能丢,如ret,ends,end start

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值