用子程序形式编写:
A*B:从键盘输入a和b,计算A*B,其中乘法采用移位和累加完成
源代码:
data segment
mul1 db 16,?,16 dup(?)
mul2 db 16,?,16 dup(?)
buff1 db 'Please input mul1: $'
buff2 db 'Please input mul2: $'
buff3 db 'The consequense is : $'
data ends
code segment
assume cs:code,ds:data
main proc far ; main program
mov ax,data
mov ds,ax
push ds
xor ax,ax ;push ds and es and ax=0
call tips1 ;提示用户输入第一个数
call input1 ;在缓冲区接收
call tips2 ;提示用户输入第一个数
call input2 ;在缓冲区接收
lea si,mul1+2 ;开始将第一个数10进制转换成2进制
call dtob
push bx ;压栈保存第一个数的2进制
lea si,mul2+2
call dtob ;开始将第一个数10进制转换成2进制
mov dx,bx ;dx中装的是第二个数的二进制
pop bx ;bx中装的是第一个数的二进制
call multiple ;调用乘法子程序
call tips3 ;提示结果输出
call btod ;将结果的二进制转换成十进制输出
mov ah,4ch
int 21h
ret
main endp
;-----------------------------------------------------------
tips1 proc near
mov dx,offset buff1
mov ah,9
int 21h
ret
tips1 endp
;------------------------------------------------------------
input1 proc near
lea dx,mul1
mov ah,0ah
int 21h
mov dl,13
mov ah,2
int 21h
mov dl,10
mov ah,2
int 21h
ret
input1 endp
;--------------------------------------------------------------
tips2 proc near
mov dx,offset buff2
mov ah,9
int 21h
ret
tips2 endp
;-----------------------------------------------------------
input2 proc near
lea dx,mul2
mov ah,0ah
int 21h
mov dl,13
mov ah,2
int 21h
mov dl,10
mov ah,2
int 21h
ret
input2 endp
;--------------------------------------------------------------
dtob proc near
mov bx,0
getnum:
mov al,byte ptr [si] ;用al保存第一个字符
sub al,30h
jl exit1
cmp al,9
jg exit1
cbw
xchg ax,bx
mov dx,10
mul dx
xchg ax,bx
add bx,ax
inc si ;循环,如果遇到的不是0~9的数就自动跳出程序
jmp getnum
exit1: ret
dtob endp
multiple proc near
mov bp,0 ;用bp寄存器保存结果
start:
shr dx,1 ;右移第二个乘数,判断CF的值,如果是1就进行加法操作,如果是0就继续右移
jc addition
shl bx,1 ;第一个乘数左移
cmp dx,0 ;当第二个数为0是结束
jz exit2
jmp start
addition:
add bp,bx ;将相加结果保存在BP寄存器中
shl bx,1
jmp start
exit2 :ret
multiple endp
btod proc near
mov ax, bp ;把bp寄存器的值给ax
mov cx, 1 ;计数器
mov bl, 10 ;10作除数
div1:
idiv bl
push ax ;保存ax/10后的结果,ah存放余数,al存放商
cmp al, 0 ;商为0则开始输出
jz output
mov ah, 0 ;置余数为0,继续除
inc cx
jmp div1
output:
pop dx
mov dl, dh ;出栈输出余数
add dl, 30h
mov ah, 2
int 21h
loop output
ret
btod endp
tips3 proc near
mov dx,offset buff3
mov ah,9
int 21h
ret
tips3 endp
code ends
end main
运行结果:
这次的实验有一个很困惑我的地方就是我一开始弄错了,以为我们用户能用的寄存器只有AX,BX,CX,DX这四个,所以我一直拿缓冲区的内存当作一个寄存器来回使用,这对我进行数的操作造成了很大的不便,此外我的移位操作乘法,设计的很麻烦,一开始总是想用一个寄存器保存第二个乘数的1的位权,这就遇到了我上面说的寄存器不够的情况,后来在老师的帮助下,我改进了算法,只要判断右移的第二个乘数CF位是0,还是1,如果是1就把AX左移的结果加进来,AX的值无需保存,只要最后把结果放进BP寄存器就可以了。通过这次实验,我收获了很多。