13

I am learning assembly for x86 using DosBox emulator. I am trying to perform multiplication. I do not get how it works. When I write the following code:

mov al, 3
mul 2

I get an error. Although, in the reference I am using, it says in multiplication, it assumes AX is always the place holder, therefore, if I write:

mul, 2

It multiplies al value by 2. But it does not work with me.

When I try the following:

mov al, 3
mul al,2
int 3

I get result 9 in ax. See this picture for clarification: enter image description here

Another question: Can I multiply using memory location directly? Example:

mov si,100
mul [si],5
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
user2192774
  • 3,807
  • 17
  • 47
  • 62
  • 1
    `mul al, 2` seems to be incorrectly accepted by MS-DOS DEBUG and treated as if you entered `mul al` (multiplies implicit byte operand `al` by explicit operand `al` and store in implicit destination `ax`). – ecm Oct 16 '20 at 21:16
  • There's no immediate `mul`, but there immediate `imul` in 186 and newer. See [problem in understanding mul & imul instructions of Assembly language](https://stackoverflow.com/a/19783509) . There's no memory-destination `mul` or `imul` even on the newest CPUs, only memory-source. There is `imul cx, [si], 5` if you want, though, on 186 and newer. – Peter Cordes May 22 '22 at 18:47

3 Answers3

18

There's no form of MUL that accepts an immediate operand.

Either do:

mov al,3
mov bl,2
mul bl     ; the product is in ax

or (requires 186 for imul-immediate):

mov ax,3
imul ax,2  ; imul is for signed multiplication, but low half is the same
           ; the product is in ax.  dx is not modified

or:

mov al,3
add al,al  ; same thing as multiplying by 2

or:

mov al,3
shl al,1   ; same thing as multiplying by 2
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Michael
  • 57,169
  • 9
  • 80
  • 125
  • 1
    The comment in your second code snippet is wrong. After `imul ax, 2` the product is in AX (not in DX:AX). – Sep Roland Oct 18 '15 at 20:32
  • 2
    Also note that `imul`-immediate is a 3-operand instruction. So you can use it non-destructively, like `imul cx, si, 1234`. Most assemblers let you write `imul cx, 1234` as a short-hand for `imul cx, cx, 1234`, similar to writing `vaddps ymm0, ymm1` instead of `vaddps ymm0, ymm0, ymm1`: i.e. when dst = src1. – Peter Cordes Aug 26 '17 at 16:33
4

Intel manual

The Intel 64 and IA-32 Architectures Software Developer’s Manual - Volume 2 Instruction Set Reference - 325383-056US September 2015 section "MUL - Unsigned Multiply" column Instruction contains only:

MUL r/m8
MUL r/m8*
MUL r/m16
MUL r/m32
MUL r/m64

r/mXX means register or memory: so immediates (immXX) like mul 2 are not allowed in any of the forms: the processor simply does not support that operation.

This also answers the second question: it is possible to multiply by memory:

x: dd 0x12341234
mov eax, 2
mul dword [x]
; eax == 0x24682468

And also shows why things like mul al,2 will not work: there is no form that takes two arguments.

As mentioned by Michael however, imul does have immediate forms like IMUL r32, r/m32, imm32 and many others that mul does not.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
2

There's no immediate mul, but there is non-widening imul-immediate in 186 and newer, and imul reg, r/m in 386 and newer. See @phuclv's answer on problem in understanding mul & imul instructions of Assembly language for more details, and of course Intel's instruction set reference manuals for mul and imul:

There's no memory-destination mul or imul even on the newest CPUs.

There is imul cx, [si], 5 if you want, though, on 186 and newer, for 16-bit operand-size and wider. And on 386, also imul di, [si].

But those new forms of imul don't exist for 8-bit operand-size, so there is no imul cl, [si], 5.

On a 386 or newer, it would typically be more efficient to use an LEA for a multiply by a simple constant, although it does cost a bit more code-size.

; assuming 16-bit mode
    mov  cx, [si]              ; or better movzx ecx, word [si] on newer CPUs
    lea  cx, [ecx + ecx*4]     ; CX *= 5
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847