Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

problem in understanding mul & imul instructions of Assembly language

Tags:

x86

assembly

nasm

I'm learning 80386 from PC Assembly by paul caurter

  mul source
  • If the operand is byte sized, it is multiplied by the byte in the AL register and the result is stored in the 16 bits of AX.

fine.

  • If the source is 16-bit, it is multiplied by the word in AX and the 32-bit result is stored in DX:AX.

Q1: Why DX:AX ? Why can't it store in EAX / EDX?

imul is really confusing

imul dest, source1
imul dest, source1, source2

alt text

I've problem in understanding the table.

Q2: in the 2nd entry of the table. Again, why DX:AX. Why not EAX or EDX?

Now consider following code snippet:

imul eax ; edx:eax = eax * eax
mov ebx, eax ; save answer in ebx
mov eax, square_msg ; square_msg db "Square of input is ", 0
call print_string ; prints the string eax
mov eax, ebx 
call print_int ;  prints the int stored in eax
call print_nl ; prints new line

Q3: Its previsously said that The notation EDX:EAX means to think of the EDX and EAX registers as one 64 bit register with the upper 32 bits in EDX and the lower bits in EAX. So the answer is also stored in edx, right? in the above code we didn't consider any EDX we are just referring to EAX How is this still working?

Q4: I've problem with rest of all entries in the table. worst case multiplication result of two n bit numbers(n = 8/16/32 bits) is 2n bits. How come its storing the result of two 16/32 bit multiplication result in register of same size itself?

like image 744
claws Avatar asked Dec 22 '09 17:12

claws


People also ask

What is the purpose of Mul?

The MUL function is a miniature of the multiplication function. In this function, we call the function that required an argument as a first number, and that function calls another function that required another argument and this step goes on.

What type of instruction is MUL?

Multiplies the contents of two general-purpose registers and stores the result in a third general-purpose register.

How does the MUL instruction work?

The MUL instruction multiplies the unsigned 8-bit integer in the accumulator and the unsigned 8-bit integer in the B register producing a 16-bit product. The low-order byte of the product is returned in the accumulator. The high-order byte of the product is returned in the B register.

What is the difference between MUL and Imul?

The MUL instruction multiplies unsigned numbers. IMUL multiplies signed numbers. For both instructions, one factor must be in the accumulator register (AL for 8-bit numbers, AX for 16-bit numbers, EAX for 32-bit numbers). The other factor can be in any single register or memory operand.


1 Answers

There are lots of different variations of the imul instruction.

The variant you've stumbled upon is a 16 bit multiplication. It multiplies the AX register with whatever you pass as the argument to imul and stores the result in DX:AX.

One 32 bit variant works like the 16 bit multiplication but writes the register into EDX:EAX. To use this variant all you have to do is to use a 32 bit source operand.

E.g:

  ; a 16 bit multiplication:
  mov ax, [factor1]
  mov bx, [factor2]
  imul bx              ; 32-bit result in DX:AX
  ; or  imul  word [factor2]

  ; a 32 bit multiplication:
  mov eax, [factor1]
  mov ebx, [factor2] 
  imul ebx             ; 64-bit result in EDX:EAX

On a 386 or later, you can also write an imul in the two operand form. That makes it much more flexible and easier to work with. In this variant you can freely choose any 2 registers as the source and destination, and the CPU won't waste time writing a high-half result anywhere. And won't destroy EDX.

  mov   ecx, [factor1]
  imul  ecx, [factor2]    ; result in ecx, no other registers affected
  imul  ecx, ecx          ; and square the result

Or for signed 16-bit inputs to match your imul. (use movzx for unsigned inputs)

  movsx   ecx, word [factor1]
  movsx   eax, word [factor2]  ; sign-extend inputs to 32-bit
  imul    eax, ecx             ; 32-bit multiply, result in EAX
  imul    eax, eax             ; and square the result

This variant of imul was introduced with 386, and is available in 16 and 32-bit operand-size. (And 64-bit operand-size in 64-bit mode).

In 32-bit code you can always assume that 386 instructions like imul reg, reg/mem are available, but you can use it in 16 bit code if you don't care about older CPUs.

186 introduced a 3-operand immediate form.

imul  cx, bx, 123        ; requires 186

imul  ecx, ebx, 123      ; requires 386
like image 97
Nils Pipenbrinck Avatar answered Oct 09 '22 15:10

Nils Pipenbrinck