汇编上机-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

浙公网安备 33010602011771号