我正在做的事情,将不使用MUL或DIV运算符在组件中分两个数字。逻辑是,如果n * var < x,其中x是要除的数字,var是除以的数字,则n加1并重复。因此,如果有余数,分频器会将答案加1。如何在不使用MUL或DIV运算符的情况下将两个数字在程序集中分开?
首先,我创建了一个利用位移的乘法器,并且这可以工作。
//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 VAR> = X一个N递增,并设置寄存器以正确的数量倍增,和一个。如果n是 var < 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 < x,其中x是采取的,增量的平方根n和重复次数。用分隔线解决这个错误也应该可以帮助我处理发生相同错误的平方根程序。
我一直坚持这几天,我无法弄清楚是什么错误导致这个奇怪的错误。任何帮助表示赞赏。
使用调试器来遍历代码,看看它没有做到你想做的。 – Jester
前一段时间,我用普通的asm编码了一个小波兰注释计算器。它的工作,至少对于整数。尽管如此,整数分解的结果也是小数,这似乎也起作用。只要你知道,这个划分是重复的减法,你可以通过使用sub来完成。我是这样做的。 – icbytes
在第二个代码块中:第一次运行'L11:'时,'eax'是什么?看起来没有定义给我。加上'js/jns'做两次'cmp'会浪费CPU周期。在第一个'cmp + js'指令对之后,你不需要再次执行'cmp',因为标志仍然是从前一个设置的(然后'js'不会修改标志),并且'jns'会在100%因为所有的SF = 1例已经被前面的'js'拾取。 ......我只检查了第二块的〜10行,因为我很好奇你是否真的*做过++ n,然后再乘以'n * var' AGAIN,OMG:D ..可笑。 '(n + 1)* var ==(n * var)+ var'! – Ped7g