简体   繁体   中英

Multiply numbers without using instructions MUL, IMUL, SHL, SHR, LOOP

是否可以不使用x86汇编语言中的指令MUL,IMUL,SHL,SHR,LOOP,JMP来计算乘法结果?

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)

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 (eg shl eax, 1 replaced with add eax, eax ); and you can replace LOOP with an explicit loop (eg 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. Eg 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
    }
}

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 - (ab)²/4 .

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 technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM