我正在研究在不使用MUL或DIV运算符的情况下在汇编中划分两个数字的东西。如果n * var<则逻辑是x,其中x是要除的数,var是要除的数,将n递增1并重复。因此,如果有剩余部分,分隔符将把答案四舍五入。
首先,我创建了一个利用位移的乘法器,这很有效。
//multiply
int ans, var1;
_asm {
mov eax, 00001111b; A = 1111
mov ebx, 00001010b; B = 1010
mov var1, 00000001b; C = 0001
mov ecx, 0;
shl ebx, 3; shift b register left by 3
L1:
cmp ecx, 4; check if multiplication is done
je L4; go to empty loop
inc ecx; increment counter by 1
AND var1, eax; check if the least significant bit is 1
cmp var1, 1; checks if var1 is = 1
je L2;
cmp var1, 0; check if var1 = 0
je L3;
L2:
shr eax, 1; shift a register right 1 bit
add eax, ebx; add a and b registers
jmp L1; go back to L1
L3:
shr eax, 1;
jmp L1; go back to L1
L4 :
mov ans, eax; move eax to answer
};
cout << "Multiply 00001111 and 00001010" << endl << ans << endl;
所以我要做的是用另外两个循环实现这个乘法器:一个递增n并将寄存器设置为正确的数字以进行乘法,另一个检查n var&gt; = x。如果n var&lt; x,它将增加n并将寄存器设置为乘,然后将它们相乘。找到答案后,递增的寄存器(edx)将变为变量d并输出到控制台。
这个程序中有一些错误,我没有看到,并且不知何故,答案总是变成var2 * 16,其中var2是要分割的数字。
int var1;
int var2;
int var3;
int d;
_asm {
; if n*var3 < var2, increment n and repeat
mov var2, 12; number to be divided
mov var3, 5; number to divide with
mov ecx, 0;
mov edx, 0; number to increment
L11 :
cmp eax, var2;
js L12; if n*n < var2, increment n and multiply.
cmp eax, var2
jns L16; answer found, jump to empty loop
L12 :
inc edx
mov eax, edx
mov ebx, var3
shl ebx, 3
mov ecx, 0
jmp L13
L13 :
cmp ecx, 4; check if multiplication is done
je L11;
inc ecx; increment counter by 1
AND var1, eax; check if the least significant bit is 1
cmp var1, 1; checks if var1 is = 1
je L14;
cmp var1, 0; check if var1 = 0
je L15;
L14:
shr eax, 1; shift a register right 1 bit
add eax, ebx; add a and b registers
jmp L13; go back to L1
L15 :
shr eax, 1;
jmp L13;
L16:
mov d, edx
};
cout << "The quotient is " << d << endl;
我还创建了一个非常相似的程序来计算数字的平方根,如果n * n&lt; x,其中x是取平方根的数字,递增n和重复。使用分隔符解决这个错误也应该帮助我使用平方根程序,同时发生同样的错误。
我已经被困在这几天了,我无法弄清楚造成这个奇怪错误的错误。任何帮助表示赞赏。
答案 0 :(得分:0)
减法可以解答您的问题(&#34;如何在不使用MUL或DIV运算符的情况下在汇编中分割两个数字?&#34;),示例(在VS2013上测试):
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(void){
int dividend;
cout << "Enter DIVIDEND : "; //◄■ EXAMPLE : 23.
cin >> dividend;
int divisor;
cout << "Enter DIVISOR : "; //◄■ EXAMPLE : 4.
cin >> divisor;
int quotient = 0;
_asm {
mov eax, dividend
divisions:
cmp eax, divisor
jb finish //◄■ IF DIVIDEND < DIVISOR
sub eax, divisor //◄■ DIVIDEND - DIVISOR. EXAMPLE : 23 - 4.
inc quotient //◄■ DIVISIONS COUNTER.
jmp divisions
finish:
}
cout << "The result is " << quotient; //◄■ EXAMPLE : 5
return 0;
}
以前的代码会抛出整数结果。如果你想要带小数的结果,有必要将最后一个被除数(前一个例子中的3)乘以10表示一位小数,或乘以100表示两位小数(或1000表示三位小数,依此类推),例如(在VS2013上测试) ):
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(void){
int dividend;
cout << "Enter DIVIDEND : "; //◄■ EXAMPLE : 23.
cin >> dividend;
int divisor;
cout << "Enter DIVISOR : "; //◄■ EXAMPLE : 4.
cin >> divisor;
// ▼ CALCULATE QUOTIENT.
int quotient = 0;
_asm {
mov eax, dividend
divisions:
cmp eax, divisor
jb finish1 //◄■ IF DIVIDEND < DIVISOR
sub eax, divisor //◄■ DIVIDEND - DIVISOR. EXAMPLE : 23 - 4.
inc quotient //◄■ DIVISIONS COUNTER.
jmp divisions
finish1:
mov dividend, eax //◄■ LAST DIVIDEND (USED FOR REMAINDER). EXAMPLE : 3.
}
// ▼ CALCULATE REMAINDER WITH TWO DECIMALS.
int remainder = 0;
_asm {
// ▼ MULTIPLY LAST DIVIDEND BY 100. EXAMPLE : 3 * 100 = 300.
mov ecx, 100 //◄■ REPEAT 100 TIMES.
mov eax, 0
multiply:
add eax, dividend //◄■ MULTIPLY IS A SERIES OF ADDITIONS. EXAMPLE : EAX + 3.
loop multiply
// ▼ GET REMAINDER WITH TWO DECIMALS.
decimals:
cmp eax, divisor
jb finish2 //◄■ IF DIVIDEND < DIVISOR
sub eax, divisor //◄■ DIVIDEND - DIVISOR. EXAMPLE : 300 - 4.
inc remainder //◄■ DIVISIONS COUNTER.
jmp decimals
finish2:
}
cout << "The result is " << quotient << "." << remainder; //◄■ EXAMPLE : 5.75
return 0;
}