Is it possible to calculate result of multiplication without using instructions MUL, IMUL, SHL, SHR, LOOP, JMP in x86 assembly language?
CPUs without a multiply instruction can generally do it with repeated addition but that becomes extremely difficult without loops.
However, since you haven't specified which specific CPU you're interested in, I would posit one that either has an instruction like:
add rt, rs, count
instruction which adds rs
to rt
exactly count
times. That would enable you to do it without a loop
or jump
instruction :-)
Of course, then you could just have an paxmul
instruction that does multiplication for you - not technically a mul
but no doubt against the spirit of the question.
But, to be honest, this question may be seen as moot since you'd be hard pressed actually trying to find a CPU without the instructions you list.
The following code will multiply the contents of the registers ecx
and edx
and store the result in register eax
. The content of the registers ebx
and edx
is destroyed:
mov ebx, 1
mov eax, 0
repeat:
test ecx, ebx
jz dontadd
add eax, edx
dontadd:
add edx, edx
add ebx, ebx
jnz repeat
without ... LOOP
If "LOOP" does not only cover the "LOOP" instruction but any conditional jump instructions:
Doing a multiplication without conditional jump instructions is a bit more difficult but not impossible; the following example does so (Input: ecx
and edx
, output eax
, the content of all registers used will be destroyed):
mov ebx, 1
mov eax, 0
not ecx
# Repeat the following code 32 times:
mov esi, ebx
and esi, ecx
dec esi
and esi, edx
add eax, esi
add edx, edx
add ebx, ebx
# (repeat the code here)
Hell bent against full table lookup and logarithm, addition and exponentiation, you can still do
table lookup of squares and subtraction: ab = (a+b)²/4 - (a-b)²/4.
Is it possible to calculate result of multiplication without using instructions MUL, IMUL, SHL, SHR, LOOP, JMP in x86 assembly language?
Yes.
Without MUL the normal approach is "SHIFT LEFT and TEST and ADD" in a loop, like this:
result = 0;
while(a > 0) {
result = result << 1;
if( a & 0x80000000 != 0) {
result = result + b;
}
a = a << 1;
}
Note that a loop like this for 32-bit integers will have (at most) 32 iterations.
You can replace these shifts with additions (e.g. shl eax, 1
replaced with add eax, eax
); and you can replace LOOP
with an explicit loop (e.g. dec ecx
, jne next
) or unroll the loop (repeat the code 32 times). These replacements will probably improve performance.
Once you have unsigned multiplication, IMUL
can be replaced with branches that convert the values to positive and uses unsigned multiplication. E.g. like:
if(a < 0) {
a = -a;
if(b < 0) {
b = -b
return a*b; // Unsigned multiplication
} else {
return -a*b; // Unsigned multiplication
}
} else {
if(b < 0) {
b = -b
return -a*b; // Unsigned multiplication
} else {
return a*b; // Unsigned multiplication
}
}