汇编上机-04

【题目】

  编写汇编程序,在程序中设置两个加数,显示加法算式,用户输入运算结果,给出正确与否的信息。

  {提示: 1) 显示十进制数据:书p227 binidec 2) 输入十进制数据:书p200 decibin}

【分析】

   其实这个程序的难点在于10进制的输入和输出!因为相对于01、02、03来说,前面的输入输出都是字符或者字符串,没有考虑到字符转换的问题。

  书上其实给出了很详细的例子,所以这里给出的也是书上的提炼。

  本人技艺不精,如有错误还请指出。

>>>代码部分

 利用封装的思想,将输入和输出抽离出来成为子程序,以简化主程序

1.输入十进制

  我们首先可以知道,(目前已学)汇编要么直接输入字符串,要么直接输入字符(是不是有点C++快速读入的感觉)

  我们采用依次输入字符,将字符转化为数字,在利用“p=p*10+a”的原理,将输入的字符转换为数字

步骤:

  • 输入字符
  • 将该字符-30h
  • 判断该字符是否在数字的范围内,若否则判断为输入别的字符,停止字符转数字的操作,转向ret
  • 是则利用bx保存最终的结果

下见代码

decibin proc near
;从键盘输入一个十进制数,存入BX寄存器
	mov bx,0    ;将bx清空,用于保存数据
newchar:
	mov ah,01h
	int 21h    ;步骤一
	sub al,30h  ;步骤二
	jl exit
	cmp al,09h
	jg exit    ;步骤三
	cbw      ;ax中为目前输入的数值
	xchg ax,bx  ;将ax中的数与bx交换,目的是将原本存在bx中的数扩大10倍
	mov cx,0ah  
	mul cx
	xchg ax,bx  ;换回来,bx扩大了10倍,ax不变
	add bx,ax   ;步骤四
	jmp newchar
exit:
	ret
decibin endp

2.输出十进制

难点在哪呢? 你怎么将一个寄存器里面的数用十进制输出?其实和二进制、十六进制的输出相同,输出十进制依旧是输出字符,只不过我们需要将基数作为10,找出每个数位上的数字,从前往后输出即可

步骤

  • 将除数按照10000、1000、...、1的顺序放入cx中,被除数放在bx中不动,每次进行dec_div时从左往右一位一位输出
  • 除出的商直接输出,余数放在bx中,其实就是将每个数按照10的倍数分解,依次输出

下见代码

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    ;ax里面al即够用本题的余数,所以仅考虑al即可,不用考虑ah
	add dl,30h
	mov ah,02h
	int 21h
	ret
dec_div 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
	assume cs:code,ds:data
main proc far

start:
	;段地址送段寄存器
	mov ax, data
	mov ds,ax
	;加法计算,结果存入result
	mov ax,oper1
	add ax,oper2
	mov result,ax
	;显示算式
	mov bx,oper1
	call binidec
	mov ah,02h
	mov dl,2bh
	int 21h
	mov bx,oper2
	call binidec
	mov ah,02h
	mov dl,3dh
	int 21h
	;用户输入运算结果,并显示信息
	call decibin
	mov ah,09h
	lea dx,crlf
	int 21h
	;判断用户输入是否正确,并显示信息
	cmp bx,result
	jz right
	lea dx,wrong_msg
	jmp output
right:
	lea dx,right_msg
output:
	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
newchar:
	mov ah,01h
	int 21h
	sub al,30h
	jl exit
	cmp al,09h
	jg exit
	cbw
	xchg ax,bx
	mov cx,0ah
	mul cx
	xchg ax,bx
	add bx,ax
	jmp newchar
exit:
	ret
decibin endp
	
code ends

end start

  

 

posted on 2022-11-21 08:59  Qiansui  阅读(34)  评论(0编辑  收藏  举报