我的任务是编写一个MASM x86汇编程序,它通过位移将两个16位数相乘/除。到目前为止我所拥有的是:
INCLUDE Irvine32.inc
.data
count BYTE -1
val1 SDWORD ?
val2 SDWORD ?
str1 BYTE "Enter Integer 1 here: ",0 ;
str2 BYTE "Enter Integer 2 here: ",0
str3 BYTE "The product is: ",0
mval WORD ?
mval2 WORD ?
pval WORD ?
.code
call clrscr
main PROC
mov dh,10
mov dl,20
call Gotoxy
mov edx, OFFSET str1
call WriteString
call ReadInt
mov mval,ax
mov dh,12
mov dl,20
call Gotoxy
mov edx, OFFSET str2
call WriteString
call ReadInt
mov mval2,ax
mov dh, 14
mov dl, 20
call Gotoxy
mov edx, OFFSET str3
call WriteString
mov ax,pval
call WriteInt
call crlf
call waitmsg
mov eax,0
mov ax,mval2
mov ecx, 16
L1:
shr bx,1
INC count
JNC DontAdd
push ecx
mov ax,mval
mov cl,count
shl dx,cl
add ax,dx
pop ecx
DontAdd:
LOOP L1
call waitmsg
exit
main ENDP
END main
如何正确实现按位乘法/除法?
答案 0 :(得分:0)
您处于某种程度,您应该使用程序来跟踪代码。看看这个32位示例并将其转换为16位:
INCLUDE Irvine32.inc
.data
First DWORD ?
Second DWORD ?
Result DWORD ?
GetFirst BYTE "1st number: ",0
GetSecond BYTE "2nd number: ",0
Linefeed BYTE 13, 10, 0
MulSign BYTE " * ",0
DivSign BYTE " / ",0
EquSign BYTE " = ",0
.code
main PROC
mov edx, OFFSET GetFirst
call WriteString
call ReadDec
mov First, eax
mov edx, OFFSET GetSecond
call WriteString
call ReadDec
mov Second, eax
mov ebx, First
mov eax, Second
call BitwiseMultiply
mov Result, eax
mov eax, First
call WriteDec
mov edx, OFFSET MulSign
call WriteString
mov eax, Second
call WriteDec
mov edx, OFFSET EquSign
call WriteString
mov eax, Result
call WriteDec
mov edx, OFFSET Linefeed
call WriteString
mov eax, First
mov ebx, Second
call BitwiseDivide
mov Result, eax
mov eax, First
call WriteDec
mov edx, OFFSET DivSign
call WriteString
mov eax, Second
call WriteDec
mov edx, OFFSET EquSign
call WriteString
mov eax, Result
call WriteDec
mov edx, OFFSET Linefeed
call WriteString
exit
main ENDP
; Multiply EBX by EAX
BitwiseMultiply PROC USES EBX ECX EDX
mov edx, eax ; EDX: multiplier (EBX: multiplicand)
xor eax, eax ; Result will be in EAX - clear it
bsr ecx, edx ; ECX = position of the most significant bit
jz R1 ; Return with EAX=0 if EDX == 0
L1:
shr edx, 1 ; Look at the rightmost bit of the multiplier
jnc @F ; Skip addition if this bit == 0
add eax, ebx ; Add multiplikand to result
@@:
shl ebx, 1 ; Increase multipland for the next round
sub ecx, 1 ; Decrease loop variable
jnc L1 ; Loop if ECX >= 0
R1:
ret ; Result in EAX
BitwiseMultiply ENDP
; Divide EAX by EBX
BitwiseDivide PROC USES ECX EDX ESI
mov esi, eax ; ESI: dividend (EBX: divisor)
xor eax, eax ; Result (quotient) = 0
xor edx, edx ; EDX = 0 (start value)
mov cl, 32 ; 32 loops
L1:
shl esi, 1 ; Bit 31 from EAX ...
rcl edx, 1 ; ... to Bit 1 of EDX
cmp ebx, edx ; Carry, if EDX > Divisor
ja @F ; Skip subtraction if carry==0 and zero==0 (result not zero)
sub edx, ebx ; Subtract ...
stc ; ... and set carry
@@:
rcl eax, 1 ; Append carry (0 or 1) to quotient.
sub cl, 1
jnz L1 ; loop while CL > 0
ret ; Result in EAX
BitwiseDivide ENDP
END main