Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 901 Vote(s) - 3.52 Average
  • 1
  • 2
  • 3
  • 4
  • 5
MUL instruction doesn't support an immediate value

#1
I've read a few tutorials and examples, but I cannot wrap my head around how the `MUL` instruction works. I've used `ADD` and `SUB` without problems. So apparently this instruction multiplies its operand by the value in a register.

What register (eax, ebp, esp, etc.) is multiplied by the first operand? And what register is the result stored in, so I can move it to the stack? Sorry, I'm just learning x86 assembly.

When I try to compile this line...

mul 9

I get, `Error: suffix or operands invalid for 'mul'`. Can anyone help me out?

global main
main:
push ebp
movl ebp, esp
sub esp, byte +8
mov eax, 7
mul 9
mov [esp], eax
call _putchar
xor eax, eax
leave
ret
Reply

#2

[To see links please register here]


> the destination operand is an implied
> operand located in register AL, AX or
> EAX (depending on the size of the
> operand); the source operand is
> located in a general-purpose register
> or a memory location
>
> The result is stored in register AX,
> register pair DX:AX, or register pair
> EDX:EAX (depending on the operand
> size), with the high-order bits of the
> product contained in register AH, DX,
> or EDX, respectively. If the
> high-order bits of the product are 0,
> the CF and OF flags are cleared;
> otherwise, the flags are set.

In your source it should be `mul` instead of `mull`
Reply

#3
MUL can't use an immediate value as an argument. You have to load '9' into a register, say,

movl $7, %eax
movl $9, %ecx
mull %ecx

which would multiply eax by ecx and store the 64-bit product in edx:eax.

There's a good comprehensive reference of x86 assembly instructions on the Intel web site, see here





But that is probably far more information that you need now.
Reply

#4
I'll give you a link to my favorite easy-to-read, but complete, reference for x86:

[To see links please register here]


Reply

#5
**How to read on the Intel manual to see that it is not possible**

First download the Intel manual. Current download page is:

[To see links please register here]

but just Google "intel x86 manual" as that is bound to change.

What we want is the Combined Volume 2 Instruction Set Reference A-Z which contains all instructions.

In that manual, find the documentation for `DIV`. We see that `DIV` has the following forms under the *Instruction* column:

- `DIV r/m8`
- `DIV r/m16`
- `DIV r/m32`
- `DIV r/m64`

`r/mX` means that it can take a register or memory location of size X.

Therefore, there is no form that takes `immX`, which is an immediate value, or literal.

So it is not possible to encode that instruction to the processor, and now we know that the only way to go is pass through registers or memory.

Registers are faster, so we use them of course if possible.
Reply

#6
If you look at [`MUL`][1] format table you'll notice that it only accepts one register parameter. However turn over to [`IMUL`][2] and you'll see there are many forms of it that accept an immediate

<pre>
6B /r ib <b>IMUL r16, r/m16, imm8</b> word register ← <i>r/m16</i> ∗ sign-extended immediate byte.
6B /r ib <b>IMUL r32, r/m32, imm8</b> doubleword register ← <i>r/m32</i> ∗ sign-extended immediate byte.
REX.W + 6B /r ib <b>IMUL r64, r/m64, imm8</b> Quadword register ← <i>r/m64</i> ∗ sign-extended immediate byte.
69 /r iw <b>IMUL r16, r/m16, imm16</b> word register ← <i>r/m16</i> ∗ immediate word.
69 /r id <b>IMUL r32, r/m32, imm32</b> doubleword register ← <i>r/m32</i> ∗ immediate doubleword.
REX.W + 69 /r id <b>IMUL r64, r/m64, imm32</b> Quadword register ← <i>r/m64</i> ∗ immediate doubleword.
</pre>

So to multiply eax by 9 you can do like this

mov eax, 7
imul eax, eax, 9 ; eax = eax*9

Look closer and you can also observe that those versions are non-widening. In fact nowadays `imul` is exclusively used for almost all multiplications, because non-widening multiplication is [the same for signed and unsigned values][3] and multiplication in high-level languages are non-widening (i.e. the output type and input operands' types are the same) unless you cast the operands to a wider type. As a result, [modern x86 CPUs are often optimized for `imul`][4] and it also has many more forms than `mul`


[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

[4]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through