Search code examples
assemblyx86multiplicationinteger-division

How do assemblers handle a value that is separated on 2 registers (e.g EDX:EAX)?


I'm trying to understand how do assemblers handle these.

Currently I'm trying to learn to code assembly by writing an assembly code manually. But I'm wondering how to handle a product that is separated by EDX:EAX after the operand "MUL".

What if I want to integer divide that value now by a another value, how do you do that in assembly?


Solution

  • MUL and DIV are designed both to use EDX:EAX register pair -- implicitly.

    Where MUL uses those as output registers, DIV uses those as input registers. Depending on your problem, you don't necessarily have to do anything -- just ignore the other register, since DIV actually calculates also the remainder of the division, placing it to edx.

     12313133*81231313 / 4342434 -->
      
     mov eax, 12313133
     mov ebx, 81231313
     imul ebx               ;; edx:eax = 38DAF:FE9E9FBD
     mov ebx, 4342434
     idiv ebx
    
     mov [my_result], eax   ;; = 230334407
     mov [remainder], edx
    

    Beware that DIV and IDIV will fault (#DE exception) if the quotient doesn't fit in EAX. Using a dividend that isn't sign- or zero- extended from one register makes it possible for this to happen for cases other than INT_MIN / -1 or anything / 0.

    For unsigned 32-bit div r32, it will fault if EDX >= r32, otherwise not.

    If you're using x * a / b with just one mul and div, make sure |a| < |b| or that your input x is always small enough.